Browse Source

docs: add application-scoped access tokens example for reactive OAuth2 client

Signed-off-by: C0ng_yun <s25069@gsm.hs.kr>
pull/18838/head
C0ng_yun 4 weeks ago
parent
commit
11e6b069bd
  1. 35
      docs/modules/ROOT/pages/reactive/oauth2/client/authorization-grants.adoc
  2. 60
      docs/src/test/java/org/springframework/security/docs/reactive/oauth2/webclient/ApplicationScopedAccessTokenConfiguration.java
  3. 66
      docs/src/test/java/org/springframework/security/docs/reactive/oauth2/webclient/ApplicationScopedAccessTokenTests.java

35
docs/modules/ROOT/pages/reactive/oauth2/client/authorization-grants.adoc

@ -340,7 +340,7 @@ class OAuth2ClientSecurityConfig { @@ -340,7 +340,7 @@ class OAuth2ClientSecurityConfig {
Please refer to the https://tools.ietf.org/html/rfc6749#section-4.1.3[Access Token Request/Response] protocol flow for the Authorization Code grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Authorization Code grant is `WebClientReactiveAuthorizationCodeTokenResponseClient`, which uses a `WebClient` for exchanging an authorization code for an access token at the Authorization Servers Token Endpoint.
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Authorization Code grant is `WebClientReactiveAuthorizationCodeTokenResponseClient`, which uses a `WebClient` for exchanging an authorization code for an access token at the Authorization Server's Token Endpoint.
:section-id: authorization-code
:grant-type: Authorization Code
@ -432,7 +432,7 @@ Please refer to the OAuth 2.0 Authorization Framework for further details on the @@ -432,7 +432,7 @@ Please refer to the OAuth 2.0 Authorization Framework for further details on the
Please refer to the https://tools.ietf.org/html/rfc6749#section-6[Access Token Request/Response] protocol flow for the Refresh Token grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Refresh Token grant is `WebClientReactiveRefreshTokenTokenResponseClient`, which uses a `WebClient` when refreshing an access token at the Authorization Servers Token Endpoint.
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Refresh Token grant is `WebClientReactiveRefreshTokenTokenResponseClient`, which uses a `WebClient` when refreshing an access token at the Authorization Server's Token Endpoint.
:section-id: refresh-token
:grant-type: Refresh Token
@ -512,7 +512,7 @@ Please refer to the OAuth 2.0 Authorization Framework for further details on the @@ -512,7 +512,7 @@ Please refer to the OAuth 2.0 Authorization Framework for further details on the
Please refer to the https://tools.ietf.org/html/rfc6749#section-4.4.2[Access Token Request/Response] protocol flow for the Client Credentials grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Client Credentials grant is `WebClientReactiveClientCredentialsTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Servers Token Endpoint.
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Client Credentials grant is `WebClientReactiveClientCredentialsTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server's Token Endpoint.
:section-id: client-credentials
:grant-type: Client Credentials
@ -698,6 +698,31 @@ class OAuth2ClientController { @@ -698,6 +698,31 @@ class OAuth2ClientController {
If not provided, it will be obtained from the https://projectreactor.io/docs/core/release/reference/#context[Reactor's Context] via the key `ServerWebExchange.class`.
====
[[oauth2-client-client-credentials-application-scoped]]
=== Use the Client Credentials Grant for Application-Scoped Access Tokens
When making requests that are not associated with a specific user (e.g. background jobs, batch processes, or scheduled tasks), use `AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager` instead of `DefaultReactiveOAuth2AuthorizedClientManager`.
Unlike `DefaultReactiveOAuth2AuthorizedClientManager`, `AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager` operates outside of a `ServerWebExchange` context, making it suitable for application-scoped access tokens.
The following example shows how to configure a `WebClient` for application-scoped access tokens using the Client Credentials grant:
.WebClient with Application-Scoped Access Tokens
[tabs]
======
Java::
+
[source,java,role="primary",indent=0]
----
include::{tests-dir}/reactive/oauth2/webclient/ApplicationScopedAccessTokenConfiguration.java[tag=webclient-client-credentials]
----
======
[NOTE]
====
`AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager` uses a `ReactiveOAuth2AuthorizedClientService` to persist authorized clients, rather than a `ServerOAuth2AuthorizedClientRepository`.
This makes it suitable for use cases where there is no active `ServerWebExchange`, such as background tasks or scheduled jobs.
====
[[oauth2-client-jwt-bearer]]
== JWT Bearer
@ -714,7 +739,7 @@ Please refer to JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication @@ -714,7 +739,7 @@ Please refer to JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication
Please refer to the https://datatracker.ietf.org/doc/html/rfc7523#section-2.1[Access Token Request/Response] protocol flow for the JWT Bearer grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the JWT Bearer grant is `WebClientReactiveJwtBearerTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Servers Token Endpoint.
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the JWT Bearer grant is `WebClientReactiveJwtBearerTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server's Token Endpoint.
:section-id: jwt-bearer
:grant-type: JWT Bearer
@ -922,7 +947,7 @@ Please refer to OAuth 2.0 Token Exchange for further details on the https://data @@ -922,7 +947,7 @@ Please refer to OAuth 2.0 Token Exchange for further details on the https://data
Please refer to the https://datatracker.ietf.org/doc/html/rfc8693#section-2[Token Exchange Request and Response] protocol flow for the Token Exchange grant.
====
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Token Exchange grant is `WebClientReactiveTokenExchangeTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Servers Token Endpoint.
The default implementation of `ReactiveOAuth2AccessTokenResponseClient` for the Token Exchange grant is `WebClientReactiveTokenExchangeTokenResponseClient`, which uses a `WebClient` when requesting an access token at the Authorization Server's Token Endpoint.
:section-id: token-exchange
:grant-type: Token Exchange

60
docs/src/test/java/org/springframework/security/docs/reactive/oauth2/webclient/ApplicationScopedAccessTokenConfiguration.java

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
/*
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.docs.reactive.oauth2.webclient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class ApplicationScopedAccessTokenConfiguration {
// tag::webclient-client-credentials[]
@Bean
ReactiveOAuth2AuthorizedClientManager authorizedClientManager(
ReactiveClientRegistrationRepository clientRegistrationRepository,
ReactiveOAuth2AuthorizedClientService authorizedClientService) {
var authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
var authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
@Bean
WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {
var oauth2Client = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2Client.setDefaultClientRegistrationId("my-client");
return WebClient.builder()
.filter(oauth2Client)
.build();
}
// end::webclient-client-credentials[]
}

66
docs/src/test/java/org/springframework/security/docs/reactive/oauth2/webclient/ApplicationScopedAccessTokenTests.java

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
/*
* Copyright 2004-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.docs.reactive.oauth2.webclient;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.test.SpringTestContext;
import org.springframework.security.config.test.SpringTestContextExtension;
import org.springframework.security.oauth2.client.ReactiveOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.web.reactive.function.client.WebClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests {@link ApplicationScopedAccessTokenConfiguration}.
*/
@ExtendWith(SpringTestContextExtension.class)
public class ApplicationScopedAccessTokenTests {
public final SpringTestContext spring = new SpringTestContext(this);
@Autowired
WebClient webClient;
@Test
void webClientWhenClientCredentialsThenConfigured() {
this.spring.register(TestConfig.class, ApplicationScopedAccessTokenConfiguration.class).autowire();
assertThat(this.webClient).isNotNull();
}
@Configuration
static class TestConfig {
@Bean
ReactiveClientRegistrationRepository clientRegistrationRepository() {
return Mockito.mock(ReactiveClientRegistrationRepository.class);
}
@Bean
ReactiveOAuth2AuthorizedClientService authorizedClientService() {
return Mockito.mock(ReactiveOAuth2AuthorizedClientService.class);
}
}
}
Loading…
Cancel
Save