Describe the bug I'm currently trying to upgrade spring boot version from 3.1.5 to 3.2.2 and spring cloud version from 2022.0.4 to 2023.0.0 resulting in a org.springframework.cloud.openfeign update from 4.0.4 to 4.1.0 (and a spring-security update form 6.1.5 to 6.2.1 ).

I now get the following exception for feign client requests using a custom oauth configuration.

org.springframework.cloud.client.circuitbreaker.NoFallbackAvailableException: No fallback available.
at org.springframework.cloud.client.circuitbreaker.CircuitBreaker.lambda$run$0(CircuitBreaker.java:31)
...
Caused by: java.lang.IllegalArgumentException: servletRequest cannot be null
at org.springframework.util.Assert.notNull(Assert.java:172)
at org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizedClientManager.authorize(DefaultOAuth2AuthorizedClientManager.java:144)
at org.springframework.cloud.openfeign.security.OAuth2AccessTokenInterceptor.getToken(OAuth2AccessTokenInterceptor.java:131)
at org.springframework.cloud.openfeign.security.OAuth2AccessTokenInterceptor.getToken(OAuth2AccessTokenInterceptor.java:112)
at org.springframework.cloud.openfeign.security.OAuth2AccessTokenInterceptor.apply(OAuth2AccessTokenInterceptor.java:95)
at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:124)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:91)
...

Sample We need oauth for some FeignClients but also have others that do not need it. We therefore, created the following custom configuration (basically the same as provided in org.springframework.cloud.openfeign.FeignAutoConfiguration):

@Configuration
open class OAuthConfig {
    @Bean
    @ConditionalOnBean(
        OAuth2AuthorizedClientService::class,
        ClientRegistrationRepository::class
    )
    @ConditionalOnMissingBean
    open fun feignOAuth2AuthorizedClientManager(
        clientRegistrationRepository: ClientRegistrationRepository?,
        oAuth2AuthorizedClientService: OAuth2AuthorizedClientService?
    ): OAuth2AuthorizedClientManager {
        return AuthorizedClientServiceOAuth2AuthorizedClientManager(
            clientRegistrationRepository,
            oAuth2AuthorizedClientService
        )
    }

    @Bean
    @ConditionalOnBean(OAuth2AuthorizedClientManager::class)
    open fun defaultOAuth2AccessTokenInterceptor(
        @Value("\${spring.cloud.openfeign.oauth2.clientRegistrationId:}")
        clientRegistrationId: String?,
        oAuth2AuthorizedClientManager: OAuth2AuthorizedClientManager
    ): OAuth2AccessTokenInterceptor? {
        return OAuth2AccessTokenInterceptor(clientRegistrationId, oAuth2AuthorizedClientManager)
    }
}

And add it as configuration for the FeignClients that need oauth.

@FeignClient(name = "some-client", url = "\${some-url}", configuration = [OAuthConfig::class])
interface SomeClient {
...
}

Any requests for the clients using the OAuthConfig class fail with the aforementioned exception.

Did I miss some configuration that now needs to be added/changed with the update?

Update: Did some additional investigation. The underlying problem was that the OAuth2AuthorizedClientManager bean started to be instantiated with DefaultOAuth2AuthorizedClientManager instead of AuthorizedClientServiceOAuth2AuthorizedClientManager. I did not find what was the root cause of this though.

I changed the configuration as follows (additionally removed the @Configuration annotation as with the update it started to be used for all FeignClients not just the ones referencing the configuration. This is the desired behavior according to the documentation - just was not aware of this change):

@ConditionalOnClass(OAuth2AuthorizedClientManager::class)
open class OAuthConfig {
    @Bean
    @ConditionalOnMissingBean
    open fun feignOAuth2AuthorizedClientManager(
        clientRegistrationRepository: ClientRegistrationRepository?,
        oAuth2AuthorizedClientService: OAuth2AuthorizedClientService?
    ): AuthorizedClientServiceOAuth2AuthorizedClientManager? {
        return AuthorizedClientServiceOAuth2AuthorizedClientManager(
            clientRegistrationRepository,
            oAuth2AuthorizedClientService
        )
    }

    @Bean
    @ConditionalOnMissingBean
    open fun defaultOAuth2AccessTokenInterceptor(
        @Value("\${spring.cloud.openfeign.oauth2.clientRegistrationId:}")
        clientRegistrationId: String?,
        oAuth2AuthorizedClientManager: AuthorizedClientServiceOAuth2AuthorizedClientManager?
    ): OAuth2AccessTokenInterceptor? {
        return OAuth2AccessTokenInterceptor(clientRegistrationId, oAuth2AuthorizedClientManager)
    }
}

Comment From: OlgaMaciaszek

Hello, @bearoth do I understand correctly that everything works as documented for you? Is there any additional issue?

Comment From: spring-cloud-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-cloud-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.