java - 当授权 header 存在时,Spring Security 忽略路径过滤器仍然执行

标签 java spring spring-security

我设置了一个完全工作的 Spring 安全流程,其中一些路径需要身份验证(通过 token ),而其他路径我希望在没有 token 的情况下保持开放和可访问。我遇到的问题是,当请求进入没有 Authorization header 的开放路径之一时,过滤器将被忽略并生成正确的响应。但是,当存在 Authorization header 时,即使在被忽略的路径上,请求也会通过整个安全过滤器链,而理想的过程是完全跳过过滤器链。

下面是我的配置。

    @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);
    }
}

我还尝试使用 permitAll() 将忽略的路径放入 HttpSecurity 中,但没有成功。

澄清

String[] DEFAULT_IGNORE_REQUESTS = new String[]{ "/actuator" };

在上面描述的情况下,任何发送到 /example/** 的请求都应该通过安全链和我的过滤器,以确保用户经过身份验证。任何发送到 /actuator 的请求都不应经过安全过滤器链。 /example/** 工作正常且符合预期。然而 /actuator 却没有。

当我发出没有Authorization header 的请求时,不会调用安全链。 当我发出带有 Authorization header 的请求时,将调用安全链并验证 Authorization 值( token )。如果 token 无效,则会在过滤器内引发自定义异常。即使抛出错误,我也会从 /actuator 得到预期的响应,响应值为 200。然而,在这种情况下抛出的错误会被记录并生成堆栈跟踪,这是我不想要的,因为它不是在这种情况下会出现错误。

最佳答案

在 Spring Boot 中,Filter 类型的任何 @Bean 都会添加为 servlet 过滤器。最有可能发生的情况是,您的过滤器被添加为完全独立于过滤器链的过滤器。

您可以在 WebSecurityConfigurerAdapter 中初始化 AuthenticationTokenHeaderFilter 并设置 AuthenticationManager,而不是将过滤器声明为 @Bean code> 直接(无论如何你已经这样做了)。因此,您可以删除过滤器中的@Autowired注释。

关于java - 当授权 header 存在时,Spring Security 忽略路径过滤器仍然执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57824924/

相关文章:

java - Spring-Security:当 AuthenticationManager 抛出 BadCredentialsException 时返回状态 401

spring-security - Spring Security 3.1 和正确的 jar

java - 从java小程序获取正确的本地IP地址

java - 如何通过 asyncTask 方法解析来自 2 个不同 URL 的数据

java - 使用 Spring Data REST 的 JsonMappingException : Selects wrong serializer when @Id is removed from the list that that is being mapped

java - 如何根据 href 链接动态更改 Thymeleaf 片段

java - 没有获得Spring Security自动生成的登录页面

引用对象的Java序列化是 "losing values"?

java - 电子邮件发送代码不适用于 ubuntu

java - 为什么我在使用 Spring Data JPA 的 Spring Boot 项目中获取此 "org.hibernate.exception.SQLGrammarException"?