Skip to content

Commit 1b758e7

Browse files
authored
Merge pull request wildfly#17903 from PrarthonaPaul/WFLY-19198
[WFLY-19198] Move the OIDC scope related tests back to the elytron-oidc-client testsuite: delete manualmode tests
2 parents 97a42a2 + ac97cce commit 1b758e7

File tree

17 files changed

+314
-985
lines changed

17 files changed

+314
-985
lines changed

testsuite/integration/elytron-oidc-client/src/test/java/org/wildfly/test/integration/elytron/oidc/client/KeycloakConfiguration.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
package org.wildfly.test.integration.elytron.oidc.client;
77

8+
import static org.wildfly.test.integration.elytron.oidc.client.OidcBaseTest.MULTIPLE_SCOPE_APP;
9+
import static org.wildfly.test.integration.elytron.oidc.client.OidcBaseTest.SINGLE_SCOPE_APP;
810
import java.util.ArrayList;
911
import java.util.Arrays;
1012
import java.util.Collections;
@@ -30,7 +32,7 @@
3032
*/
3133
public class KeycloakConfiguration {
3234

33-
private static final String USER_ROLE = "user";
35+
public static final String USER_ROLE = "user";
3436
public static final String JBOSS_ADMIN_ROLE = "JBossAdmin";
3537
public static final String ALICE = "alice";
3638
public static final String ALICE_PASSWORD = "alice123+";
@@ -53,6 +55,9 @@ public class KeycloakConfiguration {
5355
public static final String TENANT2_REALM = "tenant2";
5456
public static final String TENANT1_ENDPOINT = "/tenant1";
5557
public static final String TENANT2_ENDPOINT = "/tenant2";
58+
public static final String ALICE_FIRST_NAME = "Alice";
59+
public static final String ALICE_LAST_NAME = "Smith";
60+
public static final boolean ALICE_EMAIL_VERIFIED = true;
5661

5762
public enum ClientAppType {
5863
OIDC_CLIENT,
@@ -180,7 +185,7 @@ private static RealmRepresentation createRealm(String name, String clientSecret,
180185
realm.getUsers().add(createUser(CHARLOTTE, CHARLOTTE_PASSWORD, Arrays.asList(USER_ROLE, JBOSS_ADMIN_ROLE)));
181186
realm.getUsers().add(createUser(DAN, DAN_PASSWORD, Arrays.asList(USER_ROLE, JBOSS_ADMIN_ROLE)));
182187
} else {
183-
realm.getUsers().add(createUser(ALICE, ALICE_PASSWORD, Arrays.asList(USER_ROLE, JBOSS_ADMIN_ROLE)));
188+
realm.getUsers().add(createUser(ALICE, ALICE_PASSWORD, Arrays.asList(USER_ROLE, JBOSS_ADMIN_ROLE), ALICE_FIRST_NAME, ALICE_LAST_NAME, ALICE_EMAIL_VERIFIED));
184189
realm.getUsers().add(createUser(BOB, BOB_PASSWORD, Arrays.asList(USER_ROLE)));
185190
realm.getUsers().add(createUser(CHARLIE, CHARLIE_PASSWORD, Arrays.asList(USER_ROLE, JBOSS_ADMIN_ROLE)));
186191
}
@@ -205,6 +210,20 @@ private static ClientRepresentation createWebAppClient(String clientId, String c
205210
client.setRedirectUris(Arrays.asList("http://" + clientHostName + ":" + clientPort + "/" + clientApp + "/*"));
206211
}
207212
client.setEnabled(true);
213+
214+
if (clientId.equals(MULTIPLE_SCOPE_APP) || clientId.equals(SINGLE_SCOPE_APP)) {
215+
client.setOptionalClientScopes(new ArrayList<>());
216+
client.setDefaultClientScopes(new ArrayList<>());
217+
client.getDefaultClientScopes().add("web-origins");
218+
client.getDefaultClientScopes().add("acr");
219+
client.getOptionalClientScopes().add("address");
220+
client.getOptionalClientScopes().add("email");
221+
client.getOptionalClientScopes().add("profile");
222+
client.getOptionalClientScopes().add("phone");
223+
client.getDefaultClientScopes().add("roles");
224+
client.getOptionalClientScopes().add("offline_access");
225+
client.getOptionalClientScopes().add("microprofile-jwt");
226+
}
208227
client.setDirectAccessGrantsEnabled(directAccessGrantEnabled);
209228
if (allowedOrigin != null) {
210229
client.setWebOrigins(Collections.singletonList(allowedOrigin));
@@ -219,12 +238,16 @@ private static ClientRepresentation createBearerOnlyClient(String clientId) {
219238
client.setEnabled(true);
220239
return client;
221240
}
222-
223241
private static UserRepresentation createUser(String username, String password, List<String> realmRoles) {
242+
return createUser(username, password, realmRoles, username, username, false);
243+
}
244+
245+
private static UserRepresentation createUser(String username, String password, List<String> realmRoles, String firstName, String lastName, boolean emailVerified) {
224246
UserRepresentation user = new UserRepresentation();
225247
user.setUsername(username);
226-
user.setFirstName(username);
227-
user.setLastName(username);
248+
user.setFirstName(firstName);
249+
user.setLastName(lastName);
250+
user.setEmailVerified(emailVerified);
228251
user.setEnabled(true);
229252
user.setCredentials(new ArrayList<>());
230253
user.setRealmRoles(realmRoles);

testsuite/integration/elytron-oidc-client/src/test/java/org/wildfly/test/integration/elytron/oidc/client/OidcBaseTest.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55

66
package org.wildfly.test.integration.elytron.oidc.client;
77

8+
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SYSTEM_PROPERTY;
9+
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE;
810
import static org.junit.Assert.assertEquals;
911
import static org.junit.Assert.assertNotNull;
1012
import static org.junit.Assert.assertTrue;
1113
import static org.junit.Assume.assumeTrue;
14+
import static org.wildfly.security.http.oidc.Oidc.OIDC_SCOPE;
1215
import static org.wildfly.test.integration.elytron.oidc.client.KeycloakConfiguration.ALLOWED_ORIGIN;
1316

1417
import java.io.IOException;
@@ -39,11 +42,16 @@
3942
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
4043
import org.jboss.as.arquillian.api.ServerSetupTask;
4144
import org.jboss.as.arquillian.container.ManagementClient;
45+
import org.jboss.as.controller.PathAddress;
46+
import org.jboss.as.controller.operations.common.Util;
4247
import org.jboss.as.test.http.util.TestHttpClientUtils;
48+
import org.jboss.as.test.integration.management.ManagementOperations;
4349
import org.jboss.as.test.integration.security.common.servlets.SimpleSecuredServlet;
4450
import org.jboss.as.test.integration.security.common.servlets.SimpleServlet;
4551
import org.jboss.as.test.shared.TestSuiteEnvironment;
4652
import org.jboss.as.test.shared.util.AssumeTestGroupUtil;
53+
import org.jboss.as.version.Stability;
54+
import org.jboss.dmr.ModelNode;
4755
import org.jsoup.Jsoup;
4856
import org.jsoup.nodes.Document;
4957
import org.jsoup.nodes.Element;
@@ -52,6 +60,7 @@
5260
import org.keycloak.representations.idm.RealmRepresentation;
5361
import org.wildfly.common.iteration.CodePointIterator;
5462
import org.wildfly.security.jose.util.JsonSerialization;
63+
import org.wildfly.test.integration.elytron.oidc.client.subsystem.SimpleServletWithScope;
5564

5665
import io.restassured.RestAssured;
5766

@@ -88,6 +97,16 @@ public abstract class OidcBaseTest {
8897
static final String ACCESS_CONTROL_REQUEST_METHOD = "Access-Control-Request-Method";
8998
static final String ACCESS_CONTROL_REQUEST_HEADERS = "Access-Control-Request-Headers";
9099
public static final String CORS_CLIENT = "CorsClient";
100+
public static final String OPENID_SCOPE_APP = "OpenIDScopeApp";
101+
public static final String INVALID_SCOPE_APP = "InvalidScopeApp";
102+
public static final String SINGLE_SCOPE_APP = "SingleScopeApp";
103+
public static final String MULTIPLE_SCOPE_APP = "MultipleScopeApp";
104+
105+
private final Stability desiredStability;
106+
107+
public OidcBaseTest(Stability desiredStability) {
108+
this.desiredStability = desiredStability;
109+
}
91110

92111
private enum BearerAuthType {
93112
BEARER,
@@ -320,6 +339,46 @@ public void testCorsRequestWithoutEnableCors() throws Exception {
320339
SimpleServlet.RESPONSE_BODY, null, CORS_CLIENT, CLIENT_SECRET, ALLOWED_ORIGIN, false);
321340
}
322341

342+
/**
343+
* Tests that use different scope values to request access to claims values.
344+
*/
345+
346+
@Test
347+
@OperateOnDeployment(OPENID_SCOPE_APP)
348+
public void testOpenIDScope() throws Exception {
349+
String expectedScope = OIDC_SCOPE;
350+
loginToApp(KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, HttpURLConnection.HTTP_OK, SimpleServlet.RESPONSE_BODY, true,
351+
new URL("http", TestSuiteEnvironment.getHttpAddress(), TestSuiteEnvironment.getHttpPort(),
352+
"/" + OPENID_SCOPE_APP + SimpleServletWithScope.SERVLET_PATH).toURI(), expectedScope, false);
353+
}
354+
355+
@Test
356+
@OperateOnDeployment(SINGLE_SCOPE_APP)
357+
public void testSingleScope() throws Exception {
358+
String expectedScope = OIDC_SCOPE + "+profile";
359+
loginToApp(KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, HttpURLConnection.HTTP_OK, SimpleServlet.RESPONSE_BODY, true,
360+
new URL("http", TestSuiteEnvironment.getHttpAddress(), TestSuiteEnvironment.getHttpPort(),
361+
"/" + SINGLE_SCOPE_APP + SimpleServletWithScope.SERVLET_PATH).toURI(), expectedScope, false);
362+
}
363+
364+
@Test
365+
@OperateOnDeployment(MULTIPLE_SCOPE_APP)
366+
public void testMultipleScope() throws Exception {
367+
String expectedScope = OIDC_SCOPE + "+phone+profile+microprofile-jwt+email";
368+
loginToApp(KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, HttpURLConnection.HTTP_OK, SimpleServlet.RESPONSE_BODY, true,
369+
new URL("http", TestSuiteEnvironment.getHttpAddress(), TestSuiteEnvironment.getHttpPort(),
370+
"/" + MULTIPLE_SCOPE_APP + SimpleServletWithScope.SERVLET_PATH).toURI(), expectedScope, false);
371+
}
372+
373+
@Test
374+
@OperateOnDeployment(INVALID_SCOPE_APP)
375+
public void testInvalidScope() throws Exception {
376+
String expectedScope = OIDC_SCOPE + "+INVALID_SCOPE";
377+
loginToApp(KeycloakConfiguration.ALICE, KeycloakConfiguration.ALICE_PASSWORD, HttpURLConnection.HTTP_OK, SimpleServlet.RESPONSE_BODY, false,
378+
new URL("http", TestSuiteEnvironment.getHttpAddress(), TestSuiteEnvironment.getHttpPort(),
379+
"/" + INVALID_SCOPE_APP + SimpleServletWithScope.SERVLET_PATH).toURI(), expectedScope, true);
380+
}
381+
323382
public static void loginToApp(String appName, String username, String password, int expectedStatusCode, String expectedText) throws Exception {
324383
loginToApp(username, password, expectedStatusCode, expectedText, true,
325384
new URL("http", TestSuiteEnvironment.getHttpAddress(), TestSuiteEnvironment.getHttpPort(),
@@ -336,6 +395,10 @@ public static void loginToApp(String appName, String username, String password,
336395
}
337396

338397
public static void loginToApp(String username, String password, int expectedStatusCode, String expectedText, boolean loginToKeycloak, URI requestUri) throws Exception {
398+
loginToApp(username, password, expectedStatusCode, expectedText, loginToKeycloak, requestUri, null, false);
399+
}
400+
401+
public static void loginToApp(String username, String password, int expectedStatusCode, String expectedText, boolean loginToKeycloak, URI requestUri, String expectedScope, boolean checkInvalidScope) throws Exception {
339402
CookieStore store = new BasicCookieStore();
340403
HttpClient httpClient = TestHttpClientUtils.promiscuousCookieHttpClientBuilder()
341404
.setDefaultCookieStore(store)
@@ -355,7 +418,22 @@ public static void loginToApp(String username, String password, int expectedStat
355418
if (expectedText != null) {
356419
String responseString = new BasicResponseHandler().handleResponse(afterLoginClickResponse);
357420
assertTrue("Unexpected result " + responseString, responseString.contains(expectedText));
421+
if (expectedScope != null) {
422+
assertTrue(context.toString().contains("scope=" + expectedScope));
423+
if (expectedScope.contains("profile")) {
424+
assertTrue(responseString.contains("profile: " + KeycloakConfiguration.ALICE_FIRST_NAME + " " + KeycloakConfiguration.ALICE_LAST_NAME));
425+
}
426+
if (expectedScope.contains("email")) {
427+
assertTrue(responseString.contains("email: " + KeycloakConfiguration.ALICE_EMAIL_VERIFIED));
428+
}
429+
if (expectedScope.contains("microprofile-jwt")) {
430+
assertTrue(responseString.contains("microprofile-jwt: [" + KeycloakConfiguration.JBOSS_ADMIN_ROLE + ", " + KeycloakConfiguration.USER_ROLE + "]"));
431+
}
432+
}
358433
}
434+
} else if (checkInvalidScope) {
435+
assertTrue(context.toString().contains("error_description=Invalid+scopes"));
436+
assertTrue("Expected code == BAD REQUEST but got " + statusCode + " for request=" + requestUri, statusCode == HttpURLConnection.HTTP_BAD_REQUEST);
359437
} else {
360438
assertTrue("Expected code == FORBIDDEN but got " + statusCode + " for request=" + requestUri, statusCode == HttpURLConnection.HTTP_FORBIDDEN);
361439
}
@@ -653,4 +731,9 @@ public enum Type {
653731
HIDDEN, SUBMIT
654732
}
655733
}
734+
protected static <T extends OidcBaseTest> void addSystemProperty(ManagementClient client, Class<T> clazz) throws Exception {
735+
ModelNode add = Util.createAddOperation(PathAddress.pathAddress(SYSTEM_PROPERTY, OidcBaseTest.class.getName()));
736+
add.get(VALUE).set(clazz.getName());
737+
ManagementOperations.executeOperation(client.getControllerClient(), add);
738+
}
656739
}

testsuite/integration/elytron-oidc-client/src/test/java/org/wildfly/test/integration/elytron/oidc/client/deployment/OidcWithDeploymentConfigTest.java

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.jboss.as.test.integration.security.common.Utils;
2525
import org.jboss.as.test.integration.security.common.servlets.SimpleSecuredServlet;
2626
import org.jboss.as.test.integration.security.common.servlets.SimpleServlet;
27+
import org.jboss.as.version.Stability;
2728
import org.jboss.dmr.ModelNode;
2829
import org.jboss.shrinkwrap.api.ShrinkWrap;
2930
import org.jboss.shrinkwrap.api.spec.WebArchive;
@@ -33,6 +34,8 @@
3334
import org.wildfly.test.integration.elytron.oidc.client.OidcBaseTest;
3435

3536
import io.restassured.RestAssured;
37+
import org.wildfly.test.integration.elytron.oidc.client.subsystem.SimpleServletWithScope;
38+
import org.wildfly.test.stabilitylevel.StabilityServerSetupSnapshotRestoreTasks;
3639

3740
/**
3841
* Tests for the OpenID Connect authentication mechanism.
@@ -41,7 +44,7 @@
4144
*/
4245
@RunWith(Arquillian.class)
4346
@RunAsClient
44-
@ServerSetup({ OidcWithDeploymentConfigTest.KeycloakAndSystemPropertySetup.class })
47+
@ServerSetup({ OidcWithDeploymentConfigTest.PreviewStabilitySetupTask.class, OidcWithDeploymentConfigTest.KeycloakAndSystemPropertySetup.class })
4548
public class OidcWithDeploymentConfigTest extends OidcBaseTest {
4649

4750
private static final String OIDC_PROVIDER_URL = "oidc.provider.url";
@@ -63,6 +66,10 @@ public class OidcWithDeploymentConfigTest extends OidcBaseTest {
6366
private static final String BEARER_ONLY_WITH_PROVIDER_URL_FILE = "BearerOnlyWithProviderUrl.json";
6467
private static final String BASIC_AUTH_WITH_PROVIDER_URL_FILE = "BasicAuthWithProviderUrl.json";
6568
private static final String CORS_WITH_PROVIDER_URL_FILE = "CorsWithProviderUrl.json";
69+
private static final String SINGLE_SCOPE_FILE = "OidcWithSingleScope.json";
70+
private static final String MULTI_SCOPE_FILE = "OidcWithMultipleScopes.json";
71+
private static final String INVALID_SCOPE_FILE = "OidcWithInvalidScope.json";
72+
private static final String OPENID_SCOPE_FILE = "OidcWithOpenIDScope.json";
6673

6774
private static Map<String, KeycloakConfiguration.ClientAppType> APP_NAMES;
6875
static {
@@ -78,6 +85,14 @@ public class OidcWithDeploymentConfigTest extends OidcBaseTest {
7885
APP_NAMES.put(BASIC_AUTH_PROVIDER_URL_APP, KeycloakConfiguration.ClientAppType.BEARER_ONLY_CLIENT);
7986
APP_NAMES.put(CORS_PROVIDER_URL_APP, KeycloakConfiguration.ClientAppType.BEARER_ONLY_CLIENT);
8087
APP_NAMES.put(CORS_CLIENT, KeycloakConfiguration.ClientAppType.CORS_CLIENT);
88+
APP_NAMES.put(SINGLE_SCOPE_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
89+
APP_NAMES.put(MULTIPLE_SCOPE_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
90+
APP_NAMES.put(INVALID_SCOPE_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
91+
APP_NAMES.put(OPENID_SCOPE_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
92+
}
93+
94+
public OidcWithDeploymentConfigTest() {
95+
super(Stability.PREVIEW);
8196
}
8297

8398
@ArquillianResource
@@ -164,6 +179,42 @@ public static WebArchive createCorsProviderUrlDeployment() {
164179
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), CORS_WITH_PROVIDER_URL_FILE, "oidc.json");
165180
}
166181

182+
@Deployment(name = SINGLE_SCOPE_APP, managed = false, testable = false)
183+
public static WebArchive createSingleScopeDeployment() {
184+
return ShrinkWrap.create(WebArchive.class, SINGLE_SCOPE_APP + ".war")
185+
.addClasses(SimpleServlet.class)
186+
.addClasses(SimpleServletWithScope.class)
187+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
188+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), SINGLE_SCOPE_FILE, "oidc.json");
189+
}
190+
191+
@Deployment(name = MULTIPLE_SCOPE_APP, managed = false, testable = false)
192+
public static WebArchive createMultipleScopeDeployment() {
193+
return ShrinkWrap.create(WebArchive.class, MULTIPLE_SCOPE_APP + ".war")
194+
.addClasses(SimpleServlet.class)
195+
.addClasses(SimpleServletWithScope.class)
196+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
197+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), MULTI_SCOPE_FILE, "oidc.json");
198+
}
199+
200+
@Deployment(name = INVALID_SCOPE_APP, managed = false, testable = false)
201+
public static WebArchive createInvalidScopeDeployment() {
202+
return ShrinkWrap.create(WebArchive.class, INVALID_SCOPE_APP + ".war")
203+
.addClasses(SimpleServlet.class)
204+
.addClasses(SimpleServletWithScope.class)
205+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
206+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), INVALID_SCOPE_FILE, "oidc.json");
207+
}
208+
209+
@Deployment(name = OPENID_SCOPE_APP, managed = false, testable = false)
210+
public static WebArchive createOpenIdScopeDeployment() {
211+
return ShrinkWrap.create(WebArchive.class, OPENID_SCOPE_APP + ".war")
212+
.addClasses(SimpleServlet.class)
213+
.addClasses(SimpleServletWithScope.class)
214+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
215+
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OPENID_SCOPE_FILE, "oidc.json");
216+
}
217+
167218
@Test
168219
@InSequence(1)
169220
public void testWrongPasswordWithProviderUrl() throws Exception {
@@ -381,6 +432,46 @@ public void testCorsRequestWithEnableCorsWithInvalidOrigin() throws Exception {
381432
}
382433
}
383434

435+
@Test
436+
public void testOpenIDScope() throws Exception {
437+
try{
438+
deployer.deploy(OPENID_SCOPE_APP);
439+
super.testOpenIDScope();
440+
} finally {
441+
deployer.undeploy(OPENID_SCOPE_APP);
442+
}
443+
}
444+
445+
@Test
446+
public void testSingleScope() throws Exception {
447+
try {
448+
deployer.deploy(SINGLE_SCOPE_APP);
449+
super.testSingleScope();
450+
} finally {
451+
deployer.undeploy(SINGLE_SCOPE_APP);
452+
}
453+
}
454+
455+
@Test
456+
public void testMultipleScope() throws Exception {
457+
try {
458+
deployer.deploy(MULTIPLE_SCOPE_APP);
459+
super.testMultipleScope();
460+
} finally {
461+
deployer.undeploy(MULTIPLE_SCOPE_APP);
462+
}
463+
}
464+
465+
@Test
466+
public void testInvalidScope() throws Exception {
467+
try {
468+
deployer.deploy(INVALID_SCOPE_APP);
469+
super.testInvalidScope();
470+
} finally {
471+
deployer.undeploy(INVALID_SCOPE_APP);
472+
}
473+
}
474+
384475
static class KeycloakAndSystemPropertySetup extends KeycloakSetup {
385476

386477
@Override
@@ -422,4 +513,13 @@ public void tearDown(ManagementClient managementClient, String containerId) thro
422513
Utils.applyUpdate(operation, client);
423514
}
424515
}
516+
517+
public static class PreviewStabilitySetupTask extends StabilityServerSetupSnapshotRestoreTasks.Preview {
518+
@Override
519+
protected void doSetup(ManagementClient managementClient) throws Exception {
520+
// Write a system property so the model gets stored with a lower stability level.
521+
// This is to make sure we can reload back to the higher level from the snapshot
522+
OidcBaseTest.addSystemProperty(managementClient, OidcWithDeploymentConfigTest.class);
523+
}
524+
}
425525
}

0 commit comments

Comments
 (0)