migrate RequiredCredentials

This commit is contained in:
Bill Burke 2015-07-16 22:03:12 -04:00
parent e825be1c79
commit e51d2137cf
18 changed files with 722 additions and 673 deletions

View file

@ -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;
}
}

View file

@ -1,12 +1,16 @@
package org.keycloak.migration.migrators; package org.keycloak.migration.migrators;
import org.keycloak.migration.ModelVersion; import org.keycloak.migration.ModelVersion;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.ImpersonationConstants; import org.keycloak.models.ImpersonationConstants;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.models.utils.DefaultRequiredActions; import org.keycloak.models.utils.DefaultRequiredActions;
import java.util.HashSet;
import java.util.List; import java.util.List;
/** /**
@ -20,11 +24,10 @@ public class MigrateTo1_4_0 {
List<RealmModel> realms = session.realms().getRealms(); List<RealmModel> realms = session.realms().getRealms();
for (RealmModel realm : realms) { for (RealmModel realm : realms) {
if (realm.getAuthenticationFlows().size() == 0) { if (realm.getAuthenticationFlows().size() == 0) {
DefaultAuthenticationFlows.addFlows(realm); DefaultAuthenticationFlows.migrateFlows(realm);
DefaultRequiredActions.addActions(realm); DefaultRequiredActions.addActions(realm);
} }
ImpersonationConstants.setupImpersonationService(session, realm); ImpersonationConstants.setupImpersonationService(session, realm);
} }
} }

View file

@ -4,6 +4,7 @@ import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.AuthenticatorConfigModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -23,6 +24,13 @@ public class DefaultAuthenticationFlows {
if (realm.getFlowByAlias(BROWSER_FLOW) == null) browserFlow(realm); if (realm.getFlowByAlias(BROWSER_FLOW) == null) browserFlow(realm);
if (realm.getFlowByAlias(REGISTRATION_FLOW) == null) registrationFlow(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) { public static void registrationFlow(RealmModel realm) {
AuthenticationFlowModel registrationFlow = new AuthenticationFlowModel(); AuthenticationFlowModel registrationFlow = new AuthenticationFlowModel();
@ -102,6 +110,20 @@ public class DefaultAuthenticationFlows {
} }
public static void browserFlow(RealmModel realm) { 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(); AuthenticationFlowModel browser = new AuthenticationFlowModel();
browser.setAlias(BROWSER_FLOW); browser.setAlias(BROWSER_FLOW);
browser.setDescription("browser based authentication"); browser.setDescription("browser based authentication");
@ -120,6 +142,10 @@ public class DefaultAuthenticationFlows {
execution = new AuthenticationExecutionModel(); execution = new AuthenticationExecutionModel();
execution.setParentFlow(browser.getId()); execution.setParentFlow(browser.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED); execution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED);
if (migrate && hasCredentialType(realm, RequiredCredentialModel.KERBEROS.getType())) {
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
}
execution.setAuthenticator("auth-spnego"); execution.setAuthenticator("auth-spnego");
execution.setPriority(20); execution.setPriority(20);
execution.setUserSetupAllowed(false); execution.setUserSetupAllowed(false);
@ -158,6 +184,11 @@ public class DefaultAuthenticationFlows {
execution = new AuthenticationExecutionModel(); execution = new AuthenticationExecutionModel();
execution.setParentFlow(forms.getId()); execution.setParentFlow(forms.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.OPTIONAL); execution.setRequirement(AuthenticationExecutionModel.Requirement.OPTIONAL);
if (migrate && hasCredentialType(realm, RequiredCredentialModel.TOTP.getType())) {
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
}
execution.setAuthenticator("auth-otp-form"); execution.setAuthenticator("auth-otp-form");
execution.setPriority(20); execution.setPriority(20);
execution.setUserSetupAllowed(true); execution.setUserSetupAllowed(true);

View file

@ -350,30 +350,4 @@ public final class KeycloakModelUtils {
return mapperModel; 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;
}
} }

View file

@ -132,12 +132,13 @@ public class RepresentationToModel {
if (rep.getAdminTheme() != null) newRealm.setAdminTheme(rep.getAdminTheme()); if (rep.getAdminTheme() != null) newRealm.setAdminTheme(rep.getAdminTheme());
if (rep.getEmailTheme() != null) newRealm.setEmailTheme(rep.getEmailTheme()); if (rep.getEmailTheme() != null) newRealm.setEmailTheme(rep.getEmailTheme());
// todo remove this stuff as its all deprecated
if (rep.getRequiredCredentials() != null) { if (rep.getRequiredCredentials() != null) {
for (String requiredCred : rep.getRequiredCredentials()) { for (String requiredCred : rep.getRequiredCredentials()) {
addRequiredCredential(newRealm, requiredCred); newRealm.addRequiredCredential(requiredCred);
} }
} else { } else {
addRequiredCredential(newRealm, CredentialRepresentation.PASSWORD); newRealm.addRequiredCredential(CredentialRepresentation.PASSWORD);
} }
if (rep.getPasswordPolicy() != null) newRealm.setPasswordPolicy(new PasswordPolicy(rep.getPasswordPolicy())); 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) { public static void importAuthenticationFlows(RealmModel newRealm, RealmRepresentation rep) {
if (rep.getAuthenticationFlows() == null) { if (rep.getAuthenticationFlows() == null) {
// assume this is an old version being imported // assume this is an old version being imported
DefaultAuthenticationFlows.addFlows(newRealm); DefaultAuthenticationFlows.migrateFlows(newRealm);
} else { } else {
for (AuthenticatorConfigRepresentation configRep : rep.getAuthenticatorConfig()) { for (AuthenticatorConfigRepresentation configRep : rep.getAuthenticatorConfig()) {
AuthenticatorConfigModel model = toModel(configRep); AuthenticatorConfigModel model = toModel(configRep);
@ -521,10 +522,6 @@ public class RepresentationToModel {
// Basic realm stuff // Basic realm stuff
public static void addRequiredCredential(RealmModel newRealm, String requiredCred) {
newRealm.addRequiredCredential(requiredCred);
}
private static List<UserFederationProviderModel> convertFederationProviders(List<UserFederationProviderRepresentation> providers) { private static List<UserFederationProviderModel> convertFederationProviders(List<UserFederationProviderRepresentation> providers) {
List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>(); List<UserFederationProviderModel> result = new ArrayList<UserFederationProviderModel>();

View file

@ -22,14 +22,6 @@ public class UpdateTotp implements RequiredActionProvider, RequiredActionFactory
protected static Logger logger = Logger.getLogger(UpdateTotp.class); protected static Logger logger = Logger.getLogger(UpdateTotp.class);
@Override @Override
public void evaluateTriggers(RequiredActionContext context) { 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 @Override

View file

@ -4,12 +4,8 @@ import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.NotFoundException;
import org.keycloak.authentication.AuthenticationFlow; import org.keycloak.authentication.AuthenticationFlow;
import org.keycloak.authentication.Authenticator;
import org.keycloak.authentication.AuthenticatorFactory;
import org.keycloak.authentication.AuthenticatorUtil; import org.keycloak.authentication.AuthenticatorUtil;
import org.keycloak.authentication.ConfigurableAuthenticatorFactory; import org.keycloak.authentication.ConfigurableAuthenticatorFactory;
import org.keycloak.authentication.FormAction;
import org.keycloak.authentication.FormActionFactory;
import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticationFlowModel;
import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.AuthenticatorConfigModel;
@ -18,6 +14,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredActionProviderModel; import org.keycloak.models.RequiredActionProviderModel;
import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.representations.idm.ConfigPropertyRepresentation; import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.utils.CredentialHelper;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
@ -191,7 +188,7 @@ public class AuthenticationManagementResource {
rep.setSubFlow(true); rep.setSubFlow(true);
} }
String providerId = execution.getAuthenticator(); String providerId = execution.getAuthenticator();
ConfigurableAuthenticatorFactory factory = getConfigurableAuthenticatorFactory(providerId); ConfigurableAuthenticatorFactory factory = CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
rep.setReferenceType(factory.getDisplayType()); rep.setReferenceType(factory.getDisplayType());
rep.setConfigurable(factory.isConfigurable()); rep.setConfigurable(factory.isConfigurable());
for (AuthenticationExecutionModel.Requirement choice : factory.getRequirementChoices()) { for (AuthenticationExecutionModel.Requirement choice : factory.getRequirementChoices()) {
@ -209,14 +206,6 @@ public class AuthenticationManagementResource {
return Response.ok(result).build(); 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") @Path("/flows/{flowAlias}/executions")
@PUT @PUT
@NoCache @NoCache
@ -439,7 +428,7 @@ public class AuthenticationManagementResource {
@NoCache @NoCache
public AuthenticatorConfigDescription getAuthenticatorConfigDescription(@PathParam("providerId") String providerId) { public AuthenticatorConfigDescription getAuthenticatorConfigDescription(@PathParam("providerId") String providerId) {
this.auth.requireView(); this.auth.requireView();
ConfigurableAuthenticatorFactory factory = getConfigurableAuthenticatorFactory(providerId); ConfigurableAuthenticatorFactory factory = CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
if (factory == null) { if (factory == null) {
throw new NotFoundException("Could not find authenticator provider"); throw new NotFoundException("Could not find authenticator provider");
} }

View file

@ -34,7 +34,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserFederationMapperModel; import org.keycloak.models.UserFederationMapperModel;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.UserFederationSyncResult; import org.keycloak.models.UserFederationSyncResult;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigProperty;
@ -89,7 +88,7 @@ public class UserFederationProviderResource {
rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync()); rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync());
realm.updateUserFederationProvider(model); realm.updateUserFederationProvider(model);
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId()); 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) { if (kerberosCredsAdded) {
logger.info("Added 'kerberos' to required realm credentials"); logger.info("Added 'kerberos' to required realm credentials");
} }

View file

@ -4,19 +4,24 @@ import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.spi.NotFoundException; import org.jboss.resteasy.spi.NotFoundException;
import org.jboss.resteasy.spi.ResteasyProviderFactory; import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.constants.KerberosConstants;
import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.OperationType;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredCredentialModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserFederationProvider; import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderFactory; import org.keycloak.models.UserFederationProviderFactory;
import org.keycloak.models.UserFederationProviderModel; import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.provider.ProviderFactory; import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation; import org.keycloak.representations.idm.UserFederationProviderFactoryRepresentation;
import org.keycloak.representations.idm.UserFederationProviderRepresentation; import org.keycloak.representations.idm.UserFederationProviderRepresentation;
import org.keycloak.services.managers.UsersSyncManager; import org.keycloak.services.managers.UsersSyncManager;
import org.keycloak.timer.TimerProvider; import org.keycloak.timer.TimerProvider;
import org.keycloak.utils.CredentialHelper;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.GET; import javax.ws.rs.GET;
@ -61,6 +66,23 @@ public class UserFederationProvidersResource {
auth.init(RealmAuth.Resource.USER); 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 * Get List of available provider factories
* *
@ -125,7 +147,7 @@ public class UserFederationProvidersResource {
UserFederationProviderModel model = realm.addUserFederationProvider(rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName, UserFederationProviderModel model = realm.addUserFederationProvider(rep.getProviderName(), rep.getConfig(), rep.getPriority(), displayName,
rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync()); rep.getFullSyncPeriod(), rep.getChangedSyncPeriod(), rep.getLastSync());
new UsersSyncManager().refreshPeriodicSyncForProvider(session.getKeycloakSessionFactory(), session.getProvider(TimerProvider.class), model, realm.getId()); 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) { if (kerberosCredsAdded) {
logger.info("Added 'kerberos' to required realm credentials"); logger.info("Added 'kerberos' to required realm credentials");
} }

View 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;
}
}

View file

@ -26,15 +26,11 @@ import org.junit.Before;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; 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.Details;
import org.keycloak.events.Event; import org.keycloak.events.Event;
import org.keycloak.events.EventType; import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.MailUtil; 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.KeycloakRule.KeycloakSetup;
import org.keycloak.testsuite.rule.WebResource; import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule; import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testsuite.utils.CredentialHelper;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
import javax.mail.MessagingException; import javax.mail.MessagingException;

View file

@ -25,10 +25,13 @@ import org.junit.Assert;
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.keycloak.authentication.requiredactions.UpdateTotp;
import org.keycloak.events.Details; import org.keycloak.events.Details;
import org.keycloak.events.Event; import org.keycloak.events.Event;
import org.keycloak.events.EventType; import org.keycloak.events.EventType;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RequiredActionProviderModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
@ -45,7 +48,7 @@ import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup; import org.keycloak.testsuite.rule.KeycloakRule.KeycloakSetup;
import org.keycloak.testsuite.rule.WebResource; import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule; import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testsuite.utils.CredentialHelper; import org.keycloak.utils.CredentialHelper;
import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriver;
/** /**
@ -58,8 +61,11 @@ public class RequiredActionTotpSetupTest {
@Override @Override
public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) { public void config(RealmManager manager, RealmModel defaultRealm, RealmModel appRealm) {
CredentialHelper.setRequiredCredential(CredentialRepresentation.TOTP, appRealm); CredentialHelper.setRequiredCredential(manager.getSession(), CredentialRepresentation.TOTP, appRealm);
appRealm.addRequiredCredential(CredentialRepresentation.TOTP); //appRealm.addRequiredCredential(CredentialRepresentation.TOTP);
RequiredActionProviderModel requiredAction = appRealm.getRequiredActionProviderByAlias(UserModel.RequiredAction.CONFIGURE_TOTP.name());
requiredAction.setDefaultAction(true);
appRealm.updateRequiredActionProvider(requiredAction);
appRealm.setResetPasswordAllowed(true); appRealm.setResetPasswordAllowed(true);
} }

View file

@ -21,11 +21,10 @@ import org.keycloak.models.UserFederationProviderModel;
import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.RealmManager;
import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.adapter.CustomerServlet;
import org.keycloak.testsuite.rule.KerberosRule; import org.keycloak.testsuite.rule.KerberosRule;
import org.keycloak.testsuite.rule.KeycloakRule; import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebRule; import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testsuite.utils.CredentialHelper; import org.keycloak.utils.CredentialHelper;
/** /**
* Test of LDAPFederationProvider (Kerberos backed by LDAP) * Test of LDAPFederationProvider (Kerberos backed by LDAP)
@ -44,7 +43,7 @@ public class KerberosLdapTest extends AbstractKerberosTest {
@Override @Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { 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"); URL url = getClass().getResource("/kerberos-test/kerberos-app-keycloak.json");
keycloakRule.createApplicationDeployment() keycloakRule.createApplicationDeployment()
.name("kerberos-portal").contextPath("/kerberos-portal") .name("kerberos-portal").contextPath("/kerberos-portal")

View file

@ -24,8 +24,7 @@ import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.rule.KerberosRule; import org.keycloak.testsuite.rule.KerberosRule;
import org.keycloak.testsuite.rule.KeycloakRule; import org.keycloak.testsuite.rule.KeycloakRule;
import org.keycloak.testsuite.rule.WebRule; import org.keycloak.testsuite.rule.WebRule;
import org.keycloak.testsuite.utils.CredentialHelper; import org.keycloak.utils.CredentialHelper;
import org.picketlink.idm.credential.util.CredentialUtils;
/** /**
* Test of KerberosFederationProvider (Kerberos not backed by LDAP) * Test of KerberosFederationProvider (Kerberos not backed by LDAP)
@ -45,7 +44,7 @@ public class KerberosStandaloneTest extends AbstractKerberosTest {
@Override @Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) { 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"); URL url = getClass().getResource("/kerberos-test/kerberos-app-keycloak.json");
keycloakRule.createApplicationDeployment() keycloakRule.createApplicationDeployment()
.name("kerberos-portal").contextPath("/kerberos-portal") .name("kerberos-portal").contextPath("/kerberos-portal")

View file

@ -1,4 +1,4 @@
package org.keycloak.models; package org.keycloak.testsuite.model;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;

View file

@ -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;
}
}

View file

@ -6,7 +6,6 @@ import org.apache.log.Logger;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.services.managers.RealmManager; 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); log.info("Finished creation of realm " + realmName);
int labelC = ((realmNumber - 1) / NUMBER_OF_REALMS_IN_EACH_REPORT) * NUMBER_OF_REALMS_IN_EACH_REPORT; int labelC = ((realmNumber - 1) / NUMBER_OF_REALMS_IN_EACH_REPORT) * NUMBER_OF_REALMS_IN_EACH_REPORT;