|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright 2002-2020 the original author or authors.
|
|
|
+ * Copyright 2002-2022 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.
|
|
@@ -57,7 +57,7 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
|
|
|
private ClientRegistration fineRedirectUriTemplateRegistration;
|
|
|
|
|
|
- private ClientRegistration pkceRegistration;
|
|
|
+ private ClientRegistration publicClientRegistration;
|
|
|
|
|
|
private ClientRegistration oidcRegistration;
|
|
|
|
|
@@ -73,9 +73,9 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
this.registration2 = TestClientRegistrations.clientRegistration2().build();
|
|
|
this.fineRedirectUriTemplateRegistration = fineRedirectUriTemplateClientRegistration().build();
|
|
|
// @formatter:off
|
|
|
- this.pkceRegistration = TestClientRegistrations.clientRegistration()
|
|
|
- .registrationId("pkce-client-registration-id")
|
|
|
- .clientId("pkce-client-id")
|
|
|
+ this.publicClientRegistration = TestClientRegistrations.clientRegistration()
|
|
|
+ .registrationId("public-client-registration-id")
|
|
|
+ .clientId("public-client-id")
|
|
|
.clientAuthenticationMethod(ClientAuthenticationMethod.NONE)
|
|
|
.clientSecret(null)
|
|
|
.build();
|
|
@@ -85,7 +85,7 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
.build();
|
|
|
// @formatter:on
|
|
|
this.clientRegistrationRepository = new InMemoryClientRegistrationRepository(this.registration1,
|
|
|
- this.registration2, this.fineRedirectUriTemplateRegistration, this.pkceRegistration,
|
|
|
+ this.registration2, this.fineRedirectUriTemplateRegistration, this.publicClientRegistration,
|
|
|
this.oidcRegistration);
|
|
|
this.resolver = new DefaultOAuth2AuthorizationRequestResolver(this.clientRegistrationRepository,
|
|
|
this.authorizationRequestBaseUri);
|
|
@@ -371,8 +371,8 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
}
|
|
|
|
|
|
@Test
|
|
|
- public void resolveWhenAuthorizationRequestWithValidPkceClientThenResolves() {
|
|
|
- ClientRegistration clientRegistration = this.pkceRegistration;
|
|
|
+ public void resolveWhenAuthorizationRequestWithValidPublicClientThenResolves() {
|
|
|
+ ClientRegistration clientRegistration = this.publicClientRegistration;
|
|
|
String requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
|
|
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
|
|
request.setServletPath(requestUri);
|
|
@@ -398,10 +398,84 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
assertThat((String) authorizationRequest.getAttribute(PkceParameterNames.CODE_VERIFIER))
|
|
|
.matches("^([a-zA-Z0-9\\-\\.\\_\\~]){128}$");
|
|
|
assertThat(authorizationRequest.getAuthorizationRequestUri())
|
|
|
- .matches("https://example.com/login/oauth/authorize\\?" + "response_type=code&client_id=pkce-client-id&"
|
|
|
- + "scope=read:user&state=.{15,}&"
|
|
|
- + "redirect_uri=http://localhost/login/oauth2/code/pkce-client-registration-id&"
|
|
|
- + "code_challenge_method=S256&" + "code_challenge=([a-zA-Z0-9\\-\\.\\_\\~]){43}");
|
|
|
+ .matches("https://example.com/login/oauth/authorize\\?"
|
|
|
+ + "response_type=code&client_id=public-client-id&" + "scope=read:user&state=.{15,}&"
|
|
|
+ + "redirect_uri=http://localhost/login/oauth2/code/public-client-registration-id&"
|
|
|
+ + "code_challenge=([a-zA-Z0-9\\-\\.\\_\\~]){43}&" + "code_challenge_method=S256");
|
|
|
+ }
|
|
|
+
|
|
|
+ // gh-6548
|
|
|
+ @Test
|
|
|
+ public void resolveWhenAuthorizationRequestApplyPkceToConfidentialClientsThenApplied() {
|
|
|
+ this.resolver.setAuthorizationRequestCustomizer(OAuth2AuthorizationRequestCustomizers.withPkce());
|
|
|
+
|
|
|
+ ClientRegistration clientRegistration = this.registration1;
|
|
|
+ String requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
|
|
|
+ MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
|
|
+ request.setServletPath(requestUri);
|
|
|
+ OAuth2AuthorizationRequest authorizationRequest = this.resolver.resolve(request);
|
|
|
+ assertPkceApplied(authorizationRequest, clientRegistration);
|
|
|
+
|
|
|
+ clientRegistration = this.registration2;
|
|
|
+ requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
|
|
|
+ request = new MockHttpServletRequest("GET", requestUri);
|
|
|
+ request.setServletPath(requestUri);
|
|
|
+ authorizationRequest = this.resolver.resolve(request);
|
|
|
+ assertPkceApplied(authorizationRequest, clientRegistration);
|
|
|
+ }
|
|
|
+
|
|
|
+ // gh-6548
|
|
|
+ @Test
|
|
|
+ public void resolveWhenAuthorizationRequestApplyPkceToSpecificConfidentialClientThenApplied() {
|
|
|
+ this.resolver.setAuthorizationRequestCustomizer((builder) -> {
|
|
|
+ builder.attributes((attrs) -> {
|
|
|
+ String registrationId = (String) attrs.get(OAuth2ParameterNames.REGISTRATION_ID);
|
|
|
+ if (this.registration1.getRegistrationId().equals(registrationId)) {
|
|
|
+ OAuth2AuthorizationRequestCustomizers.withPkce().accept(builder);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ ClientRegistration clientRegistration = this.registration1;
|
|
|
+ String requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
|
|
|
+ MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
|
|
+ request.setServletPath(requestUri);
|
|
|
+ OAuth2AuthorizationRequest authorizationRequest = this.resolver.resolve(request);
|
|
|
+ assertPkceApplied(authorizationRequest, clientRegistration);
|
|
|
+
|
|
|
+ clientRegistration = this.registration2;
|
|
|
+ requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
|
|
|
+ request = new MockHttpServletRequest("GET", requestUri);
|
|
|
+ request.setServletPath(requestUri);
|
|
|
+ authorizationRequest = this.resolver.resolve(request);
|
|
|
+ assertPkceNotApplied(authorizationRequest, clientRegistration);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertPkceApplied(OAuth2AuthorizationRequest authorizationRequest,
|
|
|
+ ClientRegistration clientRegistration) {
|
|
|
+ assertThat(authorizationRequest.getAdditionalParameters()).containsKey(PkceParameterNames.CODE_CHALLENGE);
|
|
|
+ assertThat(authorizationRequest.getAdditionalParameters())
|
|
|
+ .contains(entry(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256"));
|
|
|
+ assertThat(authorizationRequest.getAttributes()).containsKey(PkceParameterNames.CODE_VERIFIER);
|
|
|
+ assertThat((String) authorizationRequest.getAttribute(PkceParameterNames.CODE_VERIFIER))
|
|
|
+ .matches("^([a-zA-Z0-9\\-\\.\\_\\~]){128}$");
|
|
|
+ assertThat(authorizationRequest.getAuthorizationRequestUri())
|
|
|
+ .matches("https://example.com/login/oauth/authorize\\?" + "response_type=code&" + "client_id="
|
|
|
+ + clientRegistration.getClientId() + "&" + "scope=read:user&" + "state=.{15,}&"
|
|
|
+ + "redirect_uri=http://localhost/login/oauth2/code/" + clientRegistration.getRegistrationId()
|
|
|
+ + "&" + "code_challenge=([a-zA-Z0-9\\-\\.\\_\\~]){43}&" + "code_challenge_method=S256");
|
|
|
+ }
|
|
|
+
|
|
|
+ private void assertPkceNotApplied(OAuth2AuthorizationRequest authorizationRequest,
|
|
|
+ ClientRegistration clientRegistration) {
|
|
|
+ assertThat(authorizationRequest.getAdditionalParameters()).doesNotContainKey(PkceParameterNames.CODE_CHALLENGE);
|
|
|
+ assertThat(authorizationRequest.getAdditionalParameters())
|
|
|
+ .doesNotContainKey(PkceParameterNames.CODE_CHALLENGE_METHOD);
|
|
|
+ assertThat(authorizationRequest.getAttributes()).doesNotContainKey(PkceParameterNames.CODE_VERIFIER);
|
|
|
+ assertThat(authorizationRequest.getAuthorizationRequestUri())
|
|
|
+ .matches("https://example.com/login/oauth/authorize\\?" + "response_type=code&" + "client_id="
|
|
|
+ + clientRegistration.getClientId() + "&" + "scope=read:user&" + "state=.{15,}&"
|
|
|
+ + "redirect_uri=http://localhost/login/oauth2/code/" + clientRegistration.getRegistrationId());
|
|
|
}
|
|
|
|
|
|
@Test
|
|
@@ -444,7 +518,7 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
|
|
request.setServletPath(requestUri);
|
|
|
this.resolver.setAuthorizationRequestCustomizer(
|
|
|
- (customizer) -> customizer.additionalParameters((params) -> params.remove(OidcParameterNames.NONCE))
|
|
|
+ (builder) -> builder.additionalParameters((params) -> params.remove(OidcParameterNames.NONCE))
|
|
|
.attributes((attrs) -> attrs.remove(OidcParameterNames.NONCE)));
|
|
|
OAuth2AuthorizationRequest authorizationRequest = this.resolver.resolve(request);
|
|
|
assertThat(authorizationRequest.getAdditionalParameters()).doesNotContainKey(OidcParameterNames.NONCE);
|
|
@@ -462,11 +536,10 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
String requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
|
|
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
|
|
request.setServletPath(requestUri);
|
|
|
- this.resolver
|
|
|
- .setAuthorizationRequestCustomizer((customizer) -> customizer.authorizationRequestUri((uriBuilder) -> {
|
|
|
- uriBuilder.queryParam("param1", "value1");
|
|
|
- return uriBuilder.build();
|
|
|
- }));
|
|
|
+ this.resolver.setAuthorizationRequestCustomizer((builder) -> builder.authorizationRequestUri((uriBuilder) -> {
|
|
|
+ uriBuilder.queryParam("param1", "value1");
|
|
|
+ return uriBuilder.build();
|
|
|
+ }));
|
|
|
OAuth2AuthorizationRequest authorizationRequest = this.resolver.resolve(request);
|
|
|
assertThat(authorizationRequest.getAuthorizationRequestUri())
|
|
|
.matches("https://example.com/login/oauth/authorize\\?" + "response_type=code&client_id=client-id&"
|
|
@@ -481,7 +554,7 @@ public class DefaultOAuth2AuthorizationRequestResolverTests {
|
|
|
String requestUri = this.authorizationRequestBaseUri + "/" + clientRegistration.getRegistrationId();
|
|
|
MockHttpServletRequest request = new MockHttpServletRequest("GET", requestUri);
|
|
|
request.setServletPath(requestUri);
|
|
|
- this.resolver.setAuthorizationRequestCustomizer((customizer) -> customizer.parameters((params) -> {
|
|
|
+ this.resolver.setAuthorizationRequestCustomizer((builder) -> builder.parameters((params) -> {
|
|
|
params.put("appid", params.get("client_id"));
|
|
|
params.remove("client_id");
|
|
|
}));
|