@Override public OAuth2AccessTokenResponse getTokenResponse(OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest) { Assert.notNull(clientCredentialsGrantRequest, "clientCredentialsGrantRequest cannot be null"); RequestEntity<?> request = this.requestEntityConverter.convert(clientCredentialsGrantRequest); ResponseEntity<OAuth2AccessTokenResponse> response; try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); if (CollectionUtils.isEmpty(tokenResponse.getAccessToken().getScopes())) { // As per spec, in Section 5.1 Successful Access Token Response // https://tools.ietf.org/html/rfc6749#section-5.1 // If AccessTokenResponse.scope is empty, then default to the scope // originally requested by the client in the Token Request tokenResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse) .scopes(clientCredentialsGrantRequest.getClientRegistration().getScopes()) .build(); } return tokenResponse; }
@Override public OAuth2AccessTokenResponse getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) { Assert.notNull(authorizationCodeGrantRequest, "authorizationCodeGrantRequest cannot be null"); RequestEntity<?> request = this.requestEntityConverter.convert(authorizationCodeGrantRequest); ResponseEntity<OAuth2AccessTokenResponse> response; try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); if (CollectionUtils.isEmpty(tokenResponse.getAccessToken().getScopes())) { // As per spec, in Section 5.1 Successful Access Token Response // https://tools.ietf.org/html/rfc6749#section-5.1 // If AccessTokenResponse.scope is empty, then default to the scope // originally requested by the client in the Token Request tokenResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse) .scopes(authorizationCodeGrantRequest.getClientRegistration().getScopes()) .build(); } return tokenResponse; }
@Test public void authenticateWhenTokenResponseDoesNotContainIdTokenThenThrowOAuth2AuthenticationException() { this.exception.expect(OAuth2AuthenticationException.class); this.exception.expectMessage(containsString("invalid_id_token")); OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withResponse(this.accessTokenSuccessResponse()) .additionalParameters(Collections.emptyMap()) .build(); when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(accessTokenResponse); this.authenticationProvider.authenticate( new OAuth2LoginAuthenticationToken(this.clientRegistration, this.authorizationExchange)); }
@Test public void buildWhenResponseAndRefreshNullThenRefreshNull() { Instant expiresAt = Instant.now().plusSeconds(5); Set<String> scopes = new LinkedHashSet<>(Arrays.asList("scope1", "scope2")); Map<String, Object> additionalParameters = new HashMap<>(); additionalParameters.put("param1", "value1"); additionalParameters.put("param2", "value2"); OAuth2AccessTokenResponse tokenResponse = OAuth2AccessTokenResponse .withToken(TOKEN_VALUE) .tokenType(OAuth2AccessToken.TokenType.BEARER) .expiresIn(expiresAt.toEpochMilli()) .scopes(scopes) .additionalParameters(additionalParameters) .build(); OAuth2AccessTokenResponse withResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse) .build(); assertThat(withResponse.getRefreshToken()).isNull(); } }
@Override public Mono<OAuth2AccessTokenResponse> getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationGrantRequest) { return Mono.defer(() -> { ClientRegistration clientRegistration = authorizationGrantRequest.getClientRegistration(); OAuth2AuthorizationExchange authorizationExchange = authorizationGrantRequest.getAuthorizationExchange(); String tokenUri = clientRegistration.getProviderDetails().getTokenUri(); BodyInserters.FormInserter<String> body = body(authorizationExchange); return this.webClient.post() .uri(tokenUri) .accept(MediaType.APPLICATION_JSON) .headers(headers -> headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret())) .body(body) .exchange() .flatMap(response -> response.body(oauth2AccessTokenResponse())) .map(response -> { if (response.getAccessToken().getScopes().isEmpty()) { response = OAuth2AccessTokenResponse.withResponse(response) .scopes(authorizationExchange.getAuthorizationRequest().getScopes()) .build(); } return response; }); }); }
@Test public void buildWhenResponseThenAllAttributesAreSet() { Instant expiresAt = Instant.now().plusSeconds(5); Set<String> scopes = new LinkedHashSet<>(Arrays.asList("scope1", "scope2")); Map<String, Object> additionalParameters = new HashMap<>(); additionalParameters.put("param1", "value1"); additionalParameters.put("param2", "value2"); OAuth2AccessTokenResponse tokenResponse = OAuth2AccessTokenResponse .withToken(TOKEN_VALUE) .tokenType(OAuth2AccessToken.TokenType.BEARER) .expiresIn(expiresAt.toEpochMilli()) .scopes(scopes) .refreshToken(REFRESH_TOKEN_VALUE) .additionalParameters(additionalParameters) .build(); OAuth2AccessTokenResponse withResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse) .build(); assertThat(withResponse.getAccessToken().getTokenValue()).isEqualTo(tokenResponse.getAccessToken().getTokenValue()); assertThat(withResponse.getAccessToken().getTokenType()).isEqualTo(OAuth2AccessToken.TokenType.BEARER); assertThat(withResponse.getAccessToken().getIssuedAt()).isEqualTo(tokenResponse.getAccessToken().getIssuedAt()); assertThat(withResponse.getAccessToken().getExpiresAt()).isEqualTo(tokenResponse.getAccessToken().getExpiresAt()); assertThat(withResponse.getAccessToken().getScopes()).isEqualTo(tokenResponse.getAccessToken().getScopes()); assertThat(withResponse.getRefreshToken().getTokenValue()).isEqualTo(tokenResponse.getRefreshToken().getTokenValue()); assertThat(withResponse.getAdditionalParameters()).isEqualTo(tokenResponse.getAdditionalParameters()); }
.map(response -> { if (response.getAccessToken().getScopes().isEmpty()) { response = OAuth2AccessTokenResponse.withResponse(response) .scopes(authorizationGrantRequest.getClientRegistration().getScopes()) .build();
@Override public OAuth2AccessTokenResponse getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) { Assert.notNull(authorizationCodeGrantRequest, "authorizationCodeGrantRequest cannot be null"); RequestEntity<?> request = this.requestEntityConverter.convert(authorizationCodeGrantRequest); ResponseEntity<OAuth2AccessTokenResponse> response; try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); if (CollectionUtils.isEmpty(tokenResponse.getAccessToken().getScopes())) { // As per spec, in Section 5.1 Successful Access Token Response // https://tools.ietf.org/html/rfc6749#section-5.1 // If AccessTokenResponse.scope is empty, then default to the scope // originally requested by the client in the Token Request tokenResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse) .scopes(authorizationCodeGrantRequest.getClientRegistration().getScopes()) .build(); } return tokenResponse; }
@Override public OAuth2AccessTokenResponse getTokenResponse(OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest) { Assert.notNull(clientCredentialsGrantRequest, "clientCredentialsGrantRequest cannot be null"); RequestEntity<?> request = this.requestEntityConverter.convert(clientCredentialsGrantRequest); ResponseEntity<OAuth2AccessTokenResponse> response; try { response = this.restOperations.exchange(request, OAuth2AccessTokenResponse.class); } catch (RestClientException ex) { OAuth2Error oauth2Error = new OAuth2Error(INVALID_TOKEN_RESPONSE_ERROR_CODE, "An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: " + ex.getMessage(), null); throw new OAuth2AuthorizationException(oauth2Error, ex); } OAuth2AccessTokenResponse tokenResponse = response.getBody(); if (CollectionUtils.isEmpty(tokenResponse.getAccessToken().getScopes())) { // As per spec, in Section 5.1 Successful Access Token Response // https://tools.ietf.org/html/rfc6749#section-5.1 // If AccessTokenResponse.scope is empty, then default to the scope // originally requested by the client in the Token Request tokenResponse = OAuth2AccessTokenResponse.withResponse(tokenResponse) .scopes(clientCredentialsGrantRequest.getClientRegistration().getScopes()) .build(); } return tokenResponse; }
@Override public Mono<OAuth2AccessTokenResponse> getTokenResponse(OAuth2AuthorizationCodeGrantRequest authorizationGrantRequest) { return Mono.defer(() -> { ClientRegistration clientRegistration = authorizationGrantRequest.getClientRegistration(); OAuth2AuthorizationExchange authorizationExchange = authorizationGrantRequest.getAuthorizationExchange(); String tokenUri = clientRegistration.getProviderDetails().getTokenUri(); BodyInserters.FormInserter<String> body = body(authorizationExchange); return this.webClient.post() .uri(tokenUri) .accept(MediaType.APPLICATION_JSON) .headers(headers -> headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret())) .body(body) .exchange() .flatMap(response -> response.body(oauth2AccessTokenResponse())) .map(response -> { if (response.getAccessToken().getScopes().isEmpty()) { response = OAuth2AccessTokenResponse.withResponse(response) .scopes(authorizationExchange.getAuthorizationRequest().getScopes()) .build(); } return response; }); }); }
.map(response -> { if (response.getAccessToken().getScopes().isEmpty()) { response = OAuth2AccessTokenResponse.withResponse(response) .scopes(authorizationGrantRequest.getClientRegistration().getScopes()) .build();