Skip to content

Commit

Permalink
[ELY-2574] Add the ability to configure additional scope for authenti…
Browse files Browse the repository at this point in the history
…cation request
  • Loading branch information
PrarthonaPaul committed Jul 14, 2023
1 parent 3ee9bb6 commit 297ac11
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
Expand Up @@ -169,7 +169,7 @@ protected String getRedirectUri(String state) {
for (String paramName : forwardableQueryParams) {
String paramValue = getQueryParamValue(facade, paramName);
if (SCOPE.equals(paramName)) {
paramValue = removeInvalidScopeValue(addOidcScopeIfNeeded(deployment.getScope()));
paramValue = addOidcScopeIfNeeded(deployment.getScope());
}
if (paramValue != null && !paramValue.isEmpty()) {
forwardedQueryParams.add(new BasicNameValuePair(paramName, paramValue));
Expand Down Expand Up @@ -405,13 +405,6 @@ private static String addOidcScopeIfNeeded(String scope) {
}
}

private static String removeInvalidScopeValue(String scope){
List<String> requestedScopeValues = new ArrayList<>(Arrays.asList(scope.split(" ")));
List<String> validScopeValues = new ArrayList<>(Arrays.asList("profile", "email", "phone", "address", "offline_access", OIDC_SCOPE));
requestedScopeValues.removeIf(value -> !validScopeValues.contains(value));
return String.join(" ", requestedScopeValues);
}

private static boolean hasScope(String scopeParam, String targetScope) {
if (scopeParam == null || targetScope == null) {
return false;
Expand Down
Expand Up @@ -30,8 +30,10 @@
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.gargoylesoftware.htmlunit.WebClient;
import org.apache.http.HttpStatus;
import org.junit.AfterClass;
import org.junit.BeforeClass;
Expand All @@ -45,6 +47,7 @@
import io.restassured.RestAssured;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.QueueDispatcher;
import org.wildfly.security.http.HttpServerCookie;

/**
* Tests for the OpenID Connect authentication mechanism.
Expand Down Expand Up @@ -165,12 +168,10 @@ public void testTokenSignatureAlgorithm() throws Exception {
performAuthentication(getOidcConfigurationInputStreamWithTokenSignatureAlgorithm(), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT);
}

@Test
public void testInvalidScope() throws Exception {
performAuthentication(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, "INVALID_SCOPE"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT);
checkScopeValuesInHTTPServerResponse(OIDC_SCOPE);
checkInvalidScopeError(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, "INVALID_SCOPE"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), "error=invalid_scope", OIDC_SCOPE + "+INVALID_SCOPE");
}

@Test
Expand Down Expand Up @@ -241,6 +242,42 @@ private void checkScopeValuesInHTTPServerResponse(String expectedScope) throws H
assert(response.getFirstResponseHeaderValue("Location").contains("scope=" + expectedScope));
}

private void checkInvalidScopeError(InputStream oidcConfig, String username, String password, boolean loginToKeycloak,
int expectedDispatcherStatusCode, String expectedLocation, String clientPageText, String expectedScope) throws Exception {
try {
Map<String, Object> props = new HashMap<>();
OidcClientConfiguration oidcClientConfiguration = OidcClientConfigurationBuilder.build(oidcConfig);
assertEquals(OidcClientConfiguration.RelativeUrlsUsed.NEVER, oidcClientConfiguration.getRelativeUrls());

OidcClientContext oidcClientContext = new OidcClientContext(oidcClientConfiguration);
oidcFactory = new OidcMechanismFactory(oidcClientContext);
HttpServerAuthenticationMechanism mechanism = oidcFactory.createAuthenticationMechanism(OIDC_NAME, props, getCallbackHandler());

URI requestUri = new URI(getClientUrl());
TestingHttpServerRequest request = new TestingHttpServerRequest(null, requestUri);
mechanism.evaluateRequest(request);
TestingHttpServerResponse response = request.getResponse();
assert(response.getFirstResponseHeaderValue("Location").contains("scope=" + expectedScope));
assertEquals(loginToKeycloak ? HttpStatus.SC_MOVED_TEMPORARILY : HttpStatus.SC_FORBIDDEN, response.getStatusCode());
assertEquals(Status.NO_AUTH, request.getResult());

if (loginToKeycloak) {
client.setDispatcher(createAppResponse(mechanism, expectedDispatcherStatusCode, expectedLocation, clientPageText));
WebClient webClient = getWebClient();
List<HttpServerCookie> cookies = response.getCookies();
if (cookies != null) {
for (HttpServerCookie cookie : cookies) {
webClient.addCookie(getCookieString(cookie), requestUri.toURL(), null);
}
}
TextPage keycloakLoginPage = webClient.getPage(response.getLocation());
assertTrue(keycloakLoginPage.getWebResponse().getWebRequest().toString().contains("error_description=Invalid+scopes"));
}
} finally {
client.setDispatcher(new QueueDispatcher());
}
}

private InputStream getOidcConfigurationInputStream(String clientSecret, String authServerUrl) {
String oidcConfig = "{\n" +
" \"realm\" : \"" + TEST_REALM + "\",\n" +
Expand Down

0 comments on commit 297ac11

Please sign in to comment.