Skip to content

Commit 7d83dda

Browse files
author
Steve Riesenberg
committed
Support grant types other than authorization_code
Closes spring-projectsgh-9795
1 parent 9ad018f commit 7d83dda

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/registration/ClientRegistrations.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Map;
2424
import java.util.function.Supplier;
2525

26+
import com.nimbusds.oauth2.sdk.GrantType;
2627
import com.nimbusds.oauth2.sdk.ParseException;
2728
import com.nimbusds.oauth2.sdk.as.AuthorizationServerMetadata;
2829
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
@@ -239,23 +240,51 @@ private static ClientRegistration.Builder withProviderConfiguration(Authorizatio
239240
() -> "The Issuer \"" + metadataIssuer + "\" provided in the configuration metadata did "
240241
+ "not match the requested issuer \"" + issuer + "\"");
241242
String name = URI.create(issuer).getHost();
243+
AuthorizationGrantType grantType = getAuthorizationGrantType(metadata.getGrantTypes());
242244
ClientAuthenticationMethod method = getClientAuthenticationMethod(issuer,
243245
metadata.getTokenEndpointAuthMethods());
244246
Map<String, Object> configurationMetadata = new LinkedHashMap<>(metadata.toJSONObject());
245247
// @formatter:off
246248
return ClientRegistration.withRegistrationId(name)
247249
.userNameAttributeName(IdTokenClaimNames.SUB)
248-
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
250+
.authorizationGrantType(grantType)
249251
.clientAuthenticationMethod(method)
250252
.redirectUri("{baseUrl}/{action}/oauth2/code/{registrationId}")
251-
.authorizationUri(metadata.getAuthorizationEndpointURI().toASCIIString())
253+
.authorizationUri((metadata.getAuthorizationEndpointURI() != null) ? metadata
254+
.getAuthorizationEndpointURI().toASCIIString() : null)
252255
.providerConfigurationMetadata(configurationMetadata)
253256
.tokenUri(metadata.getTokenEndpointURI().toASCIIString())
254257
.issuerUri(issuer)
255258
.clientName(issuer);
256259
// @formatter:on
257260
}
258261

262+
private static AuthorizationGrantType getAuthorizationGrantType(List<GrantType> metadataGrantTypes) {
263+
if (metadataGrantTypes == null || metadataGrantTypes.size() > 1) {
264+
return AuthorizationGrantType.AUTHORIZATION_CODE;
265+
}
266+
GrantType grantType = metadataGrantTypes.get(0);
267+
if (GrantType.AUTHORIZATION_CODE.equals(grantType)) {
268+
return AuthorizationGrantType.AUTHORIZATION_CODE;
269+
}
270+
else if (GrantType.IMPLICIT.equals(grantType)) {
271+
return AuthorizationGrantType.IMPLICIT;
272+
}
273+
else if (GrantType.REFRESH_TOKEN.equals(grantType)) {
274+
return AuthorizationGrantType.REFRESH_TOKEN;
275+
}
276+
else if (GrantType.CLIENT_CREDENTIALS.equals(grantType)) {
277+
return AuthorizationGrantType.CLIENT_CREDENTIALS;
278+
}
279+
else if (GrantType.PASSWORD.equals(grantType)) {
280+
return AuthorizationGrantType.PASSWORD;
281+
}
282+
else if (GrantType.JWT_BEARER.equals(grantType)) {
283+
return AuthorizationGrantType.JWT_BEARER;
284+
}
285+
return new AuthorizationGrantType(grantType.getValue());
286+
}
287+
259288
private static ClientAuthenticationMethod getClientAuthenticationMethod(String issuer,
260289
List<com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod> metadataAuthMethods) {
261290
if (metadataAuthMethods == null || metadataAuthMethods

oauth2/oauth2-client/src/test/java/org/springframework/security/oauth2/client/registration/ClientRegistrationsTests.java

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,22 +240,72 @@ public void issuerWhenOAuth2GrantTypesSupportedNullThenDefaulted() throws Except
240240
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
241241
}
242242

243+
// gh-9795
244+
@Test
245+
public void issuerWhenMultipleGrantTypesThenDefaulted() throws Exception {
246+
this.response.put("grant_types_supported", Arrays.asList("client_credentials", "password"));
247+
ClientRegistration registration = registration("").build();
248+
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
249+
}
250+
243251
// gh-9828
244252
@Test
245253
public void issuerWhenImplicitGrantTypeThenSuccess() throws Exception {
246254
this.response.put("grant_types_supported", Arrays.asList("implicit"));
247255
ClientRegistration registration = registration("").build();
248-
// The authorization_code grant type is still the default
249-
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
256+
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.IMPLICIT);
257+
}
258+
259+
// gh-9795
260+
@Test
261+
public void issuerWhenRefreshTokenGrantTypeThenSuccess() throws Exception {
262+
this.response.put("grant_types_supported", Arrays.asList("refresh_token"));
263+
ClientRegistration registration = registration("").build();
264+
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
265+
}
266+
267+
// gh-9795
268+
@Test
269+
public void issuerWhenClientCredentialsGrantTypeThenSuccess() throws Exception {
270+
this.response.put("grant_types_supported", Arrays.asList("client_credentials"));
271+
ClientRegistration registration = registration("").build();
272+
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
273+
}
274+
275+
// gh-9795
276+
@Test
277+
public void issuerWhenPasswordGrantTypeThenSuccess() throws Exception {
278+
this.response.put("grant_types_supported", Arrays.asList("password"));
279+
ClientRegistration registration = registration("").build();
280+
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.PASSWORD);
250281
}
251282

252283
// gh-9828
253284
@Test
254285
public void issuerWhenOAuth2JwtBearerGrantTypeThenSuccess() throws Exception {
255286
this.response.put("grant_types_supported", Arrays.asList("urn:ietf:params:oauth:grant-type:jwt-bearer"));
256287
ClientRegistration registration = registrationOAuth2("", null).build();
257-
// The authorization_code grant type is still the default
258-
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
288+
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.JWT_BEARER);
289+
}
290+
291+
// gh-9795
292+
@Test
293+
public void issuerWhenSaml2BearerGrantTypeThenSuccess() throws Exception {
294+
this.response.put("grant_types_supported", Arrays.asList("urn:ietf:params:oauth:grant-type:saml2-bearer"));
295+
ClientRegistration registration = registration("").build();
296+
assertThat(registration.getAuthorizationGrantType().getValue())
297+
.isEqualTo("urn:ietf:params:oauth:grant-type:saml2-bearer");
298+
}
299+
300+
// gh-9795
301+
@Test
302+
public void issuerWhenResponseAuthorizationEndpointIsNullThenSuccess() throws Exception {
303+
this.response.put("grant_types_supported", Arrays.asList("urn:ietf:params:oauth:grant-type:jwt-bearer"));
304+
this.response.remove("authorization_endpoint");
305+
ClientRegistration registration = registration("").build();
306+
assertThat(registration.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.JWT_BEARER);
307+
ClientRegistration.ProviderDetails provider = registration.getProviderDetails();
308+
assertThat(provider.getAuthorizationUri()).isNull();
259309
}
260310

261311
@Test

0 commit comments

Comments
 (0)