6 changed files with 276 additions and 231 deletions
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
/* |
||||
* Copyright 2002-2018 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 |
||||
* |
||||
* http://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.oauth2.client.endpoint; |
||||
|
||||
import org.springframework.core.convert.converter.Converter; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.http.RequestEntity; |
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration; |
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; |
||||
|
||||
import java.util.Collections; |
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE; |
||||
|
||||
/** |
||||
* Utility methods used by the {@link Converter}'s that convert |
||||
* from an implementation of an {@link AbstractOAuth2AuthorizationGrantRequest} |
||||
* to a {@link RequestEntity} representation of an OAuth 2.0 Access Token Request |
||||
* for the specific Authorization Grant. |
||||
* |
||||
* @author Joe Grandja |
||||
* @since 5.1 |
||||
* @see OAuth2AuthorizationCodeGrantRequestEntityConverter |
||||
* @see OAuth2ClientCredentialsGrantRequestEntityConverter |
||||
*/ |
||||
final class OAuth2AuthorizationGrantRequestEntityUtils { |
||||
private static HttpHeaders DEFAULT_TOKEN_REQUEST_HEADERS = getDefaultTokenRequestHeaders(); |
||||
|
||||
static HttpHeaders getTokenRequestHeaders(ClientRegistration clientRegistration) { |
||||
HttpHeaders headers = new HttpHeaders(); |
||||
headers.addAll(DEFAULT_TOKEN_REQUEST_HEADERS); |
||||
if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) { |
||||
headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret()); |
||||
} |
||||
return headers; |
||||
} |
||||
|
||||
private static HttpHeaders getDefaultTokenRequestHeaders() { |
||||
HttpHeaders headers = new HttpHeaders(); |
||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8)); |
||||
final MediaType contentType = MediaType.valueOf(APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8"); |
||||
headers.setContentType(contentType); |
||||
return headers; |
||||
} |
||||
} |
||||
@ -0,0 +1,87 @@
@@ -0,0 +1,87 @@
|
||||
/* |
||||
* Copyright 2002-2018 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 |
||||
* |
||||
* http://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.oauth2.client.endpoint; |
||||
|
||||
import org.springframework.core.convert.converter.Converter; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.http.HttpMethod; |
||||
import org.springframework.http.RequestEntity; |
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration; |
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; |
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; |
||||
import org.springframework.util.CollectionUtils; |
||||
import org.springframework.util.LinkedMultiValueMap; |
||||
import org.springframework.util.MultiValueMap; |
||||
import org.springframework.util.StringUtils; |
||||
import org.springframework.web.util.UriComponentsBuilder; |
||||
|
||||
import java.net.URI; |
||||
|
||||
/** |
||||
* A {@link Converter} that converts the provided {@link OAuth2ClientCredentialsGrantRequest} |
||||
* to a {@link RequestEntity} representation of an OAuth 2.0 Access Token Request |
||||
* for the Client Credentials Grant. |
||||
* |
||||
* @author Joe Grandja |
||||
* @since 5.1 |
||||
* @see Converter |
||||
* @see OAuth2ClientCredentialsGrantRequest |
||||
* @see RequestEntity |
||||
*/ |
||||
public class OAuth2ClientCredentialsGrantRequestEntityConverter implements Converter<OAuth2ClientCredentialsGrantRequest, RequestEntity<?>> { |
||||
|
||||
/** |
||||
* Returns the {@link RequestEntity} used for the Access Token Request. |
||||
* |
||||
* @param clientCredentialsGrantRequest the client credentials grant request |
||||
* @return the {@link RequestEntity} used for the Access Token Request |
||||
*/ |
||||
@Override |
||||
public RequestEntity<?> convert(OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest) { |
||||
ClientRegistration clientRegistration = clientCredentialsGrantRequest.getClientRegistration(); |
||||
|
||||
HttpHeaders headers = OAuth2AuthorizationGrantRequestEntityUtils.getTokenRequestHeaders(clientRegistration); |
||||
MultiValueMap<String, String> formParameters = this.buildFormParameters(clientCredentialsGrantRequest); |
||||
URI uri = UriComponentsBuilder.fromUriString(clientRegistration.getProviderDetails().getTokenUri()) |
||||
.build() |
||||
.toUri(); |
||||
|
||||
return new RequestEntity<>(formParameters, headers, HttpMethod.POST, uri); |
||||
} |
||||
|
||||
/** |
||||
* Returns a {@link MultiValueMap} of the form parameters used for the Access Token Request body. |
||||
* |
||||
* @param clientCredentialsGrantRequest the client credentials grant request |
||||
* @return a {@link MultiValueMap} of the form parameters used for the Access Token Request body |
||||
*/ |
||||
private MultiValueMap<String, String> buildFormParameters(OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest) { |
||||
ClientRegistration clientRegistration = clientCredentialsGrantRequest.getClientRegistration(); |
||||
|
||||
MultiValueMap<String, String> formParameters = new LinkedMultiValueMap<>(); |
||||
formParameters.add(OAuth2ParameterNames.GRANT_TYPE, clientCredentialsGrantRequest.getGrantType().getValue()); |
||||
if (!CollectionUtils.isEmpty(clientRegistration.getScopes())) { |
||||
formParameters.add(OAuth2ParameterNames.SCOPE, |
||||
StringUtils.collectionToDelimitedString(clientRegistration.getScopes(), " ")); |
||||
} |
||||
if (ClientAuthenticationMethod.POST.equals(clientRegistration.getClientAuthenticationMethod())) { |
||||
formParameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId()); |
||||
formParameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret()); |
||||
} |
||||
|
||||
return formParameters; |
||||
} |
||||
} |
||||
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
/* |
||||
* Copyright 2002-2018 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 |
||||
* |
||||
* http://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.oauth2.client.endpoint; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.http.HttpHeaders; |
||||
import org.springframework.http.HttpMethod; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.http.RequestEntity; |
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration; |
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType; |
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; |
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; |
||||
import org.springframework.util.MultiValueMap; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE; |
||||
|
||||
/** |
||||
* Tests for {@link OAuth2ClientCredentialsGrantRequestEntityConverter}. |
||||
* |
||||
* @author Joe Grandja |
||||
*/ |
||||
public class OAuth2ClientCredentialsGrantRequestEntityConverterTests { |
||||
private OAuth2ClientCredentialsGrantRequestEntityConverter converter = new OAuth2ClientCredentialsGrantRequestEntityConverter(); |
||||
private OAuth2ClientCredentialsGrantRequest clientCredentialsGrantRequest; |
||||
|
||||
@Before |
||||
public void setup() { |
||||
ClientRegistration clientRegistration = ClientRegistration.withRegistrationId("registration-1") |
||||
.clientId("client-1") |
||||
.clientSecret("secret") |
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.BASIC) |
||||
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) |
||||
.scope("read", "write") |
||||
.tokenUri("https://provider.com/oauth2/token") |
||||
.build(); |
||||
this.clientCredentialsGrantRequest = new OAuth2ClientCredentialsGrantRequest(clientRegistration); |
||||
} |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
@Test |
||||
public void convertWhenGrantRequestValidThenConverts() { |
||||
RequestEntity<?> requestEntity = this.converter.convert(this.clientCredentialsGrantRequest); |
||||
|
||||
ClientRegistration clientRegistration = this.clientCredentialsGrantRequest.getClientRegistration(); |
||||
|
||||
assertThat(requestEntity.getMethod()).isEqualTo(HttpMethod.POST); |
||||
assertThat(requestEntity.getUrl().toASCIIString()).isEqualTo( |
||||
clientRegistration.getProviderDetails().getTokenUri()); |
||||
|
||||
HttpHeaders headers = requestEntity.getHeaders(); |
||||
assertThat(headers.getAccept()).contains(MediaType.APPLICATION_JSON_UTF8); |
||||
assertThat(headers.getContentType()).isEqualTo( |
||||
MediaType.valueOf(APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8")); |
||||
assertThat(headers.getFirst(HttpHeaders.AUTHORIZATION)).startsWith("Basic "); |
||||
|
||||
MultiValueMap<String, String> formParameters = (MultiValueMap<String, String>) requestEntity.getBody(); |
||||
assertThat(formParameters.getFirst(OAuth2ParameterNames.GRANT_TYPE)).isEqualTo( |
||||
AuthorizationGrantType.CLIENT_CREDENTIALS.getValue()); |
||||
assertThat(formParameters.getFirst(OAuth2ParameterNames.SCOPE)).isEqualTo("read write"); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue