当身份验证失败时,将弹簧安全性更改为返回401

发布于 2025-02-11 19:26:45 字数 2343 浏览 0 评论 0原文

在我的Spring Boot(v。2.7.0)应用程序中,我正在使用Spring Security进行身份验证。如果用户尝试使用无效的凭据登录,则服务器使用403(禁止)状态代码响应,但是我希望401 (未经授权)可以使用。

我在配置中找不到任何表明弹簧安全性默认行为的任何东西,但是无论它是否有,我希望在身份验证失败时返回401。

我介入了相关的弹簧安全代码,看来弹簧安全 方法simpleurlauthenticationfailurehandler.onauthenticationfailure在身份验证失败时被调用。该方法包括该行,

response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());

但由于某种原因,403返回了客户端 - 因此,我想在上面的行之后正在更改响应。

当身份验证失败时,如何将弹簧安全性更改为返回401?我在下面包含了我的安全配置以供参考。

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {

    @Autowired
    private AuthenticationConfiguration authenticationConfiguration;

    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {
        AuthenticationManager authenticationManager = authenticationConfiguration.getAuthenticationManager();
        var jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager);

        var jwtAuthorisationFilter = new JwtAuthorisationFilter();

        http.cors().and().csrf().disable().authorizeRequests()
            .anyRequest().authenticated().and()
            .addFilter(jwtAuthenticationFilter)
            .addFilterAfter(jwtAuthorisationFilter, BasicAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        return http.build();
    }
}

jwtauthenticationFilter调用authenticationManager.authenticate,它会导致org.springframework.security.authentication.badcredentialsexception.badcredentialsexception如果凭证为Invaliends Invalid。

更新

我尝试添加自定义AuthenticationFailureHandler bean a>,但是我的自定义bean从未被调用(默认的bean simpleurlauthenticationfailurehandler被调用)。

In my Spring Boot (v. 2.7.0) app, I'm using Spring Security for authentication. If a user attempts to login with invalid credentials, the server responds with a 403 (Forbidden) status code, but I would expect 401 (Unauthorized) to be used instead.

I can't find anything in my configuration that indicates the default behaviour of Spring Security has been overriden, but whether it has or not, I want 401 to be returned when authentication fails.

I stepped through the relevant Spring Security code and it appears the Spring Security
method SimpleUrlAuthenticationFailureHandler.onAuthenticationFailure is called when authentication fails. This method includes the line

response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase());

But for some reason 403 is returned to the client - so I guess the response is being changed subsequent to the line above.

How can I change Spring Security to return 401 when authentication fails? I've included my security configuration below for reference.

@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true, jsr250Enabled = true)
public class SecurityConfiguration {

    @Autowired
    private AuthenticationConfiguration authenticationConfiguration;

    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {
        AuthenticationManager authenticationManager = authenticationConfiguration.getAuthenticationManager();
        var jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager);

        var jwtAuthorisationFilter = new JwtAuthorisationFilter();

        http.cors().and().csrf().disable().authorizeRequests()
            .anyRequest().authenticated().and()
            .addFilter(jwtAuthenticationFilter)
            .addFilterAfter(jwtAuthorisationFilter, BasicAuthenticationFilter.class)
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        return http.build();
    }
}

The JwtAuthenticationFilter calls authenticationManager.authenticate which causes a org.springframework.security.authentication.BadCredentialsException to be thrown if the credentials are invalid.

Update

I tried adding a custom AuthenticationFailureHandler bean as described in this article, but my custom bean is never invoked (the default bean SimpleUrlAuthenticationFailureHandler is called instead).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甚是思念 2025-02-18 19:26:45

您可以提供自己的自定义AccessDeniedHandler实现。

@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
    AuthenticationManager authenticationManager = authenticationConfiguration.getAuthenticationManager();
    var jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager);

    var jwtAuthorisationFilter = new JwtAuthorisationFilter();

    http.cors().and().csrf().disable().authorizeRequests()
        .anyRequest().authenticated().and()
        .addFilter(jwtAuthenticationFilter)
        .addFilterAfter(jwtAuthorisationFilter, BasicAuthenticationFilter.class)
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .exceptionHandling()
        .accessDeniedHandler( (request, response, exception) ->
             response.sendError(HttpStatus.UNAUTHORIZED.value(), exception.getMessage()
        ));

    return http.build();
}

You can provide your own custom AccessDeniedHandler implementation.

@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
    AuthenticationManager authenticationManager = authenticationConfiguration.getAuthenticationManager();
    var jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager);

    var jwtAuthorisationFilter = new JwtAuthorisationFilter();

    http.cors().and().csrf().disable().authorizeRequests()
        .anyRequest().authenticated().and()
        .addFilter(jwtAuthenticationFilter)
        .addFilterAfter(jwtAuthorisationFilter, BasicAuthenticationFilter.class)
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .exceptionHandling()
        .accessDeniedHandler( (request, response, exception) ->
             response.sendError(HttpStatus.UNAUTHORIZED.value(), exception.getMessage()
        ));

    return http.build();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文