• Spring Security + JJWT 实现 JWT 认证和授权


    关于 JJWT 的使用,可以参考之前的文章:JJWT 使用示例

    一、鉴权过滤器

    @Component
    public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    
        @Override
        protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
                                        FilterChain filterChain) throws ServletException, IOException {
            String token = httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION);
            if(!StringUtils.isEmpty(token)) {
                UserInfoModel userInfo = JwtUtil.verifyToken(token, JwtConstant.AIM_ACCESS);
                if(userInfo != null) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userInfo, null, userInfo.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
    
            filterChain.doFilter(httpServletRequest, httpServletResponse);
        }
    }
    

    二、Spring Security 配置

    @Configuration
    @EnableWebSecurity
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
        @Autowired
        private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
        @Autowired
        private EntryPointUnauthorizedHandler entryPointUnauthorizedHandler;
        @Autowired
        private RestAccessDeniedHandler restAccessDeniedHandler;
    
        @Bean
        GrantedAuthorityDefaults grantedAuthorityDefaults() {
            // 去除 ROLE_ 前缀
            return new GrantedAuthorityDefaults("");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .antMatchers("/login").permitAll()
                    .anyRequest().authenticated()
                    .and().cors()
                    .and().csrf().disable();
            http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
            http.exceptionHandling()
                    .authenticationEntryPoint(entryPointUnauthorizedHandler)
                    .accessDeniedHandler(restAccessDeniedHandler);
            // 不创建会话
            http.sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }
    }
    

    其中 EntryPointUnauthorizedHandler 和 RestAccessDeniedHandler 是未认证或未授权异常处理,详细代码可以看源码

    三、获取当前登录用户

    public class CurrentUserUtil {
    
        public static UserInfoModel getUserInfo() {
    
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if(authentication != null) {
                if(authentication instanceof UsernamePasswordAuthenticationToken) {
                    return (UserInfoModel)authentication.getPrincipal();
                }
            }
    
            return null;
        }
    }
    

    测试代码见 TestController,测试时在请求 Header 中添加 Authorization 即可

    完整代码:GitHub

    参考:

    1. Spring Security和JWT实现登录授权认证
    2. How do I remove the ROLE_ prefix from Spring Security with JavaConfig?
  • 相关阅读:
    python增加 删除列表元素
    Fildder2
    Appscan使用第三方浏览器
    Appscan的下载安装
    http状态码
    python学习资料
    Fiddler抓包工具
    性能测试的一些资料
    Jmeter分布式测试
    内存溢出的原因及解决办法(转)
  • 原文地址:https://www.cnblogs.com/victorbu/p/13186820.html
Copyright © 2020-2023  润新知