springboot 使用了spring Security后 不能直接访问 openApi接口文档了
这段是我加的,但是没用
@Data
@Component
public class CheckTokenFilter extends OncePerRequestFilter {
@Resource
private JwtUtils jwtUtils;
@Resource
private CustomerUserDetailsService customerUserDetailsService;
@Resource
private LoginFailureHandler loginFailureHandler;
@Resource
private RedisService redisService;
//获取登录请求地址
@Value("${request.login.url}")
private String loginUrl;
@Value("${request.interface.url}")
private String apiUrl;
@Value("${request.ssoLogin.url}")
private String ssoLoginUrl;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
//获取当前请求的url地址
String url = request.getRequestURI();
//如果当前请求不是登录请求或接口请求, 则需要进行token验证 || url.equals("/doc.html")
if (!(url.equals(loginUrl) || url.equals(apiUrl) || url.equals(ssoLoginUrl) || url.equals("/doc.html") )) {
//进行token验证
this.validateToken(request);
}
}catch (AuthenticationException e){
loginFailureHandler.onAuthenticationFailure(request, response, e);
}
//登录请求不需要验证token
doFilter(request, response, filterChain);
}
/**
* 进行token验证
* @param request
* @throws AuthenticationException
*/
private void validateToken(HttpServletRequest request) throws AuthenticationException {
//从头部获取token信息
String token = request.getHeader("token");
//如果请求头部没有获取到token,则从请求的参数中进行获取
if (ObjectUtils.isEmpty(token)) {
token = request.getParameter("token");
}
//如果请求参数中也不存在token信息,则抛出异常
if (ObjectUtils.isEmpty(token)) {
throw new CustomerAuthenticationException("未经认证的非法访问!");
}
//判断redis中是否存在该token
String tokenKey = "token_" + token;
String redisToken = redisService.get(tokenKey);
//如果redis里面没有token,说明该token失效
if (ObjectUtils.isEmpty(redisToken)) {
throw new CustomerAuthenticationException("会话超时,请重新登录!");
}
//如果token和Redis中的token不一致,则验证失败
if (!token.equals(redisToken)) {
throw new CustomerAuthenticationException("验证失败,请联系管理员!");
}
//如果存在token,则从token中解析出用户名
String username = jwtUtils.getUsernameFromToken(token);
//如果用户名为空,则解析失败
if (ObjectUtils.isEmpty(username)) {
throw new CustomerAuthenticationException("用户解析失败,请联系管理员!");
}
//获取用户信息
UserDetails userDetails = customerUserDetailsService.loadUserByUsername(username);
//判断用户信息是否为空
if (userDetails == null) {
throw new CustomerAuthenticationException("用户信息验证失败,请联系管理员!");
}
//创建身份验证对象
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
//设置到Spring Security上下文
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启权限注解控制
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private CustomerUserDetailsService customerUserDetailsService;
@Resource
private LoginSuccessHandler loginSuccessHandler;
@Resource
private LoginFailureHandler loginFailureHandler;
@Resource
private AnonymousAuthenticationHandler anonymousAuthenticationHandler;
@Resource
private CustomerAccessDeniedHandler customerAccessDeniedHandler;
@Resource
private CheckTokenFilter checkTokenFilter;
/**
* 注入加密处理类
* @return
*/
@Bean
public BCryptPasswordEncoderHandler passwordEncoder(){
return new BCryptPasswordEncoderHandler();
}
/**
* 处理登录认证
* @param http
* @throws Exception
*/
protected void configure(HttpSecurity http) throws Exception {
//登录前进行过滤
http.addFilterBefore(checkTokenFilter, UsernamePasswordAuthenticationFilter.class);
//表单登录
http.formLogin()
//登录请求
.loginProcessingUrl("/user/login")
//设置登录用户名和密码,和默认一致就不用设置
//.usernameParameter("username")
//.passwordParameter("password")
//设置登录验证成功或失败后的的跳转地址
.successHandler(loginSuccessHandler)
.failureHandler(loginFailureHandler)
// 禁用csrf防御机制
.and().csrf().disable()
.sessionManagement()
//不创建Session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
//设置需要拦截的请求
.authorizeRequests()
//不拦截登录请求
.antMatchers("/user/login")
.permitAll()
.antMatchers("/api/warn/*")
.permitAll()
.antMatchers("/api/login/*")
.permitAll()
// .antMatchers("/openapi/**", "/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html**", "/webjars/**")
// .permitAll()
//其它请求都需要拦截和身份认证
.anyRequest()
.authenticated()
.and()
.exceptionHandling()
//匿名无权限访问
.authenticationEntryPoint(anonymousAuthenticationHandler)
//认证用户无权限访问
.accessDeniedHandler(customerAccessDeniedHandler)
.and()
.cors();//开启跨域配置
}
/**
* 配置认证处理器
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//密码加密
auth.userDetailsService(customerUserDetailsService)
.passwordEncoder(passwordEncoder());
}
}