Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Align code in oauth2-client extensions for WebClient #6811

Closed
21 tasks done
jgrandja opened this issue Apr 23, 2019 · 3 comments
Closed
21 tasks done

Align code in oauth2-client extensions for WebClient #6811

jgrandja opened this issue Apr 23, 2019 · 3 comments
Assignees
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: enhancement A general enhancement
Milestone

Comments

@jgrandja
Copy link
Contributor

jgrandja commented Apr 23, 2019

The WebClient extensions for OAuth 2.0 Client are supported via ServletOAuth2AuthorizedClientExchangeFilterFunction (Servlet) and ServerOAuth2AuthorizedClientExchangeFilterFunction (WebFlux).

The ServerOAuth2AuthorizedClientExchangeFilterFunction (WebFlux) uses a collaborator OAuth2AuthorizedClientResolver to realize part of the feature set. However, ServletOAuth2AuthorizedClientExchangeFilterFunction (Servlet) doesn't have such a collaborator and therefore all the code is contained within. We should consider adding an OAuth2AuthorizedClientResolver equivalent for the Servlet version to align the code and provide consistency.

Furthermore, as we continue to add support for other grant types, e.g. Resource Owner Password Credentials #6003, the code within each ExchangeFilterFunction could grow quite a bit making it more complex and harder to maintain. It is also preferred that the code in each ExchangeFilterFunction is aligned/consistent and reused wherever possible. However, we need to be careful with reuse and ensure we don't introduce a blocking operation within the reactive implementation.

As part of this decomposition exercise, we should consider re-structuring components/collaborators so they can potentially be reused by other technology stacks, e.g. WebFlux's WebSocketClient #6711, RestTemplate or Feign Client.

Related #6683, #6780

This issue is divided into the following tasks.

Servlet

  • #17 Introduce OAuth2AuthorizedClientProvider
  • #18 Implement authorization_code OAuth2AuthorizedClientProvider
  • #19 Implement client_credentials OAuth2AuthorizedClientProvider
  • #20 Add refresh_token OAuth2AccessTokenResponseClient
  • #21 Implement refresh_token OAuth2AuthorizedClientProvider
  • #22 Implement delegating OAuth2AuthorizedClientProvider
  • #29 Refactor and use OAuth2AuthorizedClientProvider implementations
  • #37 Simplify population of OAuth2AuthorizationContext
  • #59 Redesign OAuth2AuthorizedClientProvider to load/save OAuth2AuthorizedClient
  • #60 ClientCredentialsOAuth2AuthorizedClientProvider should load/save OAuth2AuthorizedClient
  • #61 RefreshTokenOAuth2AuthorizedClientProvider should load/save OAuth2AuthorizedClient
  • #62 Refactor and use redesigned OAuth2AuthorizedClientProvider implementations

Reactive

  • #42 Introduce ReactiveOAuth2AuthorizedClientProvider
  • #43 Implement authorization_code ReactiveOAuth2AuthorizedClientProvider
  • #44 Implement client_credentials ReactiveOAuth2AuthorizedClientProvider
  • #45 Add refresh_token ReactiveOAuth2AccessTokenResponseClient
  • #46 Implement refresh_token ReactiveOAuth2AuthorizedClientProvider
  • #47 Implement delegating ReactiveOAuth2AuthorizedClientProvider
  • #86 Add builder for ReactiveOAuth2AuthorizedClientProvider
  • #87 Introduce ReactiveOAuth2AuthorizedClientManager
  • #48 Refactor and use ReactiveOAuth2AuthorizedClientManager/Provider(s)
@jgrandja jgrandja self-assigned this Apr 23, 2019
@jgrandja jgrandja added type: enhancement A general enhancement in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) Reactive labels Apr 23, 2019
@jgrandja jgrandja added this to the 5.2.0.RC1 milestone Apr 23, 2019
@rwinch rwinch removed the Reactive label May 6, 2019
@jgrandja jgrandja modified the milestones: 5.2.0.M3, 5.2.x Jun 3, 2019
@jgrandja jgrandja modified the milestones: 5.2.x, 5.2.0.M4 Jul 25, 2019
@jzheaux jzheaux modified the milestones: 5.2.0.M4, 5.2.0.RC1 Aug 5, 2019
@jgrandja
Copy link
Contributor Author

