Implement support for user consent #4
@ -7,17 +7,21 @@ import org.springframework.boot.testcontainers.service.connection.ServiceConnect
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||||
|
import org.springframework.security.oauth2.core.oidc.OidcScopes;
|
||||||
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
|
||||||
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
|
||||||
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
|
import org.springframework.security.oauth2.server.authorization.settings.ClientSettings;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
import org.springframework.test.web.servlet.ResultActions;
|
||||||
import org.springframework.web.util.UriComponents;
|
import org.springframework.web.util.UriComponents;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
import org.testcontainers.containers.MariaDBContainer;
|
import org.testcontainers.containers.MariaDBContainer;
|
||||||
|
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
@ -62,11 +66,45 @@ public class ConsentFlowTest extends AbstractMetadataTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void consent_page_exists() throws Exception {
|
public void consent_page_exists() throws Exception {
|
||||||
|
attemptAuthorizationWithConsentResponse("some-other-end-user")
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void consent_page_displays_information_so_end_user_can_make_informed_decision() throws Exception {
|
||||||
|
String principal = "some-other-end-user";
|
||||||
|
|
||||||
|
attemptAuthorizationWithConsentResponse(principal)
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpectAll(
|
||||||
|
content().string(containsString(TestConfig.CLIENT_NAME)),
|
||||||
|
content().string(containsString(TestConfig.CLIENT_DOMAIN)),
|
||||||
|
content().string(containsString(principal)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shows_requested_scopes() throws Exception {
|
||||||
|
attemptAuthorizationWithConsentResponseUsingScopes("some-other-end-user", Set.of("openid", "profile"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpectAll(
|
||||||
|
content().string(containsString("openid")),
|
||||||
|
content().string(containsString("profile")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultActions attemptAuthorizationWithConsentResponse(String principal) throws Exception {
|
||||||
|
Set<String> scopes = Set.of();
|
||||||
|
return attemptAuthorizationWithConsentResponseUsingScopes(principal, scopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResultActions attemptAuthorizationWithConsentResponseUsingScopes(String principal, Set<String> scopes)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
MvcResult result = mockMvc.perform(get(getAuthorizationEndpoint())
|
MvcResult result = mockMvc.perform(get(getAuthorizationEndpoint())
|
||||||
.with(remoteUser("some-other-end-user"))
|
.with(remoteUser(principal))
|
||||||
.queryParam("response_type", "code")
|
.queryParam("response_type", "code")
|
||||||
.queryParam("client_id", TestConfig.CLIENT_ID)
|
.queryParam("client_id", TestConfig.CLIENT_ID)
|
||||||
.queryParam("redirect_uri", TestConfig.REDIRECT_URI))
|
.queryParam("redirect_uri", TestConfig.REDIRECT_URI)
|
||||||
|
.queryParam("scope", String.join(" ", scopes)))
|
||||||
.andExpect(status().is3xxRedirection())
|
.andExpect(status().is3xxRedirection())
|
||||||
.andExpect(redirectedUrlPattern("**/oauth2/consent?**"))
|
.andExpect(redirectedUrlPattern("**/oauth2/consent?**"))
|
||||||
.andReturn();
|
.andReturn();
|
||||||
@ -74,9 +112,8 @@ public class ConsentFlowTest extends AbstractMetadataTest {
|
|||||||
String consentUrl = result.getResponse().getRedirectedUrl();
|
String consentUrl = result.getResponse().getRedirectedUrl();
|
||||||
assertNotNull(consentUrl, "Should have redirected to the consent page");
|
assertNotNull(consentUrl, "Should have redirected to the consent page");
|
||||||
|
|
||||||
mockMvc.perform(get(consentUrl)
|
return mockMvc.perform(get(consentUrl)
|
||||||
.with(remoteUser("some-end-user")))
|
.with(remoteUser(principal)));
|
||||||
.andExpect(status().isOk());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UriComponents parseUrl(final String url) {
|
private static UriComponents parseUrl(final String url) {
|
||||||
@ -92,7 +129,9 @@ public class ConsentFlowTest extends AbstractMetadataTest {
|
|||||||
public static class TestConfig {
|
public static class TestConfig {
|
||||||
public static final String CLIENT_ID = "client";
|
public static final String CLIENT_ID = "client";
|
||||||
public static final String CLIENT_SECRET = "secret";
|
public static final String CLIENT_SECRET = "secret";
|
||||||
public static final String REDIRECT_URI = "http://localhost/login/oauth2/code/client";
|
public static final String CLIENT_DOMAIN = "http://localhost";
|
||||||
|
public static final String REDIRECT_URI = CLIENT_DOMAIN + "/login/oauth2/code/client";
|
||||||
|
public static final String CLIENT_NAME = "My test client";
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Primary
|
@Primary
|
||||||
@ -101,9 +140,13 @@ public class ConsentFlowTest extends AbstractMetadataTest {
|
|||||||
{
|
{
|
||||||
RegisteredClient registeredClient = RegisteredClient.withId("id")
|
RegisteredClient registeredClient = RegisteredClient.withId("id")
|
||||||
.clientId(CLIENT_ID)
|
.clientId(CLIENT_ID)
|
||||||
|
.clientName(CLIENT_NAME)
|
||||||
.clientSecret("{noop}" + CLIENT_SECRET)
|
.clientSecret("{noop}" + CLIENT_SECRET)
|
||||||
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
|
||||||
.redirectUri(REDIRECT_URI)
|
.redirectUri(REDIRECT_URI)
|
||||||
|
.scope(OidcScopes.OPENID)
|
||||||
|
.scope(OidcScopes.PROFILE)
|
||||||
|
.scope(OidcScopes.EMAIL)
|
||||||
.clientSettings(ClientSettings.builder()
|
.clientSettings(ClientSettings.builder()
|
||||||
.requireAuthorizationConsent(true)
|
.requireAuthorizationConsent(true)
|
||||||
.build())
|
.build())
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user