|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright 2020-2024 the original author or authors.
|
|
|
+ * Copyright 2020-2025 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.
|
|
@@ -232,9 +232,6 @@ public class OAuth2AuthorizationCodeGrantTests {
|
|
|
@Autowired
|
|
|
private OAuth2AuthorizationService authorizationService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private OAuth2AuthorizationConsentService authorizationConsentService;
|
|
|
-
|
|
|
@Autowired
|
|
|
private JwtDecoder jwtDecoder;
|
|
|
|
|
@@ -692,38 +689,6 @@ public class OAuth2AuthorizationCodeGrantTests {
|
|
|
assertThat(consentPage).contains(scopeCheckbox("message.write"));
|
|
|
}
|
|
|
|
|
|
- @Test
|
|
|
- public void requestWhenRequiresConsentThenDisplaysConsentPageWithOnlyNewScope() throws Exception {
|
|
|
- this.spring.register(AuthorizationServerConfiguration.class).autowire();
|
|
|
-
|
|
|
- RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scopes((scopes) -> {
|
|
|
- scopes.clear();
|
|
|
- scopes.add("message.read");
|
|
|
- scopes.add("message.write");
|
|
|
- }).clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).build();
|
|
|
- this.registeredClientRepository.save(registeredClient);
|
|
|
-
|
|
|
- OAuth2AuthorizationConsent authorizationConsent = OAuth2AuthorizationConsent
|
|
|
- .withId(registeredClient.getId(), "user")
|
|
|
- .scope("message.write")
|
|
|
- .build();
|
|
|
-
|
|
|
- this.authorizationConsentService.save(authorizationConsent);
|
|
|
-
|
|
|
- String consentPage = this.mvc
|
|
|
- .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI)
|
|
|
- .queryParams(getAuthorizationRequestParameters(registeredClient))
|
|
|
- .with(user("user")))
|
|
|
- .andExpect(status().is2xxSuccessful())
|
|
|
- .andReturn()
|
|
|
- .getResponse()
|
|
|
- .getContentAsString();
|
|
|
-
|
|
|
- assertThat(consentPage).contains("Consent required");
|
|
|
- assertThat(consentPage).contains(scopeCheckbox("message.read"));
|
|
|
- assertThat(consentPage).contains(disabledScopeCheckbox("message.write"));
|
|
|
- }
|
|
|
-
|
|
|
@Test
|
|
|
public void requestWhenConsentRequestThenReturnAccessTokenResponse() throws Exception {
|
|
|
this.spring.register(AuthorizationServerConfiguration.class).autowire();
|
|
@@ -781,47 +746,6 @@ public class OAuth2AuthorizationCodeGrantTests {
|
|
|
.andReturn();
|
|
|
}
|
|
|
|
|
|
- @Test
|
|
|
- public void requestWhenCustomConsentPageConfiguredThenRedirectWithAllScopes() throws Exception {
|
|
|
- this.spring.register(AuthorizationServerConfigurationCustomConsentPage.class).autowire();
|
|
|
-
|
|
|
- RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scopes((scopes) -> {
|
|
|
- scopes.clear();
|
|
|
- scopes.add("message.read");
|
|
|
- scopes.add("message.write");
|
|
|
- }).clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).build();
|
|
|
- this.registeredClientRepository.save(registeredClient);
|
|
|
-
|
|
|
- OAuth2AuthorizationConsent authorizationConsent = OAuth2AuthorizationConsent
|
|
|
- .withId(registeredClient.getId(), "user")
|
|
|
- .scope("message.write")
|
|
|
- .build();
|
|
|
-
|
|
|
- this.authorizationConsentService.save(authorizationConsent);
|
|
|
-
|
|
|
- MvcResult mvcResult = this.mvc
|
|
|
- .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI)
|
|
|
- .queryParams(getAuthorizationRequestParameters(registeredClient))
|
|
|
- .with(user("user")))
|
|
|
- .andExpect(status().is3xxRedirection())
|
|
|
- .andReturn();
|
|
|
- String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
|
|
|
- assertThat(redirectedUrl).matches("http://localhost/oauth2/consent\\?scope=.+&client_id=.+&state=.+");
|
|
|
-
|
|
|
- String locationHeader = URLDecoder.decode(redirectedUrl, StandardCharsets.UTF_8);
|
|
|
- UriComponents uriComponents = UriComponentsBuilder.fromUriString(locationHeader).build();
|
|
|
- MultiValueMap<String, String> redirectQueryParams = uriComponents.getQueryParams();
|
|
|
-
|
|
|
- assertThat(uriComponents.getPath()).isEqualTo(consentPage);
|
|
|
- assertThat(redirectQueryParams.getFirst(OAuth2ParameterNames.SCOPE)).isEqualTo("message.read message.write");
|
|
|
- assertThat(redirectQueryParams.getFirst(OAuth2ParameterNames.CLIENT_ID))
|
|
|
- .isEqualTo(registeredClient.getClientId());
|
|
|
-
|
|
|
- String state = extractParameterFromRedirectUri(redirectedUrl, "state");
|
|
|
- OAuth2Authorization authorization = this.authorizationService.findByToken(state, STATE_TOKEN_TYPE);
|
|
|
- assertThat(authorization).isNotNull();
|
|
|
- }
|
|
|
-
|
|
|
@Test
|
|
|
public void requestWhenCustomConsentPageConfiguredThenRedirect() throws Exception {
|
|
|
this.spring.register(AuthorizationServerConfigurationCustomConsentPage.class).autowire();
|
|
@@ -1152,6 +1076,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
|
|
.isEqualTo(true);
|
|
|
}
|
|
|
|
|
|
+ // gh-2182
|
|
|
@Test
|
|
|
public void requestWhenPushedAuthorizationRequestAndRequiresConsentThenDisplaysConsentPage() throws Exception {
|
|
|
this.spring.register(AuthorizationServerConfigurationWithPushedAuthorizationRequests.class).autowire();
|
|
@@ -1192,54 +1117,7 @@ public class OAuth2AuthorizationCodeGrantTests {
|
|
|
assertThat(consentPage).contains(scopeCheckbox("message.write"));
|
|
|
}
|
|
|
|
|
|
- @Test
|
|
|
- public void requestWhenPushedAuthorizationRequestAndRequiresConsentThenDisplaysConsentPageWithOnlyNewScope()
|
|
|
- throws Exception {
|
|
|
- this.spring.register(AuthorizationServerConfigurationWithPushedAuthorizationRequests.class).autowire();
|
|
|
-
|
|
|
- RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scopes((scopes) -> {
|
|
|
- scopes.clear();
|
|
|
- scopes.add("message.read");
|
|
|
- scopes.add("message.write");
|
|
|
- }).clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).build();
|
|
|
- this.registeredClientRepository.save(registeredClient);
|
|
|
-
|
|
|
- OAuth2AuthorizationConsent authorizationConsent = OAuth2AuthorizationConsent
|
|
|
- .withId(registeredClient.getId(), "user")
|
|
|
- .scope("message.write")
|
|
|
- .build();
|
|
|
-
|
|
|
- this.authorizationConsentService.save(authorizationConsent);
|
|
|
-
|
|
|
- MvcResult mvcResult = this.mvc
|
|
|
- .perform(post("/oauth2/par").params(getAuthorizationRequestParameters(registeredClient))
|
|
|
- .param(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE)
|
|
|
- .param(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256")
|
|
|
- .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeader(registeredClient)))
|
|
|
- .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store")))
|
|
|
- .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache")))
|
|
|
- .andExpect(status().isCreated())
|
|
|
- .andExpect(jsonPath("$.request_uri").isNotEmpty())
|
|
|
- .andExpect(jsonPath("$.expires_in").isNotEmpty())
|
|
|
- .andReturn();
|
|
|
-
|
|
|
- String requestUri = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.request_uri");
|
|
|
-
|
|
|
- String consentPage = this.mvc
|
|
|
- .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI)
|
|
|
- .queryParam(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())
|
|
|
- .queryParam(OAuth2ParameterNames.REQUEST_URI, requestUri)
|
|
|
- .with(user("user")))
|
|
|
- .andExpect(status().is2xxSuccessful())
|
|
|
- .andReturn()
|
|
|
- .getResponse()
|
|
|
- .getContentAsString();
|
|
|
-
|
|
|
- assertThat(consentPage).contains("Consent required");
|
|
|
- assertThat(consentPage).contains(scopeCheckbox("message.read"));
|
|
|
- assertThat(consentPage).contains(disabledScopeCheckbox("message.write"));
|
|
|
- }
|
|
|
-
|
|
|
+ // gh-2182
|
|
|
@Test
|
|
|
public void requestWhenPushedAuthorizationRequestAndCustomConsentPageConfiguredThenRedirect() throws Exception {
|
|
|
this.spring.register(AuthorizationServerConfigurationWithPushedAuthorizationRequestsAndCustomConsentPage.class)
|
|
@@ -1290,64 +1168,6 @@ public class OAuth2AuthorizationCodeGrantTests {
|
|
|
assertThat(authorization).isNotNull();
|
|
|
}
|
|
|
|
|
|
- @Test
|
|
|
- public void requestWhenPushedAuthorizationRequestAndCustomConsentPageConfiguredThenRedirectWithAllScopes()
|
|
|
- throws Exception {
|
|
|
- this.spring.register(AuthorizationServerConfigurationWithPushedAuthorizationRequestsAndCustomConsentPage.class)
|
|
|
- .autowire();
|
|
|
-
|
|
|
- RegisteredClient registeredClient = TestRegisteredClients.registeredClient().scopes((scopes) -> {
|
|
|
- scopes.clear();
|
|
|
- scopes.add("message.read");
|
|
|
- scopes.add("message.write");
|
|
|
- }).clientSettings(ClientSettings.builder().requireAuthorizationConsent(true).build()).build();
|
|
|
- this.registeredClientRepository.save(registeredClient);
|
|
|
-
|
|
|
- OAuth2AuthorizationConsent authorizationConsent = OAuth2AuthorizationConsent
|
|
|
- .withId(registeredClient.getId(), "user")
|
|
|
- .scope("message.write")
|
|
|
- .build();
|
|
|
-
|
|
|
- this.authorizationConsentService.save(authorizationConsent);
|
|
|
-
|
|
|
- MvcResult mvcResult = this.mvc
|
|
|
- .perform(post("/oauth2/par").params(getAuthorizationRequestParameters(registeredClient))
|
|
|
- .param(PkceParameterNames.CODE_CHALLENGE, S256_CODE_CHALLENGE)
|
|
|
- .param(PkceParameterNames.CODE_CHALLENGE_METHOD, "S256")
|
|
|
- .header(HttpHeaders.AUTHORIZATION, getAuthorizationHeader(registeredClient)))
|
|
|
- .andExpect(header().string(HttpHeaders.CACHE_CONTROL, containsString("no-store")))
|
|
|
- .andExpect(header().string(HttpHeaders.PRAGMA, containsString("no-cache")))
|
|
|
- .andExpect(status().isCreated())
|
|
|
- .andExpect(jsonPath("$.request_uri").isNotEmpty())
|
|
|
- .andExpect(jsonPath("$.expires_in").isNotEmpty())
|
|
|
- .andReturn();
|
|
|
-
|
|
|
- String requestUri = JsonPath.read(mvcResult.getResponse().getContentAsString(), "$.request_uri");
|
|
|
-
|
|
|
- mvcResult = this.mvc
|
|
|
- .perform(get(DEFAULT_AUTHORIZATION_ENDPOINT_URI)
|
|
|
- .queryParam(OAuth2ParameterNames.CLIENT_ID, registeredClient.getClientId())
|
|
|
- .queryParam(OAuth2ParameterNames.REQUEST_URI, requestUri)
|
|
|
- .with(user("user")))
|
|
|
- .andExpect(status().is3xxRedirection())
|
|
|
- .andReturn();
|
|
|
- String redirectedUrl = mvcResult.getResponse().getRedirectedUrl();
|
|
|
- assertThat(redirectedUrl).matches("http://localhost/oauth2/consent\\?scope=.+&client_id=.+&state=.+");
|
|
|
-
|
|
|
- String locationHeader = URLDecoder.decode(redirectedUrl, StandardCharsets.UTF_8);
|
|
|
- UriComponents uriComponents = UriComponentsBuilder.fromUriString(locationHeader).build();
|
|
|
- MultiValueMap<String, String> redirectQueryParams = uriComponents.getQueryParams();
|
|
|
-
|
|
|
- assertThat(uriComponents.getPath()).isEqualTo(consentPage);
|
|
|
- assertThat(redirectQueryParams.getFirst(OAuth2ParameterNames.SCOPE)).isEqualTo("message.read message.write");
|
|
|
- assertThat(redirectQueryParams.getFirst(OAuth2ParameterNames.CLIENT_ID))
|
|
|
- .isEqualTo(registeredClient.getClientId());
|
|
|
-
|
|
|
- String state = extractParameterFromRedirectUri(redirectedUrl, "state");
|
|
|
- OAuth2Authorization authorization = this.authorizationService.findByToken(state, STATE_TOKEN_TYPE);
|
|
|
- assertThat(authorization).isNotNull();
|
|
|
- }
|
|
|
-
|
|
|
private static String generateDPoPProof(String tokenEndpointUri) {
|
|
|
// @formatter:off
|
|
|
Map<String, Object> publicJwk = TestJwks.DEFAULT_EC_JWK
|
|
@@ -1404,12 +1224,6 @@ public class OAuth2AuthorizationCodeGrantTests {
|
|
|
"<input class=\"form-check-input\" type=\"checkbox\" name=\"scope\" value=\"{0}\" id=\"{0}\">", scope);
|
|
|
}
|
|
|
|
|
|
- private static String disabledScopeCheckbox(String scope) {
|
|
|
- return MessageFormat.format(
|
|
|
- "<input class=\"form-check-input\" type=\"checkbox\" name=\"scope\" id=\"{0}\" checked disabled>",
|
|
|
- scope);
|
|
|
- }
|
|
|
-
|
|
|
private String extractParameterFromRedirectUri(String redirectUri, String param)
|
|
|
throws UnsupportedEncodingException {
|
|
|
String locationHeader = URLDecoder.decode(redirectUri, StandardCharsets.UTF_8.name());
|