Resolved after merging #7116

@jgrandja
Copy link
Contributor Author

jgrandja commented Sep 6, 2019

@fritzdj @DarrenForsythe @philsttr @kujaomega @Vaelyr

The purpose of this issue was to track related issues and associated PR's in order to resolve #6780 #6683 and to help with #6711.

With the release of 5.2.0.RC1 (today), I'd like to provide some sample code/configuration to show usage of the new interfaces and associated implementations. I do plan on documenting all of this (and a lot more) in the reference manual but that work still needs to get done. I'm hoping by 5.2.0 GA or 5.2.1 at the latest. Please see the tests as they demonstrate various use case scenarios and usage of the new API's.

Servlet

The new interfaces are OAuth2AuthorizedClientManager and OAuth2AuthorizedClientProvider.

The default implementation for OAuth2AuthorizedClientManager is DefaultOAuth2AuthorizedClientManager.

Here is a sample configuration:

OAuth2AuthorizedClientProvider authorizedClientProvider =
		OAuth2AuthorizedClientProviderBuilder.builder()
				.authorizationCode()
				.refreshToken()
				.clientCredentials()
				.password()
				.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
		clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

An instance of DefaultOAuth2AuthorizedClientManager can now be used independently with any HTTP client. For example, you can directly use this in combination with RestTemplate or Feign client or any HTTP client of your choosing.

NOTE: ServletOAuth2AuthorizedClientExchangeFilterFunction has been re-factored and now uses DefaultOAuth2AuthorizedClientManager by default. However, it can also be supplied a custom OAuth2AuthorizedClientManager.

Reactive

The new interfaces are ReactiveOAuth2AuthorizedClientManager and ReactiveOAuth2AuthorizedClientProvider.

The default implementation for ReactiveOAuth2AuthorizedClientManager is DefaultReactiveOAuth2AuthorizedClientManager.

Here is a sample configuration:

ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider =
		ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
				.authorizationCode()
				.refreshToken()
				.clientCredentials()
				.password()
				.build();
DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(
		clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

An instance of DefaultReactiveOAuth2AuthorizedClientManager can now be used independently with any reactive HTTP client.

NOTE: ServerOAuth2AuthorizedClientExchangeFilterFunction has been re-factored and now uses DefaultReactiveOAuth2AuthorizedClientManager by default. However, it can also be supplied a custom ReactiveOAuth2AuthorizedClientManager.

"Outside of Request Context" (Non-Reactive)

AuthorizedClientServiceOAuth2AuthorizedClientManager is an implementation of OAuth2AuthorizedClientManager which provides the capability of operating outside of a HttpServletRequest context, e.g. in a scheduled/background thread and/or in the service-tier.

For example, if your use case is to leverage the client_credentials grant in a @Scheduled (#6683), than your configuration would be this:

OAuth2AuthorizedClientProvider authorizedClientProvider =
		OAuth2AuthorizedClientProviderBuilder.builder()
				.clientCredentials()
				.build();
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(
		clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);

NOTE: This implementation uses an OAuth2AuthorizedClientService instead of a OAuth2AuthorizedClientRepository.

WebSocketClient integration

If you require oauth2-client functionality with WebFlux's WebSocketClient (#6711), than you would need to provide an implementation of ReactiveOAuth2AuthorizedClientManager. It would be very similar to DefaultReactiveOAuth2AuthorizedClientManager, but instead make use of WebSocketClient and/or related components. The ReactiveOAuth2AuthorizedClientProvider implementations can be reused straight-up.

Furthermore, if you require this for Servlet WebSocketClient, than implement OAuth2AuthorizedClientManager and straight-up reuse the OAuth2AuthorizedClientProvider implementations.

@mmaask
Copy link

mmaask commented Sep 6, 2019

Great news, thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: oauth2 An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants