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.