Skip to content

Commit

Permalink
Added test cases for different scope values and a function to remove …
Browse files Browse the repository at this point in the history
…invalid scope values. Waiting for keyCloak team to respond about invalid scope values to determine if we can hardcode valid scope values
  • Loading branch information
PrarthonaPaul committed Jul 6, 2023
1 parent 9a97235 commit 3ee9bb6
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 5 deletions.
Expand Up @@ -70,7 +70,7 @@ public void init(OidcClientConfiguration oidcClientConfiguration, Object credent
throw log.invalidJwtClientCredentialsUsingSecretConfig(oidcClientConfiguration.getResourceName());
}

Map<String, Object> cfg = (Map<String, Object>) credentialsConfig;
Map<String, Object> cfg = (Map<String, Object>)credentialsConfig;
String clientSecretString = (String) cfg.get("secret");
if (clientSecretString == null) {
throw log.missingParameterInJwtClientCredentialsConfig("secret", oidcClientConfiguration.getResourceName());
Expand Down
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 = addOidcScopeIfNeeded(paramValue);
paramValue = removeInvalidScopeValue(addOidcScopeIfNeeded(deployment.getScope()));
}
if (paramValue != null && !paramValue.isEmpty()) {
forwardedQueryParams.add(new BasicNameValuePair(paramName, paramValue));
Expand Down Expand Up @@ -405,6 +405,13 @@ 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 @@ -181,13 +181,15 @@ protected HtmlInput loginToKeycloak(String username, String password, URI reques
webClient.addCookie(getCookieString(cookie), requestUri.toURL(), null);
}
}

HtmlPage keycloakLoginPage = webClient.getPage(location);
HtmlForm loginForm = keycloakLoginPage.getForms().get(0);
loginForm.getInputByName(KEYCLOAK_USERNAME).setValueAttribute(username);
loginForm.getInputByName(KEYCLOAK_PASSWORD).setValueAttribute(password);
return loginForm.getInputByName(KEYCLOAK_LOGIN);
}


protected String getCookieString(HttpServerCookie cookie) {
final StringBuilder header = new StringBuilder(cookie.getName());
header.append("=");
Expand Down
Expand Up @@ -22,10 +22,12 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import static org.wildfly.security.http.oidc.Oidc.OIDC_NAME;
import static org.wildfly.security.http.oidc.Oidc.OIDC_SCOPE;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
Expand All @@ -34,6 +36,7 @@
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.wildfly.security.http.HttpAuthenticationException;
import org.wildfly.security.http.HttpServerAuthenticationMechanism;

import com.gargoylesoftware.htmlunit.TextPage;
Expand All @@ -55,6 +58,7 @@ public static void startTestContainers() throws Exception {
assumeTrue("Docker isn't available, OIDC tests will be skipped", isDockerAvailable());
KEYCLOAK_CONTAINER = new KeycloakContainer();
KEYCLOAK_CONTAINER.start();
Runtime.getRuntime().addShutdownHook(new Thread(KEYCLOAK_CONTAINER::stop)); //remove before push
sendRealmCreationRequest(KeycloakConfiguration.getRealmRepresentation(TEST_REALM, CLIENT_ID, CLIENT_SECRET, CLIENT_HOST_NAME, CLIENT_PORT, CLIENT_APP));
client = new MockWebServer();
client.start(CLIENT_PORT);
Expand Down Expand Up @@ -165,19 +169,29 @@ public void testTokenSignatureAlgorithm() throws Exception {
@Test
public void testInvalidScope() throws Exception {
performAuthentication(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, "INVALID_SCOPE"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_BAD_REQUEST, null, "Bad request");
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT);
checkScopeValuesInHTTPServerResponse(OIDC_SCOPE);
}

@Test
public void testEmptyScope() throws Exception {
performAuthentication(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, ""), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT);
checkScopeValuesInHTTPServerResponse(OIDC_SCOPE);
}

@Test
public void testSingleScopeValue() throws Exception {
performAuthentication(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, CLIENT_ID), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
performAuthentication(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, "profile"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT);
checkScopeValuesInHTTPServerResponse(OIDC_SCOPE + "+profile");
}

@Test
public void testMultipleScopeValue() throws Exception {
performAuthentication(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, CLIENT_ID + "offline_access"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
performAuthentication(getoidcConfigurationInputStreamWithScope(CLIENT_SECRET, "profile email phone"), KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD,
true, HttpStatus.SC_MOVED_TEMPORARILY, getClientUrl(), CLIENT_PAGE_TEXT);
checkScopeValuesInHTTPServerResponse(OIDC_SCOPE + "+profile+email+phone");
}

private void performAuthentication(InputStream oidcConfig, String username, String password, boolean loginToKeycloak,
Expand Down Expand Up @@ -217,6 +231,16 @@ private InputStream getOidcConfigurationInputStream(String clientSecret) {
return getOidcConfigurationInputStream(clientSecret, KEYCLOAK_CONTAINER.getAuthServerUrl());
}

private void checkScopeValuesInHTTPServerResponse(String expectedScope) throws HttpAuthenticationException, URISyntaxException {
Map<String, Object> props = new HashMap<>();
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));
}

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

0 comments on commit 3ee9bb6

Please sign in to comment.