原创 jwt-security简单实现

1 springboor自动配置

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class LowcSecurityConfig extends SecurityConfig {

@Autowired
private CommonUserService adminUserService;

@Bean
public UserDetailsService userDetailsService() {
    //获取登录用户信息
    return username -> adminUserService.loadUserByUsername(username);
}}

2 JWT登录授权过滤器
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
@Resource
private UserDetailsService userDetailsService;
@Resource
private JwtTokenUtil jwtTokenUtil;
@Value("${jwt.tokenHeader}")
private String tokenHeader;
@Value("${jwt.tokenHead}")
private String tokenHead;

@Override
protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response,
                                FilterChain chain) throws ServletException, IOException {
    String authHeader = request.getHeader(this.tokenHeader);
    if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
        String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer "
        String username = jwtTokenUtil.getUserNameFromToken(authToken);
        LOGGER.info("checking username:{}", username);
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                LOGGER.info("authenticated user:{}", username);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
    }
    chain.doFilter(request, response);
}

}

3 对SpringSecurity的配置的扩展,支持自定义白名单资源路径和查询用户逻辑
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity
            .authorizeRequests();
    //不需要保护的资源路径允许访问
    for (String url : ignoreUrlsConfig().getUrls()) {
        registry.antMatchers(url).permitAll();
    }
    //允许跨域请求的OPTIONS请求
    registry.antMatchers(HttpMethod.OPTIONS)
            .permitAll();
    // 任何请求需要身份认证
    registry.and()
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            // 关闭跨站请求防护及不使用session
            .and()
            .csrf()
            .disable()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            // 自定义权限拒绝处理类
            .and()
            .exceptionHandling()
            .accessDeniedHandler(restfulAccessDeniedHandler())
            .authenticationEntryPoint(restAuthenticationEntryPoint())
            // 自定义权限拦截器JWT过滤器
            .and()
            .addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
}

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.userDetailsService(userDetailsService())
            .passwordEncoder(passwordEncoder());
}

/**
 *security包里的加密工具
 */
@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

/**
 * 自定义权限拦截器JWT过滤器
 */
@Bean
public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter() {
    return new JwtAuthenticationTokenFilter();
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

/**
 *自定义的没有权限访问时处理类
 */
@Bean
public RestfulAccessDeniedHandler restfulAccessDeniedHandler() {
    return new RestfulAccessDeniedHandler();
}

/**
 *自定义的未登录或登录过期处理类
 */
@Bean
public RestAuthenticationEntryPoint restAuthenticationEntryPoint() {
    return new RestAuthenticationEntryPoint();
}

/**
 * 自定义的不需要保护的资源路径(可在application.yml文件中进行修改)
 */
@Bean
public IgnoreUrlsConfig ignoreUrlsConfig() {
    return new IgnoreUrlsConfig();
}

/**
 * 自定义的Token工具类
 */
@Bean
public JwtTokenUtil jwtTokenUtil() {
    return new JwtTokenUtil();
}}

4 yml配置

jwt:
tokenHeader: Authorization #JWT存储的请求头
secret: *********# #JWT加解密使用的密钥
expiration: 604800 #JWT的超期限时间(60
60
24
7)
tokenHead: Bearer #JWT负载中拿到开头

化繁为简,极致高效。 所有代码为本人原创,转载请联系本人。
原文地址:https://www.cnblogs.com/crissblog/p/14862401.html