在实现MvcSecurityConfiguration的类configure(HttpSecurity http)方法中添加如下内容:
http.exceptionHandling()
.authenticationEntryPoint(new UnauthorizedEntryPoint())
.and()
.csrf().disable()
.logout()
.addLogoutHandler(new TokenLogoutHandle(redisTemplate, tokenManager))
.logoutUrl("/auth/logout")
.and()
.authorizeRequests()
// 静态资源等等
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/webjars/**",
"/v2/**"
).permitAll()
.antMatchers("/auth/**").permitAll()
.antMatchers("/swagger-ui.html").permitAll()
.antMatchers("/swagger-resources/**").permitAll()
.anyRequest().authenticated()//设置所有请求都要认证
.and().apply(securityConfigurerAdapter());//设置token的配置
securityConfigurerAdapter()具体的内容
private TokenConfigurer securityConfigurerAdapter() {
return new TokenConfigurer(tokenManager);
}
TokenConfigurer类如下:
public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
//token提供类
private final TokenManager tokenManager;
public TokenConfigurer(TokenManager tokenManager) {
this.tokenManager = tokenManager;
}
@Override
public void configure(HttpSecurity http) {
TokenFilter customFilter = new TokenFilter(tokenManager);//token过滤器类
http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class);
}
}
TokenFilter类
@RequiredArgsConstructor
public class TokenFilter extends GenericFilterBean {
private final TokenManager tokenManager;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String token = resolveToken(req);
// 对于 Token 为空的不需要去查 Redis
if (token != null && token.length() != 0) {
//用户在线并且token有用,给token续期
if (StringUtils.hasText(token)) {
Authentication authentication = tokenManager.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
// Token 续期
tokenManager.checkRenewal(token);
}
}
chain.doFilter(request, response);
}
private String resolveToken(HttpServletRequest req) {
String token = req.getHeader("Authorization");
if (StringUtils.hasText(token) && token.startsWith("Bearer")) {
// 去掉令牌前缀
return token.replace("Bearer", "");
} else {
log.debug("非法Token:{}", token);
}
return null;
}
}