use of org.springframework.security.oauth2.client.registration.ClientRegistration in project spring-security by spring-projects.
the class PasswordReactiveOAuth2AuthorizedClientProvider method authorize.
/**
* Attempt to authorize (or re-authorize) the
* {@link OAuth2AuthorizationContext#getClientRegistration() client} in the provided
* {@code context}. Returns an empty {@code Mono} if authorization (or
* re-authorization) is not supported, e.g. the client's
* {@link ClientRegistration#getAuthorizationGrantType() authorization grant type} is
* not {@link AuthorizationGrantType#PASSWORD password} OR the
* {@link OAuth2AuthorizationContext#USERNAME_ATTRIBUTE_NAME username} and/or
* {@link OAuth2AuthorizationContext#PASSWORD_ATTRIBUTE_NAME password} attributes are
* not available in the provided {@code context} OR the
* {@link OAuth2AuthorizedClient#getAccessToken() access token} is not expired.
*
* <p>
* The following {@link OAuth2AuthorizationContext#getAttributes() context attributes}
* are supported:
* <ol>
* <li>{@link OAuth2AuthorizationContext#USERNAME_ATTRIBUTE_NAME} (required) - a
* {@code String} value for the resource owner's username</li>
* <li>{@link OAuth2AuthorizationContext#PASSWORD_ATTRIBUTE_NAME} (required) - a
* {@code String} value for the resource owner's password</li>
* </ol>
* @param context the context that holds authorization-specific state for the client
* @return the {@link OAuth2AuthorizedClient} or an empty {@code Mono} if
* authorization (or re-authorization) is not supported
*/
@Override
public Mono<OAuth2AuthorizedClient> authorize(OAuth2AuthorizationContext context) {
Assert.notNull(context, "context cannot be null");
ClientRegistration clientRegistration = context.getClientRegistration();
OAuth2AuthorizedClient authorizedClient = context.getAuthorizedClient();
if (!AuthorizationGrantType.PASSWORD.equals(clientRegistration.getAuthorizationGrantType())) {
return Mono.empty();
}
String username = context.getAttribute(OAuth2AuthorizationContext.USERNAME_ATTRIBUTE_NAME);
String password = context.getAttribute(OAuth2AuthorizationContext.PASSWORD_ATTRIBUTE_NAME);
if (!StringUtils.hasText(username) || !StringUtils.hasText(password)) {
return Mono.empty();
}
if (authorizedClient != null && !hasTokenExpired(authorizedClient.getAccessToken())) {
// need for re-authorization
return Mono.empty();
}
if (authorizedClient != null && hasTokenExpired(authorizedClient.getAccessToken()) && authorizedClient.getRefreshToken() != null) {
// handle the refresh
return Mono.empty();
}
OAuth2PasswordGrantRequest passwordGrantRequest = new OAuth2PasswordGrantRequest(clientRegistration, username, password);
return Mono.just(passwordGrantRequest).flatMap(this.accessTokenResponseClient::getTokenResponse).onErrorMap(OAuth2AuthorizationException.class, (e) -> new ClientAuthorizationException(e.getError(), clientRegistration.getRegistrationId(), e)).map((tokenResponse) -> new OAuth2AuthorizedClient(clientRegistration, context.getPrincipal().getName(), tokenResponse.getAccessToken(), tokenResponse.getRefreshToken()));
}
use of org.springframework.security.oauth2.client.registration.ClientRegistration in project spring-security by spring-projects.
the class ServerOAuth2AuthorizedClientExchangeFilterFunctionITests method requestWhenAuthorizedButExpiredThenRefreshAndSendRequest.
@Test
public void requestWhenAuthorizedButExpiredThenRefreshAndSendRequest() {
// @formatter:off
String accessTokenResponse = "{\n" + " \"access_token\": \"refreshed-access-token\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": \"3600\"\n" + "}\n";
String clientResponse = "{\n" + " \"attribute1\": \"value1\",\n" + " \"attribute2\": \"value2\"\n" + "}\n";
// @formatter:on
this.server.enqueue(jsonResponse(accessTokenResponse));
this.server.enqueue(jsonResponse(clientResponse));
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().tokenUri(this.serverUrl).build();
given(this.clientRegistrationRepository.findByRegistrationId(eq(clientRegistration.getRegistrationId()))).willReturn(Mono.just(clientRegistration));
Instant issuedAt = Instant.now().minus(Duration.ofDays(1));
Instant expiresAt = issuedAt.plus(Duration.ofHours(1));
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "expired-access-token", issuedAt, expiresAt, new HashSet<>(Arrays.asList("read", "write")));
OAuth2RefreshToken refreshToken = TestOAuth2RefreshTokens.refreshToken();
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(clientRegistration, this.authentication.getName(), accessToken, refreshToken);
doReturn(Mono.just(authorizedClient)).when(this.authorizedClientRepository).loadAuthorizedClient(eq(clientRegistration.getRegistrationId()), eq(this.authentication), eq(this.exchange));
this.webClient.get().uri(this.serverUrl).attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(clientRegistration.getRegistrationId())).retrieve().bodyToMono(String.class).subscriberContext(Context.of(ServerWebExchange.class, this.exchange)).subscriberContext(ReactiveSecurityContextHolder.withAuthentication(this.authentication)).block();
assertThat(this.server.getRequestCount()).isEqualTo(2);
ArgumentCaptor<OAuth2AuthorizedClient> authorizedClientCaptor = ArgumentCaptor.forClass(OAuth2AuthorizedClient.class);
verify(this.authorizedClientRepository).saveAuthorizedClient(authorizedClientCaptor.capture(), eq(this.authentication), eq(this.exchange));
OAuth2AuthorizedClient refreshedAuthorizedClient = authorizedClientCaptor.getValue();
assertThat(refreshedAuthorizedClient.getClientRegistration()).isSameAs(clientRegistration);
assertThat(refreshedAuthorizedClient.getAccessToken().getTokenValue()).isEqualTo("refreshed-access-token");
}
use of org.springframework.security.oauth2.client.registration.ClientRegistration in project spring-security by spring-projects.
the class ServerOAuth2AuthorizedClientExchangeFilterFunctionITests method requestMultipleWhenNoneAuthorizedThenAuthorizeAndSendRequest.
@Test
public void requestMultipleWhenNoneAuthorizedThenAuthorizeAndSendRequest() {
// @formatter:off
String accessTokenResponse = "{\n" + " \"access_token\": \"access-token-1234\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": \"3600\",\n" + " \"scope\": \"read write\"\n" + "}\n";
String clientResponse = "{\n" + " \"attribute1\": \"value1\",\n" + " \"attribute2\": \"value2\"\n" + "}\n";
// @formatter:on
// Client 1
this.server.enqueue(jsonResponse(accessTokenResponse));
this.server.enqueue(jsonResponse(clientResponse));
ClientRegistration clientRegistration1 = TestClientRegistrations.clientCredentials().registrationId("client-1").tokenUri(this.serverUrl).build();
given(this.clientRegistrationRepository.findByRegistrationId(eq(clientRegistration1.getRegistrationId()))).willReturn(Mono.just(clientRegistration1));
// Client 2
this.server.enqueue(jsonResponse(accessTokenResponse));
this.server.enqueue(jsonResponse(clientResponse));
ClientRegistration clientRegistration2 = TestClientRegistrations.clientCredentials().registrationId("client-2").tokenUri(this.serverUrl).build();
given(this.clientRegistrationRepository.findByRegistrationId(eq(clientRegistration2.getRegistrationId()))).willReturn(Mono.just(clientRegistration2));
// @formatter:off
this.webClient.get().uri(this.serverUrl).attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(clientRegistration1.getRegistrationId())).retrieve().bodyToMono(String.class).flatMap((response) -> this.webClient.get().uri(this.serverUrl).attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(clientRegistration2.getRegistrationId())).retrieve().bodyToMono(String.class)).subscriberContext(Context.of(ServerWebExchange.class, this.exchange)).subscriberContext(ReactiveSecurityContextHolder.withAuthentication(this.authentication)).block();
// @formatter:on
assertThat(this.server.getRequestCount()).isEqualTo(4);
ArgumentCaptor<OAuth2AuthorizedClient> authorizedClientCaptor = ArgumentCaptor.forClass(OAuth2AuthorizedClient.class);
verify(this.authorizedClientRepository, times(2)).saveAuthorizedClient(authorizedClientCaptor.capture(), eq(this.authentication), eq(this.exchange));
assertThat(authorizedClientCaptor.getAllValues().get(0).getClientRegistration()).isSameAs(clientRegistration1);
assertThat(authorizedClientCaptor.getAllValues().get(1).getClientRegistration()).isSameAs(clientRegistration2);
}
use of org.springframework.security.oauth2.client.registration.ClientRegistration in project spring-security by spring-projects.
the class ServerOAuth2AuthorizedClientExchangeFilterFunctionITests method requestWhenNotAuthorizedThenAuthorizeAndSendRequest.
@Test
public void requestWhenNotAuthorizedThenAuthorizeAndSendRequest() {
// @formatter:off
String accessTokenResponse = "{\n" + " \"access_token\": \"access-token-1234\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": \"3600\",\n" + " \"scope\": \"read write\"\n" + "}\n";
String clientResponse = "{\n" + " \"attribute1\": \"value1\",\n" + " \"attribute2\": \"value2\"\n" + "}\n";
// @formatter:on
this.server.enqueue(jsonResponse(accessTokenResponse));
this.server.enqueue(jsonResponse(clientResponse));
ClientRegistration clientRegistration = TestClientRegistrations.clientCredentials().tokenUri(this.serverUrl).build();
given(this.clientRegistrationRepository.findByRegistrationId(eq(clientRegistration.getRegistrationId()))).willReturn(Mono.just(clientRegistration));
// @formatter:off
this.webClient.get().uri(this.serverUrl).attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(clientRegistration.getRegistrationId())).retrieve().bodyToMono(String.class).subscriberContext(Context.of(ServerWebExchange.class, this.exchange)).subscriberContext(ReactiveSecurityContextHolder.withAuthentication(this.authentication)).block();
// @formatter:on
assertThat(this.server.getRequestCount()).isEqualTo(2);
ArgumentCaptor<OAuth2AuthorizedClient> authorizedClientCaptor = ArgumentCaptor.forClass(OAuth2AuthorizedClient.class);
verify(this.authorizedClientRepository).saveAuthorizedClient(authorizedClientCaptor.capture(), eq(this.authentication), eq(this.exchange));
assertThat(authorizedClientCaptor.getValue().getClientRegistration()).isSameAs(clientRegistration);
}
use of org.springframework.security.oauth2.client.registration.ClientRegistration in project spring-security by spring-projects.
the class ServletOAuth2AuthorizedClientExchangeFilterFunctionITests method requestWhenAuthorizedButExpiredThenRefreshAndSendRequest.
@Test
public void requestWhenAuthorizedButExpiredThenRefreshAndSendRequest() {
// @formatter:off
String accessTokenResponse = "{\n" + " \"access_token\": \"refreshed-access-token\",\n" + " \"token_type\": \"bearer\",\n" + " \"expires_in\": \"3600\"\n" + "}\n";
String clientResponse = "{\n" + " \"attribute1\": \"value1\",\n" + " \"attribute2\": \"value2\"\n" + "}\n";
// @formatter:on
this.server.enqueue(jsonResponse(accessTokenResponse));
this.server.enqueue(jsonResponse(clientResponse));
ClientRegistration clientRegistration = TestClientRegistrations.clientRegistration().tokenUri(this.serverUrl).build();
given(this.clientRegistrationRepository.findByRegistrationId(eq(clientRegistration.getRegistrationId()))).willReturn(clientRegistration);
Instant issuedAt = Instant.now().minus(Duration.ofDays(1));
Instant expiresAt = issuedAt.plus(Duration.ofHours(1));
OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, "expired-access-token", issuedAt, expiresAt, new HashSet<>(Arrays.asList("read", "write")));
OAuth2RefreshToken refreshToken = TestOAuth2RefreshTokens.refreshToken();
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(clientRegistration, this.authentication.getName(), accessToken, refreshToken);
doReturn(authorizedClient).when(this.authorizedClientRepository).loadAuthorizedClient(eq(clientRegistration.getRegistrationId()), eq(this.authentication), eq(this.request));
this.webClient.get().uri(this.serverUrl).attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(clientRegistration.getRegistrationId())).retrieve().bodyToMono(String.class).block();
assertThat(this.server.getRequestCount()).isEqualTo(2);
ArgumentCaptor<OAuth2AuthorizedClient> authorizedClientCaptor = ArgumentCaptor.forClass(OAuth2AuthorizedClient.class);
verify(this.authorizedClientRepository).saveAuthorizedClient(authorizedClientCaptor.capture(), eq(this.authentication), eq(this.request), eq(this.response));
OAuth2AuthorizedClient refreshedAuthorizedClient = authorizedClientCaptor.getValue();
assertThat(refreshedAuthorizedClient.getClientRegistration()).isSameAs(clientRegistration);
assertThat(refreshedAuthorizedClient.getAccessToken().getTokenValue()).isEqualTo("refreshed-access-token");
}
Aggregations