Spring(引导)具有允许资源的安全预身份验证仍然经过身份验证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring(引导)具有允许资源的安全预身份验证仍然经过身份验证相关的知识,希望对你有一定的参考价值。

我使用的是Spring Boot 1.5.6(也尝试过1.5.4)。我正在使用

RequestHeaderAuthenticationFilter 

和a

PreAuthenticatedAuthenticationProvider 

保护我的spring mvc web应用程序,并允许访问控制器路径和静态资源。

在我的

RequestHeaderAuthenticationFilter

设置我想要的

setExceptionIfHeaderMissing(true);

所以我知道是否在请求中发送了头变量。

当我尝试访问任何允许的资源时,Spring Security始终在请求中查找头变量并抛出一个

PreAuthenticatedCredentialsNotFoundException

为什么即使我试图访问允许的(未受保护的)资源,Spring安全仍然会尝试查找预先验证的主体?我怎样才能规避这种行为?

我的WebSecurityConfigurerAdapter的java配置如下

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{


private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class);


@Autowired
protected UserDetailsService userDetailsService; 



@Bean
public PreAuthenticatedAuthenticationProvider preAuthenticatedAuthenticationProvider(){

    log.info("Configuring pre authentication provider");

    UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken> wrapper = 
            new UserDetailsByNameServiceWrapper<PreAuthenticatedAuthenticationToken>(
                    userDetailsService);

    PreAuthenticatedAuthenticationProvider it = new PreAuthenticatedAuthenticationProvider();
    it.setPreAuthenticatedUserDetailsService(wrapper);

    return it;      
} 

@Bean
public RequestHeaderAuthenticationFilter requestHeaderAuthenticationFilter() throws Exception{

    RequestHeaderAuthenticationFilter it = new RequestHeaderAuthenticationFilter();
    it.setAuthenticationManager(authenticationManager());
    it.setExceptionIfHeaderMissing(true);
    return it;
}

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    log.info("configure authentication provider");
    auth.authenticationProvider(preAuthenticatedAuthenticationProvider());

}


@Override
protected void configure(HttpSecurity http) throws Exception {
    log.info("Configure HttpSecurity");
    http
        .authorizeRequests()
            .antMatchers("/permitted/**", "/css/**", "/js/**", "/images/**", "/webjars/**")
                .permitAll()
            .anyRequest()
                    .authenticated()
            .and().addFilter(requestHeaderAuthenticationFilter())

    ;
}    


 @Override
 public void configure(WebSecurity web) throws Exception {
     web
        .ignoring()
            .antMatchers("/permitted/**", "/css/**", "/js/**", "/images/**", "/webjars/**"); 
}   
}
答案

我遇到了同样的问题,事实证明,除了在SecurityFilterChain中注册之外,Spring Boot还在使用Servlet Context注册RequestHeaderAuthenticationFilter。解决方案是使用FilterRegistrationBean来防止Boot使用Servlet Context自动注册过滤器。

更多细节在这里:Spring Boot Security PreAuthenticated Scenario with Anonymous access

以上是关于Spring(引导)具有允许资源的安全预身份验证仍然经过身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 2 安全性 - 预认证令牌 - 允许运行状况检查

具有多个身份验证提供程序的 Spring 安全性 - UsernameNotFoundException

具有Spring安全性的LDAP身份验证

Spring Boot:使用 Junit 模拟具有安全上下文的用户身份验证

具有 3 个字段的 Spring 安全身份验证,而不仅仅是用户名和密码

具有基本身份验证和 OAuth 顺序问题的 Spring Boot 安全性