- 认证、会话、授权
用户认证通过后,为了避免用户的每次操作都进行认证,所以可以将用户的信息保存在会话中(JWT),token解析成功后,根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则用户正常访问,没有权限则拒绝访问。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3b62c67cf1fa468b9c4ba0d14b5b35fb.png)
- 登录认证,生成token
@RestController
@RequestMapping("security")
public class LoginController {
@Autowired
AuthenticationManager authenticationManager;
@PostMapping("/login")
public String login(@RequestBody LoginDto loginDto){
UsernamePasswordAuthenticationToken authentication
=new UsernamePasswordAuthenticationToken(loginDto.getUsername(),loginDto.getPassword());
Authentication authenticate = authenticationManager.authenticate(authentication);
if( authenticate.isAuthenticated() ){
Object principal = authenticate.getPrincipal();
Map<String, Object> claims = new HashMap<>();
claims.put("user",principal);
String token = JwtUtil.createJWT("itcast",360000, claims);
return token;
}else{
return "";
}
}
}
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMapper.findByUsername(username);
if(user == null){
throw new RuntimeException("用户不存在或已被禁用");
}
UserAuth userAuth = new UserAuth();
userAuth.setUsername(user.getUsername());
userAuth.setPassword(user.getPassword());
userAuth.setNickName(user.getNickName());
List<String> roles=new ArrayList<>();
if("yz@qq.com".equals(username)){
roles.add("USER");
userAuth.setRoles(roles);
}
if("admin@qq.com".equals(username)){
roles.add("USER");
roles.add("ADMIN");
userAuth.setRoles(roles);
}
return userAuth;
}
}
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().antMatchers("/security/login").permitAll();
http.csrf().disable();
return http.build();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
- 授权,完成不同角色的授权登录
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/432d6f8974ba40b3937c916e0abc0e1f.png)
@Component
public class TokenAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
@Override
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext requestAuthorizationContext) {
HttpServletRequest request = requestAuthorizationContext.getRequest();
String requestURI = request.getRequestURI();
String token = request.getHeader("token");
if(null == token || "".equals(token)){
return new AuthorizationDecision(false);
}
Claims claims = JwtUtil.parseJWT("itcast", token);
if (ObjectUtil.isEmpty(claims)) {
return new AuthorizationDecision(false);
}
UserAuth userAuth = JSONObject.parseObject(JSON.toJSONString(claims.get("user")),UserAuth.class);
UsernamePasswordAuthenticationToken auth
=new UsernamePasswordAuthenticationToken( userAuth, userAuth.getPassword(), userAuth.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);
if(userAuth.getRoles().contains("ADMIN")){
if("/hello/admin".equals(requestURI)){
return new AuthorizationDecision(true);
}
}
if(userAuth.getRoles().contains("USER")){
if("/hello/user".equals(requestURI)){
return new AuthorizationDecision(true);
}
}
return new AuthorizationDecision(false);
}
}
@Configuration
public class SecurityConfig {
@Autowired
private TokenAuthorizationManager tokenAuthorizationManager;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests().antMatchers("/security/login").permitAll()
.anyRequest().access(tokenAuthorizationManager);
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.headers().cacheControl().disable();
http.csrf().disable();
return http.build();
}
}