Spring Security + JWT使用

  • 支持JSON 方式登录

    @Bean
    public JsonLoginFilter jsonLoginFilter(){
        JsonLoginFilter jsonLoginFilter = new JsonLoginFilter();
        jsonLoginFilter.setAuthenticationManager(authenticationManager());
        jsonLoginFilter.setAuthenticationFailureHandler((request, response, exception) -> {
            Map<String,Object> result = new HashMap<>();
            result.put("code",-1);
            result.put("msg","登录失败");
            result.put("data",exception.getMessage());
            writeResp(result,response);
        });
        jsonLoginFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
            List<String> permissions = authorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
            String token = JwtTokenUtil.generateTokenByRSA(authentication.getName(), permissions);
            Map<String,Object> result = new HashMap<>();
            result.put("code",-1);
            result.put("msg","登录成功");
            result.put("data",token);
            writeResp(result,response);
        });
        return jsonLoginFilter;
    }
    
  • 配置无权限访问异常处理器

    .exceptionHandling()
          .accessDeniedHandler(new AccessDeniedHandler() {
                        @Override
                        public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
                            Map<String,Object> result = new HashMap<>();
                            result.put("code",-1);
                            result.put("msg","访问失败");
                            result.put("data","无权限访问");
                            writeResp(result,response);
                        }
                    })
    
  • 配置认证失败异常处理器

    .exceptionHandling() 
    .authenticationEntryPoint(new AuthenticationEntryPoint() {
                        @Override
                        public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                            Map<String,Object> result = new HashMap<>();
                            result.put("code",-1);
                            result.put("msg","访问失败");
                            result.put("data","请登录");
                            writeResp(result,response);
                        }
                    })
    
  • 配置UserDetailService 定义用户来源

    @Service
    public class UserDetailService implements UserDetailsService {
        @Autowired
        private UserMapper userMapper;
        @Override
        public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
            User user = userMapper.queryUserByUsername(username);
            List<Role> roles = userMapper.getRolesByUserId(user.getId());
            user.setRoles(roles);
            if (Objects.isNull(user)) {
                throw new UsernameNotFoundException("user not found");
            }
            return user;
        }
    }
    
  • 配置token处理器

    token过滤器是用来解析token,如果解析成功,则放到SecurityContext中

    @Component
    @WebFilter(filterName = "TokenLoginFilter", urlPatterns = "/*")//先全部拦截
    public class TokenLoginFilter extends OncePerRequestFilter {
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException, IOException {
    
            String authorization = request.getHeader("Authorization");
            if (StringUtils.isEmpty(authorization)) {
                filterChain.doFilter(request, response);
                return;
            }
            AccessToken accessToken = JwtTokenUtil.verifyTokenByRSA(authorization);
            if (Objects.isNull(accessToken)) {
                filterChain.doFilter(request, response);
                return;
            }
            //已登录,获取用户信息,进行授权
            List<SimpleGrantedAuthority> authorities = accessToken.getAuthorities().stream().map(permission ->
                    new SimpleGrantedAuthority(permission)
            ).collect(Collectors.toList());
            UsernamePasswordAuthenticationToken token =
                    new UsernamePasswordAuthenticationToken(accessToken.getUsername(), null, authorities);
            SecurityContextHolder.getContext().setAuthentication(token);
            System.out.println("SecurityContextHolder信息:" + JSON.toJSONString(SecurityContextHolder.getContext()));
            filterChain.doFilter(request, response);
        }
    }
    
  • 将json过滤器和token过滤器加入SecurityFilterChain

    .addFilterAt(jsonLoginFilter(), UsernamePasswordAuthenticationFilter.class)
                    .addFilterAt(tokenLoginFilter, JsonLoginFilter.class)
    
  • 创建测试接口

    @RestController
    public class IndexController {
        @RequestMapping("/admin")
        @PreAuthorize("hasAnyAuthority('admin:write')")
        public String admin(Authentication authentication){
            return JSON.toJSONString(authentication);
        }
        @RequestMapping("/superAdmin")
        @PreAuthorize("hasAnyAuthority('super:write')")
        public String superAdmin(Authentication authentication){
            return JSON.toJSONString(authentication);
        }
    }
    
  • 验证

    • 访问登录接口:/login
    • 访问admin接口:/admin
    • 访问superAdmin接口:/superAdmin
    • 不带token访问admin接口:/admin
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讓丄帝愛伱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值