我有一个可以正常工作的春季安全性流程,设置了一些要求身份验证(通过令牌)的路径,而另一些我希望保持开放状态且无需令牌即可访问。我遇到的问题是,当请求进入没有Authorization
头的那些开放路径之一时,过滤器将被忽略,并生成正确的响应。但是,当Authorization
标头存在时,即使在忽略的路径上,当理想的过程是完全跳过过滤器链时,请求也会通过整个安全过滤器链。
下面是我的配置。
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers(DEFAULT_IGNORE_REQUESTS);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
authenticationTokenHeaderFilter.setAuthenticationManager(authenticationManager);
http.authorizeRequests()
.antMatchers("/example/**")
.authenticated()
.and()
.exceptionHandling()
.accessDeniedHandler((request, response, accessDeniedException) -> {
response.sendError(HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage());
})
.authenticationEntryPoint(new HttpAuthenticationEntryPoint())
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.cors()
.and()
.csrf().disable()
.addFilter(authenticationTokenHeaderFilter)
.addFilterBefore(new ExceptionTranslationFilter(
new Http403ForbiddenEntryPoint()),
authenticationTokenHeaderFilter.getClass()
);
}
public class AuthenticationTokenHeaderFilter extends AbstractPreAuthenticatedProcessingFilter {
@Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest httpServletRequest) {
return httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION);
}
@Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest httpServletRequest) {
return "N/A";
}
@Override
@Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
}
我还尝试用
HttpSecurity
将忽略的路径放入permitAll()
,但没有成功。澄清度
String[] DEFAULT_IGNORE_REQUESTS = new String[]{ "/actuator" };
在上述内容中,所有进入
/example/**
的请求都应通过安全链并通过我的过滤器,以确保对用户进行身份验证。进入/actuator
的任何请求都不应通过安全筛选器链。 /example/**
正常且按预期工作。但是/actuator
不会。当我发出没有
Authorization
标头的请求时,不会调用安全链。当我使用
Authorization
标头进行请求时,将调用安全链并验证Authorization
值(令牌)。如果令牌无效,则会在过滤器内引发自定义异常。即使抛出错误,我也会从/actuator
得到200的预期响应。但是,在这种情况下抛出的错误会被记录并生成堆栈跟踪,我不希望这样做,因为在这种情况下这不是错误。 最佳答案
在Spring Boot中,任何类型为@Bean
的Filter
都将添加为servlet过滤器。最有可能发生的情况是,您的过滤器是作为与过滤器链完全分离的过滤器添加的。
您可以将@Bean
初始化为AuthenticationTokenHeaderFilter
并直接设置WebSecurityConfigurerAdapter
(无论如何,您都可以),而不是将过滤器声明为AuthenticationManager
。因此,您可以在过滤器中删除@Autowired
批注。