migrate RequiredCredentials
This commit is contained in:
parent
e825be1c79
commit
e51d2137cf
18 changed files with 722 additions and 673 deletions
|
@ -0,0 +1,73 @@
|
|||
package org.keycloak.representations.idm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class RequiredActionProviderRepresentation {
|
||||
|
||||
private String alias;
|
||||
private String name;
|
||||
private String providerId;
|
||||
private boolean enabled;
|
||||
private boolean defaultAction;
|
||||
private Map<String, String> config = new HashMap<String, String>();
|
||||
|
||||
|
||||
public String getAlias() {
|
||||
return alias;
|
||||
}
|
||||
|
||||
public void setAlias(String alias) {
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for display purposes. Probably should clean this code up and make alias and name the same, but
|
||||
* the old code references an Enum and the admin console creates a "friendly" name for each enum.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isDefaultAction() {
|
||||
return defaultAction;
|
||||
}
|
||||
|
||||
public void setDefaultAction(boolean defaultAction) {
|
||||
this.defaultAction = defaultAction;
|
||||
}
|
||||
|
||||
public String getProviderId() {
|
||||
return providerId;
|
||||
}
|
||||
|
||||
public void setProviderId(String providerId) {
|
||||
this.providerId = providerId;
|
||||
}
|
||||
|
||||
public Map<String, String> getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public void setConfig(Map<String, String> config) {
|
||||
this.config = config;
|
||||
}
|
||||
}
|
|
@ -1,12 +1,16 @@
|
|||
package org.keycloak.migration.migrators;
|
||||
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.ImpersonationConstants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -20,11 +24,10 @@ public class MigrateTo1_4_0 {
|
|||
List<RealmModel> realms = session.realms().getRealms();
|
||||
for (RealmModel realm : realms) {
|
||||
if (realm.getAuthenticationFlows().size() == 0) {
|
||||
DefaultAuthenticationFlows.addFlows(realm);
|
||||
DefaultAuthenticationFlows.migrateFlows(realm);
|
||||
DefaultRequiredActions.addActions(realm);
|
||||
}
|
||||
ImpersonationConstants.setupImpersonationService(session, realm);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import org.keycloak.models.AuthenticationExecutionModel;
|
|||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -23,6 +24,13 @@ public class DefaultAuthenticationFlows {
|
|||
if (realm.getFlowByAlias(BROWSER_FLOW) == null) browserFlow(realm);
|
||||
if (realm.getFlowByAlias(REGISTRATION_FLOW) == null) registrationFlow(realm);
|
||||
}
|
||||
public static void migrateFlows(RealmModel realm) {
|
||||
browserFlow(realm, true);
|
||||
if (realm.getFlowByAlias(REGISTRATION_FLOW) == null) registrationFlow(realm);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static void registrationFlow(RealmModel realm) {
|
||||
AuthenticationFlowModel registrationFlow = new AuthenticationFlowModel();
|
||||
|
@ -102,6 +110,20 @@ public class DefaultAuthenticationFlows {
|
|||
}
|
||||
|
||||
public static void browserFlow(RealmModel realm) {
|
||||
browserFlow(realm, false);
|
||||
}
|
||||
|
||||
private static boolean hasCredentialType(RealmModel realm, String type) {
|
||||
for (RequiredCredentialModel requiredCredentialModel : realm.getRequiredCredentials()) {
|
||||
if (type.equals(requiredCredentialModel.getType())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void browserFlow(RealmModel realm, boolean migrate) {
|
||||
AuthenticationFlowModel browser = new AuthenticationFlowModel();
|
||||
browser.setAlias(BROWSER_FLOW);
|
||||
browser.setDescription("browser based authentication");
|
||||
|
@ -120,6 +142,10 @@ public class DefaultAuthenticationFlows {
|
|||
execution = new AuthenticationExecutionModel();
|
||||
execution.setParentFlow(browser.getId());
|
||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED);
|
||||
if (migrate && hasCredentialType(realm, RequiredCredentialModel.KERBEROS.getType())) {
|
||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
|
||||
|
||||
}
|
||||
execution.setAuthenticator("auth-spnego");
|
||||
execution.setPriority(20);
|
||||
execution.setUserSetupAllowed(false);
|
||||
|
@ -158,6 +184,11 @@ public class DefaultAuthenticationFlows {
|
|||
execution = new AuthenticationExecutionModel();
|
||||
execution.setParentFlow(forms.getId());
|
||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.OPTIONAL);
|
||||
if (migrate && hasCredentialType(realm, RequiredCredentialModel.TOTP.getType())) {
|
||||
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
|
||||
|
||||
}
|
||||
|
||||
execution.setAuthenticator("auth-otp-form");
|
||||
execution.setPriority(20);
|
||||
execution.setUserSetupAllowed(true);
|
||||
|
|
|
@ -350,30 +350,4 @@ public final class KeycloakModelUtils {
|
|||
return mapperModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically add "kerberos" to required realm credentials if it's supported by saved provider
|
||||
*
|
||||
* @param realm
|
||||
* @param model
|
||||
* @return true if kerberos credentials were added
|
||||
*/
|
||||
public static boolean checkKerberosCredential(RealmModel realm, UserFederationProviderModel model) {
|
||||
String allowKerberosCfg = model.getConfig().get(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION);
|
||||
if (Boolean.valueOf(allowKerberosCfg)) {
|
||||
boolean found = false;
|
||||
List<RequiredCredentialModel> currentCreds = realm.getRequiredCredentials();
|
||||
for (RequiredCredentialModel cred : currentCreds) {
|
||||
if (cred.getType().equals(UserCredentialModel.KERBEROS)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
realm.addRequiredCredential(UserCredentialModel.KERBEROS);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,12 +132,13 @@ public class RepresentationToModel {
|
|||
if (rep.getAdminTheme() != null) newRealm.setAdminTheme(rep.getAdminTheme());
|
||||
if (rep.getEmailTheme() != null) newRealm.setEmailTheme(rep.getEmailTheme());
|
||||
|
||||
// todo remove this stuff as its all deprecated
|
||||
if (rep.getRequiredCredentials() != null) {
|
||||
for (String requiredCred : rep.getRequiredCredentials()) {
|
||||
addRequiredCredential(newRealm, requiredCred);
|
||||
newRealm.addRequiredCredential(requiredCred);
|
||||
}
|
||||
} else {
|
||||
addRequiredCredential(newRealm, CredentialRepresentation.PASSWORD);
|
||||
newRealm.addRequiredCredential(CredentialRepresentation.PASSWORD);
|
||||
}
|
||||
|
||||
if (rep.getPasswordPolicy() != null) newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy()));
|
||||
|
@ -301,7 +302,7 @@ public class RepresentationToModel {
|
|||
public static void importAuthenticationFlows(RealmModel newRealm, RealmRepresentation rep) {
|
||||
if (rep.getAuthenticationFlows() == null) {
|
||||
// assume this is an old version being imported
|
||||
DefaultAuthenticationFlows.addFlows(newRealm);
|
||||
DefaultAuthenticationFlows.migrateFlows(newRealm);
|
||||
} else {
|
||||
for (AuthenticatorConfigRepresentation configRep : rep.getAuthenticatorConfig()) {
|
||||
AuthenticatorConfigModel model = toModel(configRep);
|
||||
|
@ -521,10 +522,6 @@ public class RepresentationToModel {
|
|||
|
||||
// Basic realm stuff
|
||||
|
||||
public static void addRequiredCredential(RealmModel newRealm, String requiredCred) {
|
||||
newRealm.addRequiredCredential(requiredCred);
|
||||
}
|
||||
|
||||
|
||||
private static List<UserFederationProviderModel> convertFederationProviders(List<UserFederationProviderRepresentation> providers) {
|
||||
List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();
|
||||
|
|
|
@ -22,14 +22,6 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
|
|||
protected static Logger logger = Logger.getLogger(UpdateTotp.class);
|
||||
@Override
|
||||
public void evaluateTriggers(RequiredActionContext context) {
|
||||
// I don't think we need this check here. AuthenticationProcessor should be setting the required action
|
||||
// if OTP changes from required from optional or disabled
|
||||
for (RequiredCredentialModel c : context.getRealm().getRequiredCredentials()) {
|
||||
if (c.getType().equals(CredentialRepresentation.TOTP) && !context.getUser().isTotp()) {
|
||||
context.getUser().addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
|
||||
logger.debug("User is required to configure totp");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,12 +4,8 @@ import org.jboss.logging.Logger;
|
|||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
import org.jboss.resteasy.spi.NotFoundException;
|
||||
import org.keycloak.authentication.AuthenticationFlow;
|
||||
import org.keycloak.authentication.Authenticator;
|
||||
import org.keycloak.authentication.AuthenticatorFactory;
|
||||
import org.keycloak.authentication.AuthenticatorUtil;
|
||||
import org.keycloak.authentication.ConfigurableAuthenticatorFactory;
|
||||
import org.keycloak.authentication.FormAction;
|
||||
import org.keycloak.authentication.FormActionFactory;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.AuthenticatorConfigModel;
|
||||
|
@ -18,6 +14,7 @@ import org.keycloak.models.RealmModel;
|
|||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
|
||||
import org.keycloak.utils.CredentialHelper;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
|
@ -191,7 +188,7 @@ public class AuthenticationManagementResource {
|
|||
rep.setSubFlow(true);
|
||||
}
|
||||
String providerId = execution.getAuthenticator();
|
||||
ConfigurableAuthenticatorFactory factory = getConfigurableAuthenticatorFactory(providerId);
|
||||
ConfigurableAuthenticatorFactory factory = CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
|
||||
rep.setReferenceType(factory.getDisplayType());
|
||||
rep.setConfigurable(factory.isConfigurable());
|
||||
for (AuthenticationExecutionModel.Requirement choice : factory.getRequirementChoices()) {
|
||||
|
@ -209,14 +206,6 @@ public class AuthenticationManagementResource {
|
|||
return Response.ok(result).build();
|
||||
}
|
||||
|
||||
public ConfigurableAuthenticatorFactory getConfigurableAuthenticatorFactory(String providerId) {
|
||||
ConfigurableAuthenticatorFactory factory = (AuthenticatorFactory)session.getKeycloakSessionFactory().getProviderFactory(Authenticator.class, providerId);
|
||||
if (factory == null) {
|
||||
factory = (FormActionFactory)session.getKeycloakSessionFactory().getProviderFactory(FormAction.class, providerId);
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Path("/flows/{flowAlias}/executions")
|
||||
@PUT
|
||||
@NoCache
|
||||
|
@ -439,7 +428,7 @@ public class AuthenticationManagementResource {
|
|||
@NoCache
|
||||
public AuthenticatorConfigDescription getAuthenticatorConfigDescription(@PathParam("providerId") String providerId) {
|
||||
this.auth.requireView();
|
||||
ConfigurableAuthenticatorFactory factory = getConfigurableAuthenticatorFactory(providerId);
|
||||
ConfigurableAuthenticatorFactory factory = CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
|
||||
if (factory == null) {
|
||||
throw new NotFoundException("Could not find authenticator provider");
|
||||
}
|
||||
|
|
3
services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
Normal file → Executable file
3
services/src/main/java/org/keycloak/services/resources/admin/UserFederationProviderResource.java
Normal file → Executable file
|
@ -34,7 +34,6 @@ import org.keycloak.models.RealmModel;
|
|||
import org.keycloak.models.UserFederationMapperModel;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.UserFederationSyncResult;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
|
@ -89,7 +88,7 @@ public class UserFederationProviderResource {
|
|||
rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync());
|
||||
realm.updateUserFederationProvider(model);
|
||||
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
||||
boolean kerberosCredsAdded = KeycloakModelUtils.checkKerberosCredential(realm, model);
|
||||
boolean kerberosCredsAdded = UserFederationProvidersResource.checkKerberosCredential(session, realm, model);
|
||||
if (kerberosCredsAdded) {
|
||||
logger.info("Added 'kerberos' to required realm credentials");
|
||||
}
|
||||
|
|
|
@ -4,19 +4,24 @@ import org.jboss.logging.Logger;
|
|||
import org.jboss.resteasy.annotations.cache.NoCache;
|
||||
import org.jboss.resteasy.spi.NotFoundException;
|
||||
import org.jboss.resteasy.spi.ResteasyProviderFactory;
|
||||
import org.keycloak.constants.KerberosConstants;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserFederationProvider;
|
||||
import org.keycloak.models.UserFederationProviderFactory;
|
||||
import org.keycloak.models.UserFederationProviderModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
|
||||
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||
import org.keycloak.services.managers.UsersSyncManager;
|
||||
import org.keycloak.timer.TimerProvider;
|
||||
import org.keycloak.utils.CredentialHelper;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
|
@ -61,6 +66,23 @@ public class UserFederationProvidersResource {
|
|||
auth.init(RealmAuth.Resource.USER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically add "kerberos" to required realm credentials if it's supported by saved provider
|
||||
*
|
||||
* @param realm
|
||||
* @param model
|
||||
* @return true if kerberos credentials were added
|
||||
*/
|
||||
public static boolean checkKerberosCredential(KeycloakSession session, RealmModel realm, UserFederationProviderModel model) {
|
||||
String allowKerberosCfg = model.getConfig().get(KerberosConstants.ALLOW_KERBEROS_AUTHENTICATION);
|
||||
if (Boolean.valueOf(allowKerberosCfg)) {
|
||||
CredentialHelper.setAlternativeCredential(session, CredentialRepresentation.KERBEROS, realm);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get List of available provider factories
|
||||
*
|
||||
|
@ -125,7 +147,7 @@ public class UserFederationProvidersResource {
|
|||
UserFederationProviderModel model = realm.addUserFederationProvider(rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName,
|
||||
rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync());
|
||||
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId());
|
||||
boolean kerberosCredsAdded = KeycloakModelUtils.checkKerberosCredential(realm, model);
|
||||
boolean kerberosCredsAdded = checkKerberosCredential(session, realm, model);
|
||||
if (kerberosCredsAdded) {
|
||||
logger.info("Added 'kerberos' to required realm credentials");
|
||||
}
|
||||
|
|
58
services/src/main/java/org/keycloak/utils/CredentialHelper.java
Executable file
58
services/src/main/java/org/keycloak/utils/CredentialHelper.java
Executable file
|
@ -0,0 +1,58 @@
|
|||
package org.keycloak.utils;
|
||||
|
||||
import org.keycloak.authentication.Authenticator;
|
||||
import org.keycloak.authentication.AuthenticatorFactory;
|
||||
import org.keycloak.authentication.ConfigurableAuthenticatorFactory;
|
||||
import org.keycloak.authentication.FormAction;
|
||||
import org.keycloak.authentication.FormActionFactory;
|
||||
import org.keycloak.authentication.authenticators.OTPFormAuthenticatorFactory;
|
||||
import org.keycloak.authentication.authenticators.SpnegoAuthenticatorFactory;
|
||||
import org.keycloak.authentication.authenticators.UsernamePasswordFormFactory;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
|
||||
/**
|
||||
* used to set an execution a state based on type.
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class CredentialHelper {
|
||||
|
||||
public static void setRequiredCredential(KeycloakSession session, String type, RealmModel realm) {
|
||||
AuthenticationExecutionModel.Requirement requirement = AuthenticationExecutionModel.Requirement.REQUIRED;
|
||||
authenticationRequirement(session, realm, type, requirement);
|
||||
}
|
||||
|
||||
public static void setAlternativeCredential(KeycloakSession session, String type, RealmModel realm) {
|
||||
AuthenticationExecutionModel.Requirement requirement = AuthenticationExecutionModel.Requirement.ALTERNATIVE;
|
||||
authenticationRequirement(session, realm, type, requirement);
|
||||
}
|
||||
|
||||
public static void authenticationRequirement(KeycloakSession session, RealmModel realm, String type, AuthenticationExecutionModel.Requirement requirement) {
|
||||
for (AuthenticationFlowModel flow : realm.getAuthenticationFlows()) {
|
||||
for (AuthenticationExecutionModel execution : realm.getAuthenticationExecutions(flow.getId())) {
|
||||
String providerId = execution.getAuthenticator();
|
||||
ConfigurableAuthenticatorFactory factory = getConfigurableAuthenticatorFactory(session, providerId);
|
||||
if (factory == null) continue;
|
||||
if (type.equals(factory.getReferenceCategory())) {
|
||||
execution.setRequirement(requirement);
|
||||
realm.updateAuthenticatorExecution(execution);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ConfigurableAuthenticatorFactory getConfigurableAuthenticatorFactory(KeycloakSession session, String providerId) {
|
||||
ConfigurableAuthenticatorFactory factory = (AuthenticatorFactory)session.getKeycloakSessionFactory().getProviderFactory(Authenticator.class, providerId);
|
||||
if (factory == null) {
|
||||
factory = (FormActionFactory)session.getKeycloakSessionFactory().getProviderFactory(FormAction.class, providerId);
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
}
|
|
@ -26,15 +26,11 @@ import org.junit.Before;
|
|||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.authentication.authenticators.OTPFormAuthenticator;
|
||||
import org.keycloak.authentication.authenticators.OTPFormAuthenticatorFactory;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.MailUtil;
|
||||
|
@ -50,7 +46,6 @@ import org.keycloak.testsuite.rule.KeycloakRule;
|
|||
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.testsuite.utils.CredentialHelper;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
|
|
|
@ -1,217 +1,223 @@
|
|||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2012, Red Hat, Inc., and individual contributors
|
||||
* as indicated by the @author tags. See the copyright.txt file in the
|
||||
* distribution for a full listing of individual contributors.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||
*/
|
||||
package org.keycloak.testsuite.actions;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.TimeBasedOTP;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.pages.AccountTotpPage;
|
||||
import org.keycloak.testsuite.pages.AppPage;
|
||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||
import org.keycloak.testsuite.pages.LoginConfigTotpPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.pages.LoginTotpPage;
|
||||
import org.keycloak.testsuite.pages.RegisterPage;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.testsuite.utils.CredentialHelper;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class RequiredActionTotpSetupTest {
|
||||
|
||||
@ClassRule
|
||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
|
||||
CredentialHelper.setRequiredCredential(CredentialRepresentation.TOTP, appRealm);
|
||||
appRealm.addRequiredCredential(CredentialRepresentation.TOTP);
|
||||
appRealm.setResetPasswordAllowed(true);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected AppPage appPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginTotpPage loginTotpPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginConfigTotpPage totpPage;
|
||||
|
||||
@WebResource
|
||||
protected AccountTotpPage accountTotpPage;
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
@WebResource
|
||||
protected RegisterPage registerPage;
|
||||
|
||||
protected TimeBasedOTP totp = new TimeBasedOTP();
|
||||
|
||||
@Test
|
||||
public void setupTotpRegister() {
|
||||
loginPage.open();
|
||||
loginPage.clickRegister();
|
||||
registerPage.register("firstName", "lastName", "email@mail.com", "setupTotp", "password", "password");
|
||||
|
||||
String userId = events.expectRegister("setupTotp", "email@mail.com").assertEvent().getUserId();
|
||||
|
||||
totpPage.assertCurrent();
|
||||
|
||||
totpPage.configure(totp.generate(totpPage.getTotpSecret()));
|
||||
|
||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).user(userId).detail(Details.USERNAME, "setuptotp").assertEvent().getSessionId();
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectLogin().user(userId).session(sessionId).detail(Details.USERNAME, "setuptotp").assertEvent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupTotpExisting() {
|
||||
loginPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
totpPage.assertCurrent();
|
||||
|
||||
String totpSecret = totpPage.getTotpSecret();
|
||||
|
||||
totpPage.configure(totp.generate(totpSecret));
|
||||
|
||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).assertEvent().getSessionId();
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
Event loginEvent = events.expectLogin().session(sessionId).assertEvent();
|
||||
|
||||
oauth.openLogout();
|
||||
|
||||
events.expectLogout(loginEvent.getSessionId()).assertEvent();
|
||||
|
||||
loginPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
String src = driver.getPageSource();
|
||||
loginTotpPage.login(totp.generate(totpSecret));
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectLogin().assertEvent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupTotpRegisteredAfterTotpRemoval() {
|
||||
// Register new user
|
||||
loginPage.open();
|
||||
loginPage.clickRegister();
|
||||
registerPage.register("firstName2", "lastName2", "email2@mail.com", "setupTotp2", "password2", "password2");
|
||||
|
||||
String userId = events.expectRegister("setupTotp2", "email2@mail.com").assertEvent().getUserId();
|
||||
|
||||
// Configure totp
|
||||
totpPage.assertCurrent();
|
||||
|
||||
String totpCode = totpPage.getTotpSecret();
|
||||
totpPage.configure(totp.generate(totpCode));
|
||||
|
||||
// After totp config, user should be on the app page
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectRequiredAction(EventType.UPDATE_TOTP).user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
|
||||
Event loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
|
||||
// Logout
|
||||
oauth.openLogout();
|
||||
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
|
||||
|
||||
// Try to login after logout
|
||||
loginPage.open();
|
||||
loginPage.login("setupTotp2", "password2");
|
||||
|
||||
// Totp is already configured, thus one-time password is needed, login page should be loaded
|
||||
Assert.assertTrue(loginPage.isCurrent());
|
||||
Assert.assertFalse(totpPage.isCurrent());
|
||||
|
||||
// Login with one-time password
|
||||
loginTotpPage.login(totp.generate(totpCode));
|
||||
|
||||
loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
|
||||
// Open account page
|
||||
accountTotpPage.open();
|
||||
accountTotpPage.assertCurrent();
|
||||
|
||||
// Remove google authentificator
|
||||
accountTotpPage.removeTotp();
|
||||
|
||||
events.expectAccount(EventType.REMOVE_TOTP).user(userId).assertEvent();
|
||||
|
||||
// Logout
|
||||
oauth.openLogout();
|
||||
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
|
||||
|
||||
// Try to login
|
||||
loginPage.open();
|
||||
loginPage.login("setupTotp2", "password2");
|
||||
|
||||
// Since the authentificator was removed, it has to be set up again
|
||||
totpPage.assertCurrent();
|
||||
totpPage.configure(totp.generate(totpPage.getTotpSecret()));
|
||||
|
||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent().getSessionId();
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectLogin().user(userId).session(sessionId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2012, Red Hat, Inc., and individual contributors
|
||||
* as indicated by the @author tags. See the copyright.txt file in the
|
||||
* distribution for a full listing of individual contributors.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||
*/
|
||||
package org.keycloak.testsuite.actions;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.authentication.requiredactions.UpdateTotp;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.events.Event;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.TimeBasedOTP;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.pages.AccountTotpPage;
|
||||
import org.keycloak.testsuite.pages.AppPage;
|
||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||
import org.keycloak.testsuite.pages.LoginConfigTotpPage;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.pages.LoginTotpPage;
|
||||
import org.keycloak.testsuite.pages.RegisterPage;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.utils.CredentialHelper;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class RequiredActionTotpSetupTest {
|
||||
|
||||
@ClassRule
|
||||
public static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakSetup() {
|
||||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
|
||||
CredentialHelper.setRequiredCredential(manager.getSession(), CredentialRepresentation.TOTP, appRealm);
|
||||
//appRealm.addRequiredCredential(CredentialRepresentation.TOTP);
|
||||
RequiredActionProviderModel requiredAction = appRealm.getRequiredActionProviderByAlias(UserModel.RequiredAction.CONFIGURE_TOTP.name());
|
||||
requiredAction.setDefaultAction(true);
|
||||
appRealm.updateRequiredActionProvider(requiredAction);
|
||||
appRealm.setResetPasswordAllowed(true);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(keycloakRule);
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected AppPage appPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginTotpPage loginTotpPage;
|
||||
|
||||
@WebResource
|
||||
protected LoginConfigTotpPage totpPage;
|
||||
|
||||
@WebResource
|
||||
protected AccountTotpPage accountTotpPage;
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
@WebResource
|
||||
protected RegisterPage registerPage;
|
||||
|
||||
protected TimeBasedOTP totp = new TimeBasedOTP();
|
||||
|
||||
@Test
|
||||
public void setupTotpRegister() {
|
||||
loginPage.open();
|
||||
loginPage.clickRegister();
|
||||
registerPage.register("firstName", "lastName", "email@mail.com", "setupTotp", "password", "password");
|
||||
|
||||
String userId = events.expectRegister("setupTotp", "email@mail.com").assertEvent().getUserId();
|
||||
|
||||
totpPage.assertCurrent();
|
||||
|
||||
totpPage.configure(totp.generate(totpPage.getTotpSecret()));
|
||||
|
||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).user(userId).detail(Details.USERNAME, "setuptotp").assertEvent().getSessionId();
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectLogin().user(userId).session(sessionId).detail(Details.USERNAME, "setuptotp").assertEvent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupTotpExisting() {
|
||||
loginPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
|
||||
totpPage.assertCurrent();
|
||||
|
||||
String totpSecret = totpPage.getTotpSecret();
|
||||
|
||||
totpPage.configure(totp.generate(totpSecret));
|
||||
|
||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).assertEvent().getSessionId();
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
Event loginEvent = events.expectLogin().session(sessionId).assertEvent();
|
||||
|
||||
oauth.openLogout();
|
||||
|
||||
events.expectLogout(loginEvent.getSessionId()).assertEvent();
|
||||
|
||||
loginPage.open();
|
||||
loginPage.login("test-user@localhost", "password");
|
||||
String src = driver.getPageSource();
|
||||
loginTotpPage.login(totp.generate(totpSecret));
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectLogin().assertEvent();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setupTotpRegisteredAfterTotpRemoval() {
|
||||
// Register new user
|
||||
loginPage.open();
|
||||
loginPage.clickRegister();
|
||||
registerPage.register("firstName2", "lastName2", "email2@mail.com", "setupTotp2", "password2", "password2");
|
||||
|
||||
String userId = events.expectRegister("setupTotp2", "email2@mail.com").assertEvent().getUserId();
|
||||
|
||||
// Configure totp
|
||||
totpPage.assertCurrent();
|
||||
|
||||
String totpCode = totpPage.getTotpSecret();
|
||||
totpPage.configure(totp.generate(totpCode));
|
||||
|
||||
// After totp config, user should be on the app page
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectRequiredAction(EventType.UPDATE_TOTP).user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
|
||||
Event loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
|
||||
// Logout
|
||||
oauth.openLogout();
|
||||
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
|
||||
|
||||
// Try to login after logout
|
||||
loginPage.open();
|
||||
loginPage.login("setupTotp2", "password2");
|
||||
|
||||
// Totp is already configured, thus one-time password is needed, login page should be loaded
|
||||
Assert.assertTrue(loginPage.isCurrent());
|
||||
Assert.assertFalse(totpPage.isCurrent());
|
||||
|
||||
// Login with one-time password
|
||||
loginTotpPage.login(totp.generate(totpCode));
|
||||
|
||||
loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
|
||||
// Open account page
|
||||
accountTotpPage.open();
|
||||
accountTotpPage.assertCurrent();
|
||||
|
||||
// Remove google authentificator
|
||||
accountTotpPage.removeTotp();
|
||||
|
||||
events.expectAccount(EventType.REMOVE_TOTP).user(userId).assertEvent();
|
||||
|
||||
// Logout
|
||||
oauth.openLogout();
|
||||
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
|
||||
|
||||
// Try to login
|
||||
loginPage.open();
|
||||
loginPage.login("setupTotp2", "password2");
|
||||
|
||||
// Since the authentificator was removed, it has to be set up again
|
||||
totpPage.assertCurrent();
|
||||
totpPage.configure(totp.generate(totpPage.getTotpSecret()));
|
||||
|
||||
String sessionId = events.expectRequiredAction(EventType.UPDATE_TOTP).user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent().getSessionId();
|
||||
|
||||
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
|
||||
|
||||
events.expectLogin().user(userId).session(sessionId).detail(Details.USERNAME, "setuptotp2").assertEvent();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,296 +1,296 @@
|
|||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2012, Red Hat, Inc., and individual contributors
|
||||
* as indicated by the @author tags. See the copyright.txt file in the
|
||||
* distribution for a full listing of individual contributors.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||
*/
|
||||
package org.keycloak.testsuite.composites;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.enums.SslRequired;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.ApplicationServlet;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class CompositeRoleTest {
|
||||
|
||||
public static PublicKey realmPublicKey;
|
||||
@ClassRule
|
||||
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){
|
||||
@Override
|
||||
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
|
||||
RealmModel realm = manager.createRealm("test");
|
||||
KeycloakModelUtils.generateRealmKeys(realm);
|
||||
realmPublicKey = realm.getPublicKey();
|
||||
realm.setSsoSessionIdleTimeout(3000);
|
||||
realm.setAccessTokenLifespan(10000);
|
||||
realm.setSsoSessionMaxLifespan(10000);
|
||||
realm.setAccessCodeLifespanUserAction(1000);
|
||||
realm.setAccessCodeLifespan(1000);
|
||||
realm.setSslRequired(SslRequired.EXTERNAL);
|
||||
realm.setEnabled(true);
|
||||
realm.addRequiredCredential(UserCredentialModel.PASSWORD);
|
||||
final RoleModel realmRole1 = realm.addRole("REALM_ROLE_1");
|
||||
final RoleModel realmRole2 = realm.addRole("REALM_ROLE_2");
|
||||
final RoleModel realmRole3 = realm.addRole("REALM_ROLE_3");
|
||||
final RoleModel realmComposite1 = realm.addRole("REALM_COMPOSITE_1");
|
||||
realmComposite1.addCompositeRole(realmRole1);
|
||||
|
||||
final UserModel realmComposite1User = session.users().addUser(realm, "REALM_COMPOSITE_1_USER");
|
||||
realmComposite1User.setEnabled(true);
|
||||
realmComposite1User.updateCredential(UserCredentialModel.password("password"));
|
||||
realmComposite1User.grantRole(realmComposite1);
|
||||
|
||||
final UserModel realmRole1User = session.users().addUser(realm, "REALM_ROLE_1_USER");
|
||||
realmRole1User.setEnabled(true);
|
||||
realmRole1User.updateCredential(UserCredentialModel.password("password"));
|
||||
realmRole1User.grantRole(realmRole1);
|
||||
|
||||
final ClientModel realmComposite1Application = new ClientManager(manager).createClient(realm, "REALM_COMPOSITE_1_APPLICATION");
|
||||
realmComposite1Application.setFullScopeAllowed(false);
|
||||
realmComposite1Application.setEnabled(true);
|
||||
realmComposite1Application.addScopeMapping(realmComposite1);
|
||||
realmComposite1Application.addRedirectUri("http://localhost:8081/app/*");
|
||||
realmComposite1Application.setBaseUrl("http://localhost:8081/app");
|
||||
realmComposite1Application.setManagementUrl("http://localhost:8081/app/logout");
|
||||
realmComposite1Application.setSecret("password");
|
||||
|
||||
final ClientModel realmRole1Application = new ClientManager(manager).createClient(realm, "REALM_ROLE_1_APPLICATION");
|
||||
realmRole1Application.setFullScopeAllowed(false);
|
||||
realmRole1Application.setEnabled(true);
|
||||
realmRole1Application.addScopeMapping(realmRole1);
|
||||
realmRole1Application.addRedirectUri("http://localhost:8081/app/*");
|
||||
realmRole1Application.setBaseUrl("http://localhost:8081/app");
|
||||
realmRole1Application.setManagementUrl("http://localhost:8081/app/logout");
|
||||
realmRole1Application.setSecret("password");
|
||||
|
||||
|
||||
final ClientModel appRoleApplication = new ClientManager(manager).createClient(realm, "APP_ROLE_APPLICATION");
|
||||
appRoleApplication.setFullScopeAllowed(false);
|
||||
appRoleApplication.setEnabled(true);
|
||||
appRoleApplication.addRedirectUri("http://localhost:8081/app/*");
|
||||
appRoleApplication.setBaseUrl("http://localhost:8081/app");
|
||||
appRoleApplication.setManagementUrl("http://localhost:8081/app/logout");
|
||||
appRoleApplication.setSecret("password");
|
||||
final RoleModel appRole1 = appRoleApplication.addRole("APP_ROLE_1");
|
||||
final RoleModel appRole2 = appRoleApplication.addRole("APP_ROLE_2");
|
||||
|
||||
final RoleModel realmAppCompositeRole = realm.addRole("REALM_APP_COMPOSITE_ROLE");
|
||||
realmAppCompositeRole.addCompositeRole(appRole1);
|
||||
|
||||
final UserModel realmAppCompositeUser = session.users().addUser(realm, "REALM_APP_COMPOSITE_USER");
|
||||
realmAppCompositeUser.setEnabled(true);
|
||||
realmAppCompositeUser.updateCredential(UserCredentialModel.password("password"));
|
||||
realmAppCompositeUser.grantRole(realmAppCompositeRole);
|
||||
|
||||
final UserModel realmAppRoleUser = session.users().addUser(realm, "REALM_APP_ROLE_USER");
|
||||
realmAppRoleUser.setEnabled(true);
|
||||
realmAppRoleUser.updateCredential(UserCredentialModel.password("password"));
|
||||
realmAppRoleUser.grantRole(appRole2);
|
||||
|
||||
final ClientModel appCompositeApplication = new ClientManager(manager).createClient(realm, "APP_COMPOSITE_APPLICATION");
|
||||
appCompositeApplication.setFullScopeAllowed(false);
|
||||
appCompositeApplication.setEnabled(true);
|
||||
appCompositeApplication.addRedirectUri("http://localhost:8081/app/*");
|
||||
appCompositeApplication.setBaseUrl("http://localhost:8081/app");
|
||||
appCompositeApplication.setManagementUrl("http://localhost:8081/app/logout");
|
||||
appCompositeApplication.setSecret("password");
|
||||
final RoleModel appCompositeRole = appCompositeApplication.addRole("APP_COMPOSITE_ROLE");
|
||||
appCompositeApplication.addScopeMapping(appRole2);
|
||||
appCompositeRole.addCompositeRole(realmRole1);
|
||||
appCompositeRole.addCompositeRole(realmRole2);
|
||||
appCompositeRole.addCompositeRole(realmRole3);
|
||||
appCompositeRole.addCompositeRole(appRole1);
|
||||
|
||||
final UserModel appCompositeUser = session.users().addUser(realm, "APP_COMPOSITE_USER");
|
||||
appCompositeUser.setEnabled(true);
|
||||
appCompositeUser.updateCredential(UserCredentialModel.password("password"));
|
||||
appCompositeUser.grantRole(realmAppCompositeRole);
|
||||
appCompositeUser.grantRole(realmComposite1);
|
||||
|
||||
deployServlet("app", "/app", ApplicationServlet.class);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@Test
|
||||
public void testAppCompositeUser() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("APP_COMPOSITE_APPLICATION");
|
||||
oauth.doLogin("APP_COMPOSITE_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "APP_COMPOSITE_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
|
||||
Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRealmAppCompositeUser() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("APP_ROLE_APPLICATION");
|
||||
oauth.doLogin("REALM_APP_COMPOSITE_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_APP_COMPOSITE_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
|
||||
Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRealmOnlyWithUserCompositeAppComposite() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("REALM_COMPOSITE_1_APPLICATION");
|
||||
oauth.doLogin("REALM_COMPOSITE_1_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(2, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRealmOnlyWithUserCompositeAppRole() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("REALM_ROLE_1_APPLICATION");
|
||||
oauth.doLogin("REALM_COMPOSITE_1_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRealmOnlyWithUserRoleAppComposite() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("REALM_COMPOSITE_1_APPLICATION");
|
||||
oauth.doLogin("REALM_ROLE_1_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_ROLE_1_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* JBoss, Home of Professional Open Source.
|
||||
* Copyright 2012, Red Hat, Inc., and individual contributors
|
||||
* as indicated by the @author tags. See the copyright.txt file in the
|
||||
* distribution for a full listing of individual contributors.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
||||
*/
|
||||
package org.keycloak.testsuite.composites;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.OAuth2Constants;
|
||||
import org.keycloak.enums.SslRequired;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserCredentialModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.representations.AccessToken;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.ApplicationServlet;
|
||||
import org.keycloak.testsuite.OAuthClient;
|
||||
import org.keycloak.testsuite.OAuthClient.AccessTokenResponse;
|
||||
import org.keycloak.testsuite.pages.LoginPage;
|
||||
import org.keycloak.testsuite.rule.AbstractKeycloakRule;
|
||||
import org.keycloak.testsuite.rule.WebResource;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class CompositeRoleTest {
|
||||
|
||||
public static PublicKey realmPublicKey;
|
||||
@ClassRule
|
||||
public static AbstractKeycloakRule keycloakRule = new AbstractKeycloakRule(){
|
||||
@Override
|
||||
protected void configure(KeycloakSession session, RealmManager manager, RealmModel adminRealm) {
|
||||
RealmModel realm = manager.createRealm("test");
|
||||
KeycloakModelUtils.generateRealmKeys(realm);
|
||||
realmPublicKey = realm.getPublicKey();
|
||||
realm.setSsoSessionIdleTimeout(3000);
|
||||
realm.setAccessTokenLifespan(10000);
|
||||
realm.setSsoSessionMaxLifespan(10000);
|
||||
realm.setAccessCodeLifespanUserAction(1000);
|
||||
realm.setAccessCodeLifespan(1000);
|
||||
realm.setSslRequired(SslRequired.EXTERNAL);
|
||||
realm.setEnabled(true);
|
||||
realm.addRequiredCredential(UserCredentialModel.PASSWORD);
|
||||
final RoleModel realmRole1 = realm.addRole("REALM_ROLE_1");
|
||||
final RoleModel realmRole2 = realm.addRole("REALM_ROLE_2");
|
||||
final RoleModel realmRole3 = realm.addRole("REALM_ROLE_3");
|
||||
final RoleModel realmComposite1 = realm.addRole("REALM_COMPOSITE_1");
|
||||
realmComposite1.addCompositeRole(realmRole1);
|
||||
|
||||
final UserModel realmComposite1User = session.users().addUser(realm, "REALM_COMPOSITE_1_USER");
|
||||
realmComposite1User.setEnabled(true);
|
||||
realmComposite1User.updateCredential(UserCredentialModel.password("password"));
|
||||
realmComposite1User.grantRole(realmComposite1);
|
||||
|
||||
final UserModel realmRole1User = session.users().addUser(realm, "REALM_ROLE_1_USER");
|
||||
realmRole1User.setEnabled(true);
|
||||
realmRole1User.updateCredential(UserCredentialModel.password("password"));
|
||||
realmRole1User.grantRole(realmRole1);
|
||||
|
||||
final ClientModel realmComposite1Application = new ClientManager(manager).createClient(realm, "REALM_COMPOSITE_1_APPLICATION");
|
||||
realmComposite1Application.setFullScopeAllowed(false);
|
||||
realmComposite1Application.setEnabled(true);
|
||||
realmComposite1Application.addScopeMapping(realmComposite1);
|
||||
realmComposite1Application.addRedirectUri("http://localhost:8081/app/*");
|
||||
realmComposite1Application.setBaseUrl("http://localhost:8081/app");
|
||||
realmComposite1Application.setManagementUrl("http://localhost:8081/app/logout");
|
||||
realmComposite1Application.setSecret("password");
|
||||
|
||||
final ClientModel realmRole1Application = new ClientManager(manager).createClient(realm, "REALM_ROLE_1_APPLICATION");
|
||||
realmRole1Application.setFullScopeAllowed(false);
|
||||
realmRole1Application.setEnabled(true);
|
||||
realmRole1Application.addScopeMapping(realmRole1);
|
||||
realmRole1Application.addRedirectUri("http://localhost:8081/app/*");
|
||||
realmRole1Application.setBaseUrl("http://localhost:8081/app");
|
||||
realmRole1Application.setManagementUrl("http://localhost:8081/app/logout");
|
||||
realmRole1Application.setSecret("password");
|
||||
|
||||
|
||||
final ClientModel appRoleApplication = new ClientManager(manager).createClient(realm, "APP_ROLE_APPLICATION");
|
||||
appRoleApplication.setFullScopeAllowed(false);
|
||||
appRoleApplication.setEnabled(true);
|
||||
appRoleApplication.addRedirectUri("http://localhost:8081/app/*");
|
||||
appRoleApplication.setBaseUrl("http://localhost:8081/app");
|
||||
appRoleApplication.setManagementUrl("http://localhost:8081/app/logout");
|
||||
appRoleApplication.setSecret("password");
|
||||
final RoleModel appRole1 = appRoleApplication.addRole("APP_ROLE_1");
|
||||
final RoleModel appRole2 = appRoleApplication.addRole("APP_ROLE_2");
|
||||
|
||||
final RoleModel realmAppCompositeRole = realm.addRole("REALM_APP_COMPOSITE_ROLE");
|
||||
realmAppCompositeRole.addCompositeRole(appRole1);
|
||||
|
||||
final UserModel realmAppCompositeUser = session.users().addUser(realm, "REALM_APP_COMPOSITE_USER");
|
||||
realmAppCompositeUser.setEnabled(true);
|
||||
realmAppCompositeUser.updateCredential(UserCredentialModel.password("password"));
|
||||
realmAppCompositeUser.grantRole(realmAppCompositeRole);
|
||||
|
||||
final UserModel realmAppRoleUser = session.users().addUser(realm, "REALM_APP_ROLE_USER");
|
||||
realmAppRoleUser.setEnabled(true);
|
||||
realmAppRoleUser.updateCredential(UserCredentialModel.password("password"));
|
||||
realmAppRoleUser.grantRole(appRole2);
|
||||
|
||||
final ClientModel appCompositeApplication = new ClientManager(manager).createClient(realm, "APP_COMPOSITE_APPLICATION");
|
||||
appCompositeApplication.setFullScopeAllowed(false);
|
||||
appCompositeApplication.setEnabled(true);
|
||||
appCompositeApplication.addRedirectUri("http://localhost:8081/app/*");
|
||||
appCompositeApplication.setBaseUrl("http://localhost:8081/app");
|
||||
appCompositeApplication.setManagementUrl("http://localhost:8081/app/logout");
|
||||
appCompositeApplication.setSecret("password");
|
||||
final RoleModel appCompositeRole = appCompositeApplication.addRole("APP_COMPOSITE_ROLE");
|
||||
appCompositeApplication.addScopeMapping(appRole2);
|
||||
appCompositeRole.addCompositeRole(realmRole1);
|
||||
appCompositeRole.addCompositeRole(realmRole2);
|
||||
appCompositeRole.addCompositeRole(realmRole3);
|
||||
appCompositeRole.addCompositeRole(appRole1);
|
||||
|
||||
final UserModel appCompositeUser = session.users().addUser(realm, "APP_COMPOSITE_USER");
|
||||
appCompositeUser.setEnabled(true);
|
||||
appCompositeUser.updateCredential(UserCredentialModel.password("password"));
|
||||
appCompositeUser.grantRole(realmAppCompositeRole);
|
||||
appCompositeUser.grantRole(realmComposite1);
|
||||
|
||||
deployServlet("app", "/app", ApplicationServlet.class);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public WebRule webRule = new WebRule(this);
|
||||
|
||||
@WebResource
|
||||
protected WebDriver driver;
|
||||
|
||||
@WebResource
|
||||
protected OAuthClient oauth;
|
||||
|
||||
@WebResource
|
||||
protected LoginPage loginPage;
|
||||
|
||||
@Test
|
||||
public void testAppCompositeUser() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("APP_COMPOSITE_APPLICATION");
|
||||
oauth.doLogin("APP_COMPOSITE_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "APP_COMPOSITE_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
|
||||
Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRealmAppCompositeUser() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("APP_ROLE_APPLICATION");
|
||||
oauth.doLogin("REALM_APP_COMPOSITE_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_APP_COMPOSITE_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getResourceAccess("APP_ROLE_APPLICATION").getRoles().size());
|
||||
Assert.assertTrue(token.getResourceAccess("APP_ROLE_APPLICATION").isUserInRole("APP_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRealmOnlyWithUserCompositeAppComposite() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("REALM_COMPOSITE_1_APPLICATION");
|
||||
oauth.doLogin("REALM_COMPOSITE_1_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(2, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_COMPOSITE_1"));
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRealmOnlyWithUserCompositeAppRole() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("REALM_ROLE_1_APPLICATION");
|
||||
oauth.doLogin("REALM_COMPOSITE_1_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_COMPOSITE_1_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRealmOnlyWithUserRoleAppComposite() throws Exception {
|
||||
oauth.realm("test");
|
||||
oauth.realmPublicKey(realmPublicKey);
|
||||
oauth.clientId("REALM_COMPOSITE_1_APPLICATION");
|
||||
oauth.doLogin("REALM_ROLE_1_USER", "password");
|
||||
|
||||
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||
|
||||
Assert.assertEquals(200, response.getStatusCode());
|
||||
|
||||
Assert.assertEquals("bearer", response.getTokenType());
|
||||
|
||||
AccessToken token = oauth.verifyToken(response.getAccessToken());
|
||||
|
||||
Assert.assertEquals(keycloakRule.getUser("test", "REALM_ROLE_1_USER").getId(), token.getSubject());
|
||||
|
||||
Assert.assertEquals(1, token.getRealmAccess().getRoles().size());
|
||||
Assert.assertTrue(token.getRealmAccess().isUserInRole("REALM_ROLE_1"));
|
||||
|
||||
AccessTokenResponse refreshResponse = oauth.doRefreshTokenRequest(response.getRefreshToken(), "password");
|
||||
Assert.assertEquals(200, refreshResponse.getStatusCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,11 +21,10 @@ import org.keycloak.models.UserFederationProviderModel;
|
|||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.adapter.CustomerServlet;
|
||||
import org.keycloak.testsuite.rule.KerberosRule;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.testsuite.utils.CredentialHelper;
|
||||
import org.keycloak.utils.CredentialHelper;
|
||||
|
||||
/**
|
||||
* Test of LDAPFederationProvider (Kerberos backed by LDAP)
|
||||
|
@ -44,7 +43,7 @@ public class KerberosLdapTest extends AbstractKerberosTest {
|
|||
|
||||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
CredentialHelper.setAlternativeCredential(CredentialRepresentation.KERBEROS, appRealm);
|
||||
CredentialHelper.setAlternativeCredential(manager.getSession(), CredentialRepresentation.KERBEROS, appRealm);
|
||||
URL url = getClass().getResource("/kerberos-test/kerberos-app-keycloak.json");
|
||||
keycloakRule.createApplicationDeployment()
|
||||
.name("kerberos-portal").contextPath("/kerberos-portal")
|
||||
|
|
|
@ -24,8 +24,7 @@ import org.keycloak.testsuite.AssertEvents;
|
|||
import org.keycloak.testsuite.rule.KerberosRule;
|
||||
import org.keycloak.testsuite.rule.KeycloakRule;
|
||||
import org.keycloak.testsuite.rule.WebRule;
|
||||
import org.keycloak.testsuite.utils.CredentialHelper;
|
||||
import org.picketlink.idm.credential.util.CredentialUtils;
|
||||
import org.keycloak.utils.CredentialHelper;
|
||||
|
||||
/**
|
||||
* Test of KerberosFederationProvider (Kerberos not backed by LDAP)
|
||||
|
@ -45,7 +44,7 @@ public class KerberosStandaloneTest extends AbstractKerberosTest {
|
|||
@Override
|
||||
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||
|
||||
CredentialHelper.setAlternativeCredential(CredentialRepresentation.KERBEROS, appRealm);
|
||||
CredentialHelper.setAlternativeCredential(manager.getSession(), CredentialRepresentation.KERBEROS, appRealm);
|
||||
URL url = getClass().getResource("/kerberos-test/kerberos-app-keycloak.json");
|
||||
keycloakRule.createApplicationDeployment()
|
||||
.name("kerberos-portal").contextPath("/kerberos-portal")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.keycloak.models;
|
||||
package org.keycloak.testsuite.model;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
|
@ -1,80 +0,0 @@
|
|||
package org.keycloak.testsuite.utils;
|
||||
|
||||
import org.keycloak.authentication.authenticators.OTPFormAuthenticatorFactory;
|
||||
import org.keycloak.authentication.authenticators.SpnegoAuthenticatorFactory;
|
||||
import org.keycloak.authentication.authenticators.UsernamePasswordFormFactory;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.AuthenticationFlowModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class CredentialHelper {
|
||||
|
||||
public static void setRequiredCredential(String type, RealmModel realm) {
|
||||
AuthenticationExecutionModel.Requirement requirement = AuthenticationExecutionModel.Requirement.REQUIRED;
|
||||
setCredentialRequirement(type, realm, requirement);
|
||||
}
|
||||
|
||||
public static void setAlternativeCredential(String type, RealmModel realm) {
|
||||
AuthenticationExecutionModel.Requirement requirement = AuthenticationExecutionModel.Requirement.ALTERNATIVE;
|
||||
setCredentialRequirement(type, realm, requirement);
|
||||
}
|
||||
|
||||
public static void setCredentialRequirement(String type, RealmModel realm, AuthenticationExecutionModel.Requirement requirement) {
|
||||
if (type.equals(CredentialRepresentation.TOTP)) {
|
||||
String providerId = OTPFormAuthenticatorFactory.PROVIDER_ID;
|
||||
String flowAlias = DefaultAuthenticationFlows.LOGIN_FORMS_FLOW;
|
||||
authenticationRequirement(realm, providerId, flowAlias, requirement);
|
||||
} else if (type.equals(CredentialRepresentation.KERBEROS)) {
|
||||
String providerId = SpnegoAuthenticatorFactory.PROVIDER_ID;
|
||||
String flowAlias = DefaultAuthenticationFlows.BROWSER_FLOW;
|
||||
authenticationRequirement(realm, providerId, flowAlias, requirement);
|
||||
} else if (type.equals(CredentialRepresentation.PASSWORD)) {
|
||||
String providerId = UsernamePasswordFormFactory.PROVIDER_ID;
|
||||
String flowAlias = DefaultAuthenticationFlows.LOGIN_FORMS_FLOW;
|
||||
authenticationRequirement(realm, providerId, flowAlias, requirement);
|
||||
}
|
||||
}
|
||||
|
||||
public static AuthenticationExecutionModel.Requirement getRequirement(RealmModel realm, String authenticatorProviderId, String flowAlias) {
|
||||
AuthenticationFlowModel flow = findAuthenticatorFlowByAlias(realm, flowAlias);
|
||||
AuthenticationExecutionModel execution = findExecutionByAuthenticator(realm, flow.getId(), authenticatorProviderId);
|
||||
return execution.getRequirement();
|
||||
|
||||
}
|
||||
|
||||
public static void alternativeAuthentication(RealmModel realm, String authenticatorProviderId, String flowAlias) {
|
||||
AuthenticationExecutionModel.Requirement requirement = AuthenticationExecutionModel.Requirement.ALTERNATIVE;
|
||||
authenticationRequirement(realm, authenticatorProviderId, flowAlias, requirement);
|
||||
}
|
||||
|
||||
public static void authenticationRequirement(RealmModel realm, String authenticatorProviderId, String flowAlias, AuthenticationExecutionModel.Requirement requirement) {
|
||||
AuthenticationFlowModel flow = findAuthenticatorFlowByAlias(realm, flowAlias);
|
||||
AuthenticationExecutionModel execution = findExecutionByAuthenticator(realm, flow.getId(), authenticatorProviderId);
|
||||
execution.setRequirement(requirement);
|
||||
realm.updateAuthenticatorExecution(execution);
|
||||
}
|
||||
|
||||
public static AuthenticationFlowModel findAuthenticatorFlowByAlias(RealmModel realm, String alias) {
|
||||
for (AuthenticationFlowModel model : realm.getAuthenticationFlows()) {
|
||||
if (model.getAlias().equals(alias)) {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static AuthenticationExecutionModel findExecutionByAuthenticator(RealmModel realm, String flowId, String authId) {
|
||||
for (AuthenticationExecutionModel model : realm.getAuthenticationExecutions(flowId)) {
|
||||
if (model.getAuthenticator().equals(authId)) {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ import org.apache.log.Logger;
|
|||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
|
||||
|
@ -76,13 +75,6 @@ public class CreateRealmsWorker implements Worker {
|
|||
}
|
||||
}
|
||||
|
||||
// Add required credentials
|
||||
if (createRequiredCredentials) {
|
||||
RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.PASSWORD);
|
||||
RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.TOTP);
|
||||
RepresentationToModel.addRequiredCredential(realm, CredentialRepresentation.CLIENT_CERT);
|
||||
}
|
||||
|
||||
log.info("Finished creation of realm " + realmName);
|
||||
|
||||
int labelC = ((realmNumber - 1) / NUMBER_OF_REALMS_IN_EACH_REPORT) * NUMBER_OF_REALMS_IN_EACH_REPORT;
|
||||
|
|
Loading…
Reference in a new issue