14463 introduced a condition on the Reactive OAuth2 auto-configuration support that disables it for Servlet applications. Since the Spring team has decided not to make any OAuth2 support available for RestTemplate, WebClient support is reluctantly needed in Servlet applications as well. This auto-configuration, which covers only client support, should not be disabled merely because it's running in a traditional application.
Comment From: jgrandja
@chrylis ReactiveOAuth2ClientAutoConfiguration
is implemented correctly.
It will conditionally register the @Bean
's ReactiveClientRegistrationRepository
, ReactiveOAuth2AuthorizedClientService
and ServerOAuth2AuthorizedClientRepository
.
These are WebFlux components and therefore should only be registered in a WebFlux environment.
Although new features will not be added to RestTemplate
it will not be going away anytime soon. It will likely be supported for quite some time still given the wide-spread usage of it.
It is common practice to use both RestTemplate
and WebClient
in an oauth2-client
application.
FYI, take a look at this sample that demonstrates common implementation patterns and flows used between client, authorization server and resource server.
Comment From: chrylis
I am writing a traditional HTML application that needs to use client_credentials
to access information from a resource server. Spring Security 5 OAuth2 provides token-injection support only for WebClient
(via the ServerOAuth2AuthorizedClientExchangeFilterFunction
), not RestTemplate
(as with the former OAuth2RestTemplate
), and using that filter requires either a ReactiveOAuth2AuthorizedClientManager
or ReactiveClientRegistrationRepository
and ServerOAuth2AuthorizedClientRepository
. There is nothing semantically that constrains this to a WebFlux environment.
(Note that in your linked sample, the use case at question, WebClient
in a Servlet environment, is 404.)
Comment From: bclozel
We've discussed this as a team, I'll share here the different aspects:
First: WebClient
is part of the spring-webflux
module but is not necessarily tied to WebFlux web applications. Arguably the Framework team chose to host the WebClient
class in spring-webflux
and RestTemplate
in spring-web
, making things a bit more difficult here - but I'd summarize the current position of the Framework team like this:
RestTemplate
has been put in maintenance mode. It's not deprecated and will remain for the Framework 6.x line. The team is not going to evolve its contracts nor address modern HTTP use cases like data streaming.
Right now, a Spring Boot application with both spring-mvc
and spring-webflux
on the classpath will result in a Spring MVC server application. But Spring Boot will still contribute a WebClient.Builder
bean because using a WebClient
in a Spring MVC app is not only a perfectly valid use case, it's advertised by the Framework team as a way to get familiar with reactive and work around the RestTemplate
limitations around streaming and more.
With that in mind, we are wondering:
1. should we remove the condition that prevents the reactive variant from being registered outside of an MVC scope?
2. with this condition, doesn't this prevent developers from using that component in non-web use cases? In other words, should ReactiveOAuth2Client
components be available to CLI apps?
3. it sounds like @chrylis is saying that the RestTemplate
and WebClient
variants of that component don't offer the same features. Is that linked to a particular limitation of RestTemplate
?
4. what would happen if both reactive + non-reactive variants would be available in the application context? Would Spring Security fail in a particular case? Would the components miss some important part of the infrastructure to work (in an MVC, WebFlux or CLI app case)
Comment From: mbhave
@jgrandja @rwinch Could you provide more insight into points 3 and 4 from Brian's comment, please?
Comment From: rwinch
it sounds like @chrylis is saying that the RestTemplate and WebClient variants of that component don't offer the same features. Is that linked to a particular limitation of RestTemplate?
Correct. The WebClient APIs allow for attributes to be passed in but RestTemplate does not. The OAuth features rely on the attributes. What's more is that if RestTemplate is in maintenance mode, I do not feel that it makes sense for the Security team to use our time to provide OAuth support for it (it is documented that no features are being added to it).
what would happen if both reactive + non-reactive variants would be available in the application context? Would Spring Security fail in a particular case?
I'm not sure I follow this question because I'm not sure what specifically variants is referring to.
Comment From: mbhave
I'm not sure I follow this question because I'm not sure what specifically variants is referring to.
It's referring to switching on the beans configured both by ReactiveOAuth2ClientAutoConfiguration
and OAuth2ClientAutoConfiguration
. But, I don't think that would make a difference because the beans configured by ReactiveOAuth2ClientAutoConfiguration
are only used in a webflux application, as @jgrandja pointed out, and the beans auto-configured by OAuth2ClientAutoConfiguration
are only used in a servlet environment.
The WebClient APIs allow for attributes to be passed in but RestTemplate does not. The OAuth features rely on the attributes.
@rwinch Given this, what is the best way to use WebClient
for OAuth2 requests in a servlet application?
Comment From: chrylis
So I'm clear, my comments here are talking specifically about the Spring Security 5 OAuth2 client integrations with the Spring REST clients, providing features like "declare an OAuth2 client configuration in your Spring Boot configuration and have it automatically contribute an access token to REST requests".
1–2. The condition doesn't prevent registration outside a reactive Web application; rather, it specifically blocks registration inside a Servlet application. Usage in an entirely non-Web application is not currently a problem; in that case, the auto-token filter would not be acquiring credentials to relay from an incoming request, but client_credentials
would operate normally (e.g., for a Quartz or message-driven application).
3. The legacy "Spring Security OAuth2 2", replaced with "Spring Security 5 OAuth2", removed the subclass OAuth2RestTemplate
(which sort of monkey-patched OAuth2 support onto RestTemplate), and it supports WebClient using a filter but does not provide an equivalent RestTemplate interceptor. Configuring this WebClient filter requires the bean dependencies discussed.
Comment From: chrylis
What's more is that if RestTemplate is in maintenance mode
This isn't the place to reopen that particular discussion, but I believe that the Spring team is unrealistically overoptimistic about an upcoming tipping point to reactive as the default way of doing things, and dropping support for the way that 90%+ of projects are written is... frustrating.
Comment From: chrylis
@mbhave You are conflating an application using Webflux to serve content and an application using Webflux to consume content. I have a Servlet application using MVC to serve content but using WebClient to consume content.
Comment From: rwinch
It's referring to switching on the beans configured both by ReactiveOAuth2ClientAutoConfiguration and OAuth2ClientAutoConfiguration. But, I don't think that would make a difference because the beans configured by ReactiveOAuth2ClientAutoConfiguration are only used in a webflux application, as @jgrandja pointed out, and the beans auto-configured by OAuth2ClientAutoConfiguration are only used in a servlet environment.
I haven't sorted out what these auto configurations do, but they should not do the steps for both the reactive WebClient and servlet WebClient setups. Additionally, we cannot have ServerHttpSecurity invoked in the servlet environment.
@rwinch Given this, what is the best way to use WebClient for OAuth2 requests in a servlet application?
The instructions are in WebClient integration for Servlet Environments. I'm wondering if I am missing part of your question though? Are you wondering what should cause that to be setup? If so, I think just OAuth + Servlet environment should be reason enough to set it up.
Comment From: mbhave
Thanks for the link above, @rwinch.
@chrylis I am not conflating the two. If I was, I would have closed this issue and not involved the team for further discussion.
Regarding this sentence
Spring Security 5 OAuth2 provides token-injection support only for WebClient (via the ServerOAuth2AuthorizedClientExchangeFilterFunction), not RestTemplate (as with the former OAuth2RestTemplate), and using that filter requires either a ReactiveOAuth2AuthorizedClientManager or ReactiveClientRegistrationRepository and ServerOAuth2AuthorizedClientRepository
from this comment, from what I can tell, that isn't accurate. WebClient integration for Servlet environments can be configured via a ServletOAuth2AuthorizedClientExchangeFilterFunction
, which requires either a OAuth2AuthorizedClientManager
or ClientRegistrationRepository
and OAuth2AuthorizedClientRepository
. These are auto-configured by OAuth2ClientAutoConfiguration
for servlet applications. This sample showcases how to configure OAuth2 for WebClient in servlet applications. Can you please clarify why this setup does not work for you?
Comment From: spring-projects-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-projects-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.