Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WFLY-15485] Add tests for bearer-only authentication #15849

Merged
merged 1 commit into from Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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