我正在尝试使用AngularJS和Spring Boot创建一个应用程序。我查看了很多教程,我复制了这些代码并且出了点问题。
我不熟悉这些技术,我也可能会错过一些东西。我不知道错误的位置,所以我将链接到代码所在的github。
https://github.com/BitRuby/YouLoveLife/tree/Stage1
我还添加了可能存在错误的类:
过滤类:
public class JWTFilter extends GenericFilterBean {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final String AUTHORITIES_KEY = "roles";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String authHeader = request.getHeader(AUTHORIZATION_HEADER);
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid Authorization header.");
} else {
try {
String token = authHeader.substring(7);
Claims claims = Jwts.parser().setSigningKey("secretkey").parseClaimsJws(token).getBody();
request.setAttribute("claims", claims);
SecurityContextHolder.getContext().setAuthentication(getAuthentication(claims));
filterChain.doFilter(req, res);
} catch (SignatureException e) {
((HttpServletResponse) res).sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token");
}
}
}
/**
* Method for creating Authentication for Spring Security Context Holder
* from JWT claims
*
* @param claims
* @return
*/
public Authentication getAuthentication(Claims claims) {
List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
List<String> roles = (List<String>) claims.get(AUTHORITIES_KEY);
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
User principal = new User(claims.getSubject(), "", authorities);
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
principal, "", authorities);
return usernamePasswordAuthenticationToken;
}
}
网络配置:
@Configuration
@Configurable
@Order(99)
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// This method is for overriding some configuration of the WebSecurity
// If you want to ignore some request or request patterns then you can
// specify that inside this method
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
// ignoring the "/", "/index.html", "/app/**", "/register",
// "/favicon.ico"
.antMatchers("/", "/index.html", "/app/**", "/register", "/authenticate", "/favicon.ico");
}
// This method is used for override HttpSecurity of the web Application.
// We can specify our authorization criteria inside this method.
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// starts authorizing configurations
.authorizeRequests()
// authenticate all remaining URLS
.anyRequest().fullyAuthenticated().and()
// adding JWT filter
.addFilterBefore(new JWTFilter(), UsernamePasswordAuthenticationFilter.class)
// enabling the basic authentication
.httpBasic().and()
// configuring the session as state less. Which means there is
// no session in the server
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// disabling the CSRF - Cross Site Request Forgery
.csrf().disable();
}
}
用户应用休息:
@RestController
@RequestMapping(value = "/api")
public class AppUserRestController {
@Autowired
private AppUserRepository appUserRepository;
/**
* Web service for getting all the appUsers in the application.
*
* @return list of all AppUser
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users", method = RequestMethod.GET)
public List<AppUser> users() {
return appUserRepository.findAll();
}
/**
* Web service for getting a user by his ID
*
* @param id
* appUser ID
* @return appUser
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
public ResponseEntity<AppUser> userById(@PathVariable Long id) {
AppUser appUser = appUserRepository.getOne(id);
if (appUser == null) {
return new ResponseEntity<AppUser>(HttpStatus.NO_CONTENT);
} else {
return new ResponseEntity<AppUser>(appUser, HttpStatus.OK);
}
}
/**
* Method for deleting a user by his ID
*
* @param id
* @return
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)
public ResponseEntity<AppUser> deleteUser(@PathVariable Long id) {
AppUser appUser = appUserRepository.getOne(id);
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String loggedUsername = auth.getName();
if (appUser == null) {
return new ResponseEntity<AppUser>(HttpStatus.NO_CONTENT);
} else if (appUser.getUsername().equalsIgnoreCase(loggedUsername)) {
throw new RuntimeException("You cannot delete your account");
} else {
appUserRepository.delete(appUser);
return new ResponseEntity<AppUser>(appUser, HttpStatus.OK);
}
}
/**
* Method for adding a appUser
*
* @param appUser
* @return
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users", method = RequestMethod.POST)
public ResponseEntity<AppUser> createUser(@RequestBody AppUser appUser) {
if (appUserRepository.findOneByUsername(appUser.getUsername()) != null) {
throw new RuntimeException("Username already exist");
}
return new ResponseEntity<AppUser>(appUserRepository.save(appUser), HttpStatus.CREATED);
}
/**
* Method for editing an user details
*
* @param appUser
* @return modified appUser
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users", method = RequestMethod.PUT)
public AppUser updateUser(@RequestBody AppUser appUser) {
if (appUserRepository.findOneByUsername(appUser.getUsername()) != null
&& appUserRepository.findOneByUsername(appUser.getUsername()).getId() != appUser.getId()) {
throw new RuntimeException("Username already exist");
}
return appUserRepository.save(appUser);
}
}
这样的事情:
@RestController
public class HomeRestController {
@Autowired
private AppUserRepository appUserRepository;
/**
* This method is used for user registration. Note: user registration is not
* require any authentication.
*
* @param appUser
* @return
*/
@RequestMapping(value = "/register", method = RequestMethod.POST)
public ResponseEntity<AppUser> createUser(@RequestBody AppUser appUser) {
if (appUserRepository.findOneByUsername(appUser.getUsername()) != null) {
throw new RuntimeException("Username already exist");
}
List<String> roles = new ArrayList<>();
roles.add("USER");
appUser.setRoles(roles);
return new ResponseEntity<AppUser>(appUserRepository.save(appUser), HttpStatus.CREATED);
}
/**
* This method will return the logged user.
*
* @param principal
* @return Principal java security principal object
*/
@RequestMapping("/user")
public AppUser user(Principal principal) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
String loggedUsername = auth.getName();
return appUserRepository.findOneByUsername(loggedUsername);
}
/**
* @param username
* @param password
* @param response
* @return JSON contains token and user after success authentication.
* @throws IOException
*/
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ResponseEntity<Map<String, Object>> login(@RequestParam String username, @RequestParam String password,
HttpServletResponse response) throws IOException {
String token = null;
AppUser appUser = appUserRepository.findOneByUsername(username);
Map<String, Object> tokenMap = new HashMap<String, Object>();
if (appUser != null && appUser.getPassword().equals(password)) {
token = Jwts.builder().setSubject(username).claim("roles", appUser.getRoles()).setIssuedAt(new Date())
.signWith(SignatureAlgorithm.HS256, "secretkey").compact();
tokenMap.put("token", token);
tokenMap.put("user", appUser);
return new ResponseEntity<Map<String, Object>>(tokenMap, HttpStatus.OK);
} else {
tokenMap.put("token", null);
return new ResponseEntity<Map<String, Object>>(tokenMap, HttpStatus.UNAUTHORIZED);
}
}
}
我还附加了前端出现的错误: