Describe the bug The default autoconfiguration of OAuth2 client:

@Bean
SecurityFilterChain oauth2SecurityFilterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
    http.oauth2Login(Customizer.withDefaults()); // <----------------
    http.oauth2Client(); // <--------------------------------------------
    return http.build();
}

end up registering the OAuth2AuthorizationRequestRedirectFilter twice. If I dump the filter chain I see:

    any request
        org.springframework.security.web.session.DisableEncodeUrlFilter@7fad214a
        org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@164642a4
        org.springframework.security.web.context.SecurityContextHolderFilter@51bddd98
        org.springframework.security.web.header.HeaderWriterFilter@4faf104
        org.springframework.security.web.csrf.CsrfFilter@671ea6ff
        org.springframework.security.web.authentication.logout.LogoutFilter@2e43c38d
->      org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@104dc1a2 <-
->      org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter@314a31b0 <-
        org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter@67d32a54
        org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@235b4cb8
        org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@75cf0de5
        org.springframework.security.web.savedrequest.RequestCacheAwareFilter@77d4ac52
        org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@252744a1
        org.springframework.security.web.authentication.AnonymousAuthenticationFilter@50b0afd7
        org.springframework.security.oauth2.client.web.OAuth2AuthorizationCodeGrantFilter@4735d6e5
        org.springframework.security.web.access.ExceptionTranslationFilter@49fb0bbd
        org.springframework.security.web.access.intercept.AuthorizationFilter@24c8d8be

BTW this was reported originally against Springboot here: https://github.com/spring-projects/spring-boot/issues/34406

This is confusing as the breakpoint hits twice if the request is going past these filters. If the first filter handles the request then second instance is never called.

To Reproduce Use the default OAuth2 client autoconfiguration and look at the filters in the filter chain.

Expected behavior The both oauth2Login() and oauth2Client() DSLs are used just install the OAuth2AuthorizationRequestRedirectFilter filter only once.

Sample N/A

Comment From: marcusdacoregio

Hi @sandipchitale.

I believe that this behavior is expected since both oauth2Login() and oauth2Client() configures the authorization_code slightly different, oauth2Login() assumes a redirect uri of {baseUrl}/login/oauth2/code/{registrationId} and uses a RequestCache to replay the request prior to authentication. While oauth2Client() uses any redirect uri you want and continues the filter chain afterward. But that could be wrong.

With that said, does having those two filters cause you any problems?

Comment From: sandipchitale

@marcusdacoregio I understand that oauth2Login() and oauth2Client() handle different things. Even though having the same filter ( OAuth2AuthorizationRequestRedirectFilter ) in filter chain does not cause a functional problem but it was very confusing when I had set a breakpoint in the filter and it was getting hit twice. It took me some time to realize that two instances of the same filter were in the chain (when I looked at the @nnnn object id in the debugger variables view). Because both the DSLs come from the same library, I was suggesting if the two DSLs could coordinate and use the same filter instance. Also note that when request qualifies to be handled by the filter the first one processes it and second one is not used. When the request does not qualify it just passes past both instances, meaning only one instance is really used when applicable.

Comment From: sandipchitale

BTW the same issue was filed again Springboot https://github.com/spring-projects/spring-boot/issues/34406 . I was requested to file it here.

Comment From: sjohnr

@sandipchitale I'm sorry you ran into confusion with two instances of the filter in the filter chain. This issue is a side-effect of a design decision that is probably a bit beyond changing at this point. The DSL for oauth2Login() vs oauth2Client() do allow configuring things differently as @marcusdacoregio mentioned. Because of that, it would not be simple to combine the two cases without breaking backwards compatibility.

However, I will mention that as we look towards Spring Security 7, we are thinking a lot about these types of issues and aiming to simplify configuration and make it less confusing in general, so this is extremely valuable feedback.

Having said that, I'm going to close this issue for now. If you do find a functional issue, let us know and we can re-open to look deeper.

Comment From: sandipchitale

Glad to hear you are thinking of simplifying this. Great work BTW. Thanks you. I filed the issue here as well so that you are aware people are raising similar issues on Springboot.