Search in sources :

Example 16 with ClientRegistration

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()));
}
Also used : OAuth2AuthorizationException(org.springframework.security.oauth2.core.OAuth2AuthorizationException) OAuth2AuthorizationException(org.springframework.security.oauth2.core.OAuth2AuthorizationException) Mono(reactor.core.publisher.Mono) ReactiveOAuth2AccessTokenResponseClient(org.springframework.security.oauth2.client.endpoint.ReactiveOAuth2AccessTokenResponseClient) OAuth2PasswordGrantRequest(org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest) Instant(java.time.Instant) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) WebClientReactivePasswordTokenResponseClient(org.springframework.security.oauth2.client.endpoint.WebClientReactivePasswordTokenResponseClient) Duration(java.time.Duration) Clock(java.time.Clock) AuthorizationGrantType(org.springframework.security.oauth2.core.AuthorizationGrantType) OAuth2Token(org.springframework.security.oauth2.core.OAuth2Token) Assert(org.springframework.util.Assert) StringUtils(org.springframework.util.StringUtils) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) OAuth2PasswordGrantRequest(org.springframework.security.oauth2.client.endpoint.OAuth2PasswordGrantRequest)

Example 17 with ClientRegistration

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");
}
Also used : ServerWebExchange(org.springframework.web.server.ServerWebExchange) MockServerWebExchange(org.springframework.mock.web.server.MockServerWebExchange) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) OAuth2RefreshToken(org.springframework.security.oauth2.core.OAuth2RefreshToken) OAuth2AccessToken(org.springframework.security.oauth2.core.OAuth2AccessToken) Instant(java.time.Instant) OAuth2AuthorizedClient(org.springframework.security.oauth2.client.OAuth2AuthorizedClient) Test(org.junit.jupiter.api.Test)

Example 18 with ClientRegistration

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);
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) TestingAuthenticationToken(org.springframework.security.authentication.TestingAuthenticationToken) TestOAuth2AccessTokens(org.springframework.security.oauth2.core.TestOAuth2AccessTokens) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) WebClient(org.springframework.web.reactive.function.client.WebClient) Mockito.spy(org.mockito.Mockito.spy) ServerWebExchange(org.springframework.web.server.ServerWebExchange) HashSet(java.util.HashSet) ArgumentCaptor(org.mockito.ArgumentCaptor) ReactiveSecurityContextHolder(org.springframework.security.core.context.ReactiveSecurityContextHolder) BDDMockito.given(org.mockito.BDDMockito.given) Duration(java.time.Duration) AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository(org.springframework.security.oauth2.client.web.server.AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository) MockWebServer(okhttp3.mockwebserver.MockWebServer) Assertions.assertThatExceptionOfType(org.assertj.core.api.Assertions.assertThatExceptionOfType) OAuth2AccessToken(org.springframework.security.oauth2.core.OAuth2AccessToken) Mockito.doReturn(org.mockito.Mockito.doReturn) TestClientRegistrations(org.springframework.security.oauth2.client.registration.TestClientRegistrations) ReactiveClientRegistrationRepository(org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository) MockServerHttpRequest(org.springframework.mock.http.server.reactive.MockServerHttpRequest) HttpHeaders(org.springframework.http.HttpHeaders) Context(reactor.util.context.Context) MediaType(org.springframework.http.MediaType) Mono(reactor.core.publisher.Mono) Mockito.times(org.mockito.Mockito.times) Instant(java.time.Instant) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) OAuth2AuthorizedClient(org.springframework.security.oauth2.client.OAuth2AuthorizedClient) Mockito.verify(org.mockito.Mockito.verify) Test(org.junit.jupiter.api.Test) HttpStatus(org.springframework.http.HttpStatus) AfterEach(org.junit.jupiter.api.AfterEach) Mockito.never(org.mockito.Mockito.never) MockServerWebExchange(org.springframework.mock.web.server.MockServerWebExchange) WebClientResponseException(org.springframework.web.reactive.function.client.WebClientResponseException) MockResponse(okhttp3.mockwebserver.MockResponse) Authentication(org.springframework.security.core.Authentication) OAuth2RefreshToken(org.springframework.security.oauth2.core.OAuth2RefreshToken) InMemoryReactiveOAuth2AuthorizedClientService(org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService) TestOAuth2RefreshTokens(org.springframework.security.oauth2.core.TestOAuth2RefreshTokens) ServerOAuth2AuthorizedClientRepository(org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository) Mockito.mock(org.mockito.Mockito.mock) ServerWebExchange(org.springframework.web.server.ServerWebExchange) MockServerWebExchange(org.springframework.mock.web.server.MockServerWebExchange) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) OAuth2AuthorizedClient(org.springframework.security.oauth2.client.OAuth2AuthorizedClient) Test(org.junit.jupiter.api.Test)

Example 19 with ClientRegistration

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);
}
Also used : ServerWebExchange(org.springframework.web.server.ServerWebExchange) MockServerWebExchange(org.springframework.mock.web.server.MockServerWebExchange) ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) OAuth2AuthorizedClient(org.springframework.security.oauth2.client.OAuth2AuthorizedClient) Test(org.junit.jupiter.api.Test)

Example 20 with 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");
}
Also used : ClientRegistration(org.springframework.security.oauth2.client.registration.ClientRegistration) OAuth2RefreshToken(org.springframework.security.oauth2.core.OAuth2RefreshToken) OAuth2AccessToken(org.springframework.security.oauth2.core.OAuth2AccessToken) Instant(java.time.Instant) OAuth2AuthorizedClient(org.springframework.security.oauth2.client.OAuth2AuthorizedClient) Test(org.junit.jupiter.api.Test)

Aggregations

ClientRegistration (org.springframework.security.oauth2.client.registration.ClientRegistration)258 Test (org.junit.jupiter.api.Test)214 OAuth2AuthorizationRequest (org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest)55 OAuth2AccessTokenResponse (org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse)52 RecordedRequest (okhttp3.mockwebserver.RecordedRequest)44 HttpHeaders (org.springframework.http.HttpHeaders)42 OAuth2AccessToken (org.springframework.security.oauth2.core.OAuth2AccessToken)36 OAuth2AuthorizationException (org.springframework.security.oauth2.core.OAuth2AuthorizationException)32 Instant (java.time.Instant)28 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)27 BeforeEach (org.junit.jupiter.api.BeforeEach)27 TestClientRegistrations (org.springframework.security.oauth2.client.registration.TestClientRegistrations)27 MockResponse (okhttp3.mockwebserver.MockResponse)26 Assertions.assertThatIllegalArgumentException (org.assertj.core.api.Assertions.assertThatIllegalArgumentException)26 OAuth2AuthorizedClient (org.springframework.security.oauth2.client.OAuth2AuthorizedClient)26 MultiValueMap (org.springframework.util.MultiValueMap)26 HashMap (java.util.HashMap)25 MockHttpServletRequest (org.springframework.mock.web.MockHttpServletRequest)25 LinkedMultiValueMap (org.springframework.util.LinkedMultiValueMap)25 Assertions.assertThatExceptionOfType (org.assertj.core.api.Assertions.assertThatExceptionOfType)24