春季安全匿名401而不是403

2022-09-01 03:40:12

我在Spring安全性中的默认行为有问题,即Java Config提供的授权请求。

http
       ....
       .authorizeRequests()
          .antMatchers("/api/test/secured/*").authenticated()

例如,当我调用没有登录(使用匿名用户)时,它会返回403 Forbidden。当匿名用户想要获得保护或资源时,是否有简单的方法可以将状态更改为“401未经授权”?/api/test/secured/userauthenticated()@PreAuthorize


答案 1

从Spring Boot 2类开始,Http401AuthenticationEntryPoint已被删除(请参阅Spring Boot Issue 10725)。

而不是Http401AuthenticationEntryPoint使用HttpStatusEntryPoint和HttpStatus.UNAUTHORIZED:

http.exceptionHandling()
    .authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED));

答案 2

有了弹簧安全4.x,已经有一个类

org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint 

弹簧靴还包括一个

org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint

并且它们要求开发人员使用符合规范的两个好处,因为401响应要求必须设置标头WWW-Authenticate,示例401响应可以是:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="example",
                   error="invalid_token",
                   error_description="The access token expired"

因此,在您的安全配置中,您可以定义并自动连接类的bean

例如,使用弹簧启动应用程序:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

    @Bean
    public Http401AuthenticationEntryPoint securityException401EntryPoint(){

        return new Http401AuthenticationEntryPoint("Bearer realm=\"webrealm\"");
    }

...
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .authorizeRequests()
                .antMatchers("/login").anonymous()
                .antMatchers("/").anonymous()
                .antMatchers("/api/**").authenticated()
            .and()
            .csrf()
                .disable()
                .headers()
                .frameOptions().disable()
            .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .logout()
                .permitAll()
         .exceptionHandling().authenticationEntryPoint(securityException401EntryPoint());
}

相关行是:

 .exceptionHandling().authenticationEntryPoint(securityException401EntryPoint());

推荐