spring-cloud / spring-cloud-gateway

An API Gateway built on Spring Framework and Spring Boot providing routing and more.
http://cloud.spring.io
Apache License 2.0
4.5k stars 3.31k forks source link

Consider removing `GatewayReactiveOAuth2AutoConfiguration` #3493

Open sjohnr opened 1 month ago

sjohnr commented 1 month ago

Expected Behavior

In Spring Security 6.3, we simplified configuration by introducing a new BeanDefinitionRegistryPostProcessor to register a ReactiveOAuth2AuthorizedClientManager bean if one is not already present.

Note that we aren't using @Conditional... annotations to register this bean since we don't depend on Spring Boot, and without @AutoConfigureAfter ordering would be an issue.

When both Spring Security and Spring Cloud Gateway are on the classpath with the TokenRelay filter in use, the reactive gateway's GatewayReactiveOAuth2AutoConfiguration registers a ReactiveOAuth2AuthorizedClientManager which prevents the one provided by Spring Security from being registered. Given the new feature in 6.3, I think we can remove the auto-configuration in reactive gateway and allow Spring Security to provide the bean during post-processing.

Additional context

I noticed this when working on a sample to enable the new Token Exchange feature in an OAuth2 Client that is using reactive Spring Cloud Gateway. With the new feature, I expect to be able to register the following bean:

    @Bean
    public TokenExchangeReactiveOAuth2AuthorizedClientProvider tokenExchange(
            ReactiveClientRegistrationRepository clientRegistrationRepository,
            ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {

        TokenExchangeReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
                new TokenExchangeReactiveOAuth2AuthorizedClientProvider();
        authorizedClientProvider.setSubjectTokenResolver(...);

        return authorizedClientProvider;
    }

and have this picked up by Spring Security and wired into the default instance of ReactiveOAuth2AuthorizedClientManager, thus enabling the Token Exchange grant type. Instead, it isn't picked up and the token exchange flow fails due to missing support for the Token Exchange grant type.

To use Spring Security's provided ReactiveOAuth2AuthorizedClientManager (as a workaround), applications can include:

@EnableAutoConfiguration(exclude = GatewayReactiveOAuth2AutoConfiguration.class)

However, this isn't straight-forward and requires some advanced knowledge to troubleshoot why Spring Security's default isn't being provided.

Alternatively, applications can register their own ReactiveOAuth2AuthorizedClientManager bean to override auto-configuration. This isn't ideal since the solution isn't able to take advantage of the simplified configuration feature in Spring Security.

Note: I can make the sample repository available shortly if a reproducer is needed.

sjohnr commented 1 month ago

I should mention, I have not yet checked to see if a similar issue exists for MVC gateway.

sjohnr commented 1 day ago

@spencergibb any thoughts on this one?

spencergibb commented 1 day ago

I think it sounds good.

sjohnr commented 23 hours ago

Thanks. Do we also have a similar issue on the MVC gateway?