配置了 MVC 拦截器,保存登录信息,但是仍然被 Spring Security 拦截,显示未登录
项目使用 Spring Security(以下简称 SS),在拦截器中获取 Session 并保存登录信息,但是前端登录后,发起请求时仍然得到未登录的响应。
推测是因为 MVC 拦截器的处理逻辑在 SS 之后。
请求先经过 SS,才会进入拦截器,因此直接被 SS 拦截。
通过自定义配置 Filter 解决了这个问题。
java
/**
* @author Rylin Wolf
*/
@Component
@RequiredArgsConstructor
public class LoginStoreFilter extends OncePerRequestFilter {
private final UserAdminAuthMediator mediator;
@Override
protected void doFilterInternal(HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
// 1. 获取登录用户,验证字段
UserLocalDto loginUser = (UserLocalDto) request.getSession()
.getAttribute(UserConstant.LOGIN_USER_SESSION_KEY);
// 未登录,直接放行
if (loginUser == null) {
filterChain.doFilter(request, response);
return;
}
// 省略业务方法...
SecurityContextHolder.getContext()
.setAuthentication(token);
filterChain.doFilter(request, response);
}
}
然后在 SS 的配置中,添加该过滤器。
java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http,
AccessDeniedHandler accessDeniedHandler,
AuthenticationEntryPoint entryPoint,
LoginStoreFilter loginFilter) throws Exception {
http.formLogin(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable)
.logout(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(a -> {
// 配置请求验证规则
})
.exceptionHandling((e) -> e.authenticationEntryPoint(entryPoint)
.accessDeniedHandler(accessDeniedHandler))
// 添加过滤器
.addFilterAfter(loginFilter, UsernamePasswordAuthenticationFilter.class)
;
return http.build();
}