Skip to content

Commit

Permalink
[WFLY-15485] Add tests for bearer-only authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
fjuma committed Jul 25, 2022
1 parent 699e60a commit 020771e
Show file tree
Hide file tree
Showing 8 changed files with 751 additions and 13 deletions.
Expand Up @@ -20,7 +20,9 @@

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.keycloak.representations.AccessTokenResponse;
import org.keycloak.representations.idm.ClientRepresentation;
Expand All @@ -45,6 +47,14 @@ public class KeycloakConfiguration {
public static final String ALICE_PASSWORD = "alice123+";
public static final String BOB = "bob";
public static final String BOB_PASSWORD = "bob123+";
public static final String ALLOWED_ORIGIN = "http://somehost";

public enum ClientAppType {
OIDC_CLIENT,
DIRECT_ACCESS_GRANT_OIDC_CLIENT,
BEARER_ONLY_CLIENT,
CORS_CLIENT
}

/**
* Configure RealmRepresentation as follows:
Expand All @@ -58,7 +68,7 @@ public class KeycloakConfiguration {
* </ul>
*/
public static RealmRepresentation getRealmRepresentation(final String realmName, String clientSecret,
String clientHostName, int clientPort, String... clientApps) {
String clientHostName, int clientPort, Map<String, ClientAppType> clientApps) {
return createRealm(realmName, clientSecret, clientHostName, clientPort, clientApps);
}

Expand All @@ -74,8 +84,21 @@ public static String getAdminAccessToken(String authServerUrl) {
.as(AccessTokenResponse.class).getToken();
}

public static String getAccessToken(String authServerUrl, String realmName, String username, String password, String clientId, String clientSecret) {
return RestAssured
.given()
.param("grant_type", "password")
.param("username", username)
.param("password", password)
.param("client_id", clientId)
.param("client_secret", clientSecret)
.when()
.post(authServerUrl + "/realms/" + realmName + "/protocol/openid-connect/token")
.as(AccessTokenResponse.class).getToken();
}

private static RealmRepresentation createRealm(String name, String clientSecret,
String clientHostName, int clientPort, String... clientApps) {
String clientHostName, int clientPort, Map<String, ClientAppType> clientApps) {
RealmRepresentation realm = new RealmRepresentation();

realm.setRealm(name);
Expand All @@ -94,23 +117,54 @@ private static RealmRepresentation createRealm(String name, String clientSecret,
realm.getRoles().getRealm().add(new RoleRepresentation(USER_ROLE, null, false));
realm.getRoles().getRealm().add(new RoleRepresentation(JBOSS_ADMIN_ROLE, null, false));

for (String clientApp : clientApps) {
realm.getClients().add(createWebAppClient(clientApp, clientSecret, clientHostName, clientPort, clientApp));
for (String clientApp : clientApps.keySet()) {
ClientAppType clientAppType = clientApps.get(clientApp);
switch (clientAppType) {
case DIRECT_ACCESS_GRANT_OIDC_CLIENT:
realm.getClients().add(createWebAppClient(clientApp, clientSecret, clientHostName, clientPort, clientApp, true));
break;
case BEARER_ONLY_CLIENT:
realm.getClients().add(createBearerOnlyClient(clientApp));
break;
case CORS_CLIENT:
realm.getClients().add(createWebAppClient(clientApp, clientSecret, clientHostName, clientPort, clientApp, true, ALLOWED_ORIGIN));
break;
default:
realm.getClients().add(createWebAppClient(clientApp, clientSecret, clientHostName, clientPort, clientApp, false));
}
}

realm.getUsers().add(createUser(ALICE, ALICE_PASSWORD, Arrays.asList(USER_ROLE, JBOSS_ADMIN_ROLE)));
realm.getUsers().add(createUser(BOB, BOB_PASSWORD, Arrays.asList(USER_ROLE)));
return realm;
}

private static ClientRepresentation createWebAppClient(String clientId, String clientSecret, String clientHostName, int clientPort, String clientApp) {
private static ClientRepresentation createWebAppClient(String clientId, String clientSecret, String clientHostName, int clientPort,
String clientApp, boolean directAccessGrantEnabled) {
return createWebAppClient(clientId, clientSecret, clientHostName, clientPort, clientApp, directAccessGrantEnabled, null);
}

private static ClientRepresentation createWebAppClient(String clientId, String clientSecret, String clientHostName, int clientPort,
String clientApp, boolean directAccessGrantEnabled, String allowedOrigin) {
ClientRepresentation client = new ClientRepresentation();
client.setClientId(clientId);
client.setPublicClient(false);
client.setSecret(clientSecret);
//client.setRedirectUris(Arrays.asList("*"));
client.setRedirectUris(Arrays.asList("http://" + clientHostName + ":" + clientPort + "/" + clientApp + "/*"));
client.setEnabled(true);
client.setDirectAccessGrantsEnabled(directAccessGrantEnabled);
if (allowedOrigin != null) {
client.setWebOrigins(Collections.singletonList(allowedOrigin));
}
return client;
}

private static ClientRepresentation createBearerOnlyClient(String clientId) {
ClientRepresentation client = new ClientRepresentation();
client.setClientId(clientId);
client.setBearerOnly(true);
client.setEnabled(true);
return client;
}

Expand Down

Large diffs are not rendered by default.

Expand Up @@ -25,6 +25,9 @@
import static org.jboss.as.test.integration.management.util.ModelUtil.createOpNode;
import static org.wildfly.test.integration.elytron.oidc.client.KeycloakConfiguration.getRealmRepresentation;

import java.util.HashMap;
import java.util.Map;

import org.jboss.arquillian.container.test.api.Deployer;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
Expand Down Expand Up @@ -72,7 +75,27 @@ public class OidcWithDeploymentConfigTest extends OidcBaseTest {
private static final String MISSING_EXPRESSION_APP = "MissingExpressionOidcApp";
private static final String OIDC_JSON_WITH_MISSING_EXPRESSION_FILE = "OidcWithMissingExpression.json";

private static final String[] APP_NAMES = new String[] {PROVIDER_URL_APP, AUTH_SERVER_URL_APP, WRONG_PROVIDER_URL_APP, WRONG_SECRET_APP, MISSING_EXPRESSION_APP};
private static final String BEARER_ONLY_WITH_AUTH_SERVER_URL_FILE = "BearerOnlyWithAuthServerUrl.json";

private static final String BEARER_ONLY_WITH_PROVIDER_URL_FILE = "BearerOnlyWithProviderUrl.json";
private static final String BASIC_AUTH_WITH_PROVIDER_URL_FILE = "BasicAuthWithProviderUrl.json";
private static final String CORS_WITH_PROVIDER_URL_FILE = "CorsWithProviderUrl.json";

private static Map<String, KeycloakConfiguration.ClientAppType> APP_NAMES;
static {
APP_NAMES = new HashMap<>();
APP_NAMES.put(PROVIDER_URL_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
APP_NAMES.put(AUTH_SERVER_URL_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
APP_NAMES.put(WRONG_PROVIDER_URL_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
APP_NAMES.put(WRONG_SECRET_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
APP_NAMES.put(MISSING_EXPRESSION_APP, KeycloakConfiguration.ClientAppType.OIDC_CLIENT);
APP_NAMES.put(DIRECT_ACCCESS_GRANT_ENABLED_CLIENT, KeycloakConfiguration.ClientAppType.DIRECT_ACCESS_GRANT_OIDC_CLIENT);
APP_NAMES.put(BEARER_ONLY_AUTH_SERVER_URL_APP, KeycloakConfiguration.ClientAppType.BEARER_ONLY_CLIENT);
APP_NAMES.put(BEARER_ONLY_PROVIDER_URL_APP, KeycloakConfiguration.ClientAppType.BEARER_ONLY_CLIENT);
APP_NAMES.put(BASIC_AUTH_PROVIDER_URL_APP, KeycloakConfiguration.ClientAppType.BEARER_ONLY_CLIENT);
APP_NAMES.put(CORS_PROVIDER_URL_APP, KeycloakConfiguration.ClientAppType.BEARER_ONLY_CLIENT);
APP_NAMES.put(CORS_CLIENT, KeycloakConfiguration.ClientAppType.CORS_CLIENT);
}

@ArquillianResource
protected static Deployer deployer;
Expand Down Expand Up @@ -122,6 +145,42 @@ public static WebArchive createMissingExpressionDeployment() {
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_JSON_WITH_MISSING_EXPRESSION_FILE, "oidc.json");
}

@Deployment(name = BEARER_ONLY_AUTH_SERVER_URL_APP, managed = false, testable = false)
public static WebArchive createBearerOnlyAuthServerUrlDeployment() {
return ShrinkWrap.create(WebArchive.class, BEARER_ONLY_AUTH_SERVER_URL_APP + ".war")
.addClasses(SimpleServlet.class)
.addClasses(SimpleSecuredServlet.class)
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), BEARER_ONLY_WITH_AUTH_SERVER_URL_FILE, "oidc.json");
}

@Deployment(name = BEARER_ONLY_PROVIDER_URL_APP, managed = false, testable = false)
public static WebArchive createBearerOnlyProviderUrlDeployment() {
return ShrinkWrap.create(WebArchive.class, BEARER_ONLY_PROVIDER_URL_APP + ".war")
.addClasses(SimpleServlet.class)
.addClasses(SimpleSecuredServlet.class)
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), BEARER_ONLY_WITH_PROVIDER_URL_FILE, "oidc.json");
}

@Deployment(name = BASIC_AUTH_PROVIDER_URL_APP, managed = false, testable = false)
public static WebArchive createBasicAuthProviderUrlDeployment() {
return ShrinkWrap.create(WebArchive.class, BASIC_AUTH_PROVIDER_URL_APP + ".war")
.addClasses(SimpleServlet.class)
.addClasses(SimpleSecuredServlet.class)
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), BASIC_AUTH_WITH_PROVIDER_URL_FILE, "oidc.json");
}

@Deployment(name = CORS_PROVIDER_URL_APP, managed = false, testable = false)
public static WebArchive createCorsProviderUrlDeployment() {
return ShrinkWrap.create(WebArchive.class, CORS_PROVIDER_URL_APP + ".war")
.addClasses(SimpleServlet.class)
.addClasses(SimpleSecuredServlet.class)
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), OIDC_WITHOUT_SUBSYSTEM_CONFIG_WEB_XML, "web.xml")
.addAsWebInfResource(OidcWithDeploymentConfigTest.class.getPackage(), CORS_WITH_PROVIDER_URL_FILE, "oidc.json");
}

@Test
@InSequence(1)
public void testWrongPasswordWithProviderUrl() throws Exception {
Expand All @@ -138,28 +197,46 @@ public void testSucessfulAuthenticationWithProviderUrl() throws Exception {
@Test
@InSequence(3)
public void testWrongRoleWithProviderUrl() throws Exception {
super.testWrongRoleWithProviderUrl();
}

@Test
@InSequence(4)
public void testTokenProvidedBearerOnlyNotSet() throws Exception {
super.testTokenProvidedBearerOnlyNotSet();
}

@Test
@InSequence(5)
public void testTokenNotProvidedBearerOnlyNotSet() throws Exception {
super.testTokenNotProvidedBearerOnlyNotSet();
}

@Test
@InSequence(6)
public void testBasicAuthenticationWithoutEnableBasicAuthSetAndWithoutBearerOnlySet() throws Exception {
try {
super.testWrongRoleWithProviderUrl();
super.testBasicAuthenticationWithoutEnableBasicAuthSetAndWithoutBearerOnlySet();
} finally {
deployer.undeploy(PROVIDER_URL_APP);
}
}

@Test
@InSequence(4)
@InSequence(7)
public void testWrongPasswordWithAuthServerUrl() throws Exception {
deployer.deploy(AUTH_SERVER_URL_APP);
super.testWrongPasswordWithAuthServerUrl();
}

@Test
@InSequence(5)
@InSequence(8)
public void testSucessfulAuthenticationWithAuthServerUrl() throws Exception {
super.testSucessfulAuthenticationWithAuthServerUrl();
}

@Test
@InSequence(6)
@InSequence(9)
public void testWrongRoleWithAuthServerUrl() throws Exception {
try {
super.testWrongRoleWithAuthServerUrl();
Expand Down Expand Up @@ -198,6 +275,129 @@ public void testMissingExpression() throws Exception {
}
}

@Test
@InSequence(10)
public void testSucessfulBearerOnlyAuthenticationWithAuthServerUrl() throws Exception {
deployer.deploy(BEARER_ONLY_AUTH_SERVER_URL_APP);
super.testSucessfulBearerOnlyAuthenticationWithAuthServerUrl();

}

@Test
@InSequence(11)
public void testNoTokenProvidedWithAuthServerUrl() throws Exception {
try {
super.testNoTokenProvidedWithAuthServerUrl();
} finally {
deployer.undeploy(BEARER_ONLY_AUTH_SERVER_URL_APP);
}
}

@Test
@InSequence(12)
public void testSucessfulBearerOnlyAuthenticationWithProviderUrl() throws Exception {
deployer.deploy(BEARER_ONLY_PROVIDER_URL_APP);
super.testSucessfulBearerOnlyAuthenticationWithProviderUrl();
}

@Test
@InSequence(13)
public void testWrongToken() throws Exception {
super.testWrongToken();
}

@Test
@InSequence(14)
public void testInvalidToken() throws Exception {
super.testInvalidToken();
}

@Test
@InSequence(15)
public void testNoTokenProvidedWithProviderUrl() throws Exception {
super.testNoTokenProvidedWithProviderUrl();
}

@Test
@InSequence(16)
public void testValidTokenViaQueryParameter() throws Exception {
super.testValidTokenViaQueryParameter();
}

@Test
@InSequence(17)
public void testWrongTokenViaQueryParameter() throws Exception {
super.testWrongTokenViaQueryParameter();
}

@Test
@InSequence(18)
public void testInvalidTokenViaQueryParameter() throws Exception {
super.testInvalidTokenViaQueryParameter();
}

@Test
@InSequence(19)
public void testBasicAuthenticationWithoutEnableBasicAuthSet() throws Exception {
super.testBasicAuthenticationWithoutEnableBasicAuthSet();
}

@Test
@InSequence(20)
public void testCorsRequestWithoutEnableCors() throws Exception {
try {
super.testCorsRequestWithoutEnableCors();
} finally {
deployer.undeploy(BEARER_ONLY_PROVIDER_URL_APP);
}
}

@Test
@InSequence(21)
public void testValidCredentialsBasicAuthentication() throws Exception {
deployer.deploy(BASIC_AUTH_PROVIDER_URL_APP);
super.testValidCredentialsBasicAuthentication();
}

@Test
@InSequence(22)
public void testInvalidCredentialsBasicAuthentication() throws Exception {
try {
super.testInvalidCredentialsBasicAuthentication();
} finally {
deployer.undeploy(BASIC_AUTH_PROVIDER_URL_APP);
}
}

@Test
@InSequence(23)
public void testCorsRequestWithEnableCors() throws Exception {
deployer.deploy(CORS_PROVIDER_URL_APP);
super.testCorsRequestWithEnableCors();
}

@Test
@InSequence(24)
public void testCorsRequestWithEnableCorsWithWrongToken() throws Exception {
super.testCorsRequestWithEnableCorsWithWrongToken();
}

@Test
@InSequence(25)
public void testCorsRequestWithEnableCorsWithInvalidToken() throws Exception {
super.testCorsRequestWithEnableCorsWithInvalidToken();
}

@Test
@InSequence(26)
public void testCorsRequestWithEnableCorsWithInvalidOrigin() throws Exception {
try {
super.testCorsRequestWithEnableCorsWithInvalidOrigin();
} finally {
deployer.undeploy(CORS_PROVIDER_URL_APP);
}
}

static class KeycloakAndSystemPropertySetup extends KeycloakSetup {

@Override
Expand Down

0 comments on commit 020771e

Please sign in to comment.