我尝试通过令牌进行身份验证。我需要一个过滤器,它会检查标题中的一些标记,如果它无效 - 显示错误。
这就是我所拥有的:
public class TokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
public TokenAuthenticationFilter() {
super("/rest/**");
setAuthenticationSuccessHandler((request, response, authentication) ->
{
SecurityContextHolder.getContext().setAuthentication(authentication);
String path = request.getServletPath() + (request.getPathInfo() != null ? request.getPathInfo() : "");
request.getRequestDispatcher(path).forward(request, response);
});
setAuthenticationFailureHandler((request, response, authenticationException) -> {
response.getOutputStream().print(authenticationException.getMessage());
});
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
String token = request.getHeader("token");
if (token == null)
token = request.getParameter("token");
if (token == null) {
TokenAuthentication authentication = new TokenAuthentication(null);
authentication.setAuthenticated(false);
return authentication;
}
TokenAuthentication tokenAuthentication = new TokenAuthentication(token);
return getAuthenticationManager().authenticate(tokenAuthentication);
}
}
配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class Security extends WebSecurityConfigurerAdapter {
@Autowired
private TokenAuthenticationManager tokenAuthenticationManager;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.headers().frameOptions().sameOrigin()
.and()
.csrf()
.disable()
.addFilterAfter(restTokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers("/rest/get/1").permitAll()
.antMatchers("/rest/login").permitAll()
.antMatchers("/rest/**").authenticated();
}
@Bean(name = "restTokenAuthenticationFilter")
public TokenAuthenticationFilter restTokenAuthenticationFilter() {
TokenAuthenticationFilter restTokenAuthenticationFilter = new TokenAuthenticationFilter();
restTokenAuthenticationFilter.setAuthenticationManager(tokenAuthenticationManager);
return restTokenAuthenticationFilter;
}
}
但是此过滤器上有StackOverflowError。它每次都向这个过滤器转发请求。我认为它应该是另一个AuthenticationSuccessHandler
。
更新:如果令牌有效,使用GenericFilterBean
轻松解决问题,只做chain.doFilter(request, response);
,但如何使用AbstractAuthenticationProcessingFilter
进行解决?