use of org.keycloak.models.AuthenticatorConfigModel in project keycloak by keycloak.
the class UserSessionLimitsTest method setupFlows.
@Before
public void setupFlows() {
// Do this just once per class
if (testContext.isInitialized()) {
return;
}
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
if (realm.getBrowserFlow().getAlias().equals("parent-flow")) {
return;
}
// Parent flow
AuthenticationFlowModel browser = new AuthenticationFlowModel();
browser.setAlias("parent-flow");
browser.setDescription("browser based authentication");
browser.setProviderId("basic-flow");
browser.setTopLevel(true);
browser.setBuiltIn(true);
browser = realm.addAuthenticationFlow(browser);
realm.setBrowserFlow(browser);
// username password
AuthenticationExecutionModel execution = new AuthenticationExecutionModel();
execution.setParentFlow(browser.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator(UsernamePasswordFormFactory.PROVIDER_ID);
execution.setPriority(20);
execution.setAuthenticatorFlow(false);
realm.addAuthenticatorExecution(execution);
// user session limits authenticator
execution = new AuthenticationExecutionModel();
execution.setParentFlow(browser.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator(UserSessionLimitsAuthenticatorFactory.USER_SESSION_LIMITS);
execution.setPriority(30);
execution.setAuthenticatorFlow(false);
AuthenticatorConfigModel configModel = new AuthenticatorConfigModel();
Map<String, String> sessionAuthenticatorConfig = new HashMap<>();
sessionAuthenticatorConfig.put(UserSessionLimitsAuthenticatorFactory.BEHAVIOR, UserSessionLimitsAuthenticatorFactory.DENY_NEW_SESSION);
sessionAuthenticatorConfig.put(UserSessionLimitsAuthenticatorFactory.USER_REALM_LIMIT, "1");
sessionAuthenticatorConfig.put(UserSessionLimitsAuthenticatorFactory.USER_CLIENT_LIMIT, "1");
sessionAuthenticatorConfig.put(UserSessionLimitsAuthenticatorFactory.ERROR_MESSAGE, ERROR_TO_DISPLAY);
configModel.setConfig(sessionAuthenticatorConfig);
configModel.setAlias("user-session-limits");
configModel = realm.addAuthenticatorConfig(configModel);
execution.setAuthenticatorConfig(configModel.getId());
realm.addAuthenticatorExecution(execution);
});
testContext.setInitialized(true);
}
use of org.keycloak.models.AuthenticatorConfigModel in project keycloak by keycloak.
the class DefaultAuthenticationFlows method firstBrokerLoginFlow.
public static void firstBrokerLoginFlow(RealmModel realm, boolean migrate) {
AuthenticationFlowModel firstBrokerLogin = new AuthenticationFlowModel();
firstBrokerLogin.setAlias(FIRST_BROKER_LOGIN_FLOW);
firstBrokerLogin.setDescription("Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account");
firstBrokerLogin.setProviderId("basic-flow");
firstBrokerLogin.setTopLevel(true);
firstBrokerLogin.setBuiltIn(true);
firstBrokerLogin = realm.addAuthenticationFlow(firstBrokerLogin);
AuthenticatorConfigModel reviewProfileConfig = new AuthenticatorConfigModel();
reviewProfileConfig.setAlias(IDP_REVIEW_PROFILE_CONFIG_ALIAS);
Map<String, String> config = new HashMap<>();
config.put("update.profile.on.first.login", IdentityProviderRepresentation.UPFLM_MISSING);
reviewProfileConfig.setConfig(config);
reviewProfileConfig = realm.addAuthenticatorConfig(reviewProfileConfig);
AuthenticationExecutionModel execution = new AuthenticationExecutionModel();
execution.setParentFlow(firstBrokerLogin.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator("idp-review-profile");
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
execution.setAuthenticatorConfig(reviewProfileConfig.getId());
realm.addAuthenticatorExecution(execution);
AuthenticationFlowModel uniqueOrExistingFlow = new AuthenticationFlowModel();
uniqueOrExistingFlow.setTopLevel(false);
uniqueOrExistingFlow.setBuiltIn(true);
uniqueOrExistingFlow.setAlias("User creation or linking");
uniqueOrExistingFlow.setDescription("Flow for the existing/non-existing user alternatives");
uniqueOrExistingFlow.setProviderId("basic-flow");
uniqueOrExistingFlow = realm.addAuthenticationFlow(uniqueOrExistingFlow);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(firstBrokerLogin.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setFlowId(uniqueOrExistingFlow.getId());
execution.setPriority(20);
execution.setAuthenticatorFlow(true);
realm.addAuthenticatorExecution(execution);
AuthenticatorConfigModel createUserIfUniqueConfig = new AuthenticatorConfigModel();
createUserIfUniqueConfig.setAlias(IDP_CREATE_UNIQUE_USER_CONFIG_ALIAS);
config = new HashMap<>();
config.put("require.password.update.after.registration", "false");
createUserIfUniqueConfig.setConfig(config);
createUserIfUniqueConfig = realm.addAuthenticatorConfig(createUserIfUniqueConfig);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(uniqueOrExistingFlow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
execution.setAuthenticator("idp-create-user-if-unique");
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
execution.setAuthenticatorConfig(createUserIfUniqueConfig.getId());
realm.addAuthenticatorExecution(execution);
AuthenticationFlowModel linkExistingAccountFlow = new AuthenticationFlowModel();
linkExistingAccountFlow.setTopLevel(false);
linkExistingAccountFlow.setBuiltIn(true);
linkExistingAccountFlow.setAlias(FIRST_BROKER_LOGIN_HANDLE_EXISTING_SUBFLOW);
linkExistingAccountFlow.setDescription("Handle what to do if there is existing account with same email/username like authenticated identity provider");
linkExistingAccountFlow.setProviderId("basic-flow");
linkExistingAccountFlow = realm.addAuthenticationFlow(linkExistingAccountFlow);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(uniqueOrExistingFlow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
execution.setFlowId(linkExistingAccountFlow.getId());
execution.setPriority(20);
execution.setAuthenticatorFlow(true);
realm.addAuthenticatorExecution(execution);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(linkExistingAccountFlow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator("idp-confirm-link");
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
realm.addAuthenticatorExecution(execution);
AuthenticationFlowModel accountVerificationOptions = new AuthenticationFlowModel();
accountVerificationOptions.setTopLevel(false);
accountVerificationOptions.setBuiltIn(true);
accountVerificationOptions.setAlias("Account verification options");
accountVerificationOptions.setDescription("Method with which to verity the existing account");
accountVerificationOptions.setProviderId("basic-flow");
accountVerificationOptions = realm.addAuthenticationFlow(accountVerificationOptions);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(linkExistingAccountFlow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setFlowId(accountVerificationOptions.getId());
execution.setPriority(20);
execution.setAuthenticatorFlow(true);
realm.addAuthenticatorExecution(execution);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(accountVerificationOptions.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
execution.setAuthenticator("idp-email-verification");
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
realm.addAuthenticatorExecution(execution);
AuthenticationFlowModel verifyByReauthenticationAccountFlow = new AuthenticationFlowModel();
verifyByReauthenticationAccountFlow.setTopLevel(false);
verifyByReauthenticationAccountFlow.setBuiltIn(true);
verifyByReauthenticationAccountFlow.setAlias("Verify Existing Account by Re-authentication");
verifyByReauthenticationAccountFlow.setDescription("Reauthentication of existing account");
verifyByReauthenticationAccountFlow.setProviderId("basic-flow");
verifyByReauthenticationAccountFlow = realm.addAuthenticationFlow(verifyByReauthenticationAccountFlow);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(accountVerificationOptions.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
execution.setFlowId(verifyByReauthenticationAccountFlow.getId());
execution.setPriority(20);
execution.setAuthenticatorFlow(true);
realm.addAuthenticatorExecution(execution);
// password + otp
execution = new AuthenticationExecutionModel();
execution.setParentFlow(verifyByReauthenticationAccountFlow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator("idp-username-password-form");
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
realm.addAuthenticatorExecution(execution);
AuthenticationFlowModel conditionalOTP = new AuthenticationFlowModel();
conditionalOTP.setTopLevel(false);
conditionalOTP.setBuiltIn(true);
conditionalOTP.setAlias("First broker login - Conditional OTP");
conditionalOTP.setDescription("Flow to determine if the OTP is required for the authentication");
conditionalOTP.setProviderId("basic-flow");
conditionalOTP = realm.addAuthenticationFlow(conditionalOTP);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(verifyByReauthenticationAccountFlow.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.CONDITIONAL);
if (migrate) {
// Try to read OTP requirement from browser flow
AuthenticationFlowModel browserFlow = realm.getBrowserFlow();
if (browserFlow == null) {
browserFlow = realm.getFlowByAlias(DefaultAuthenticationFlows.BROWSER_FLOW);
}
List<AuthenticationExecutionModel> browserExecutions = new LinkedList<>();
KeycloakModelUtils.deepFindAuthenticationExecutions(realm, browserFlow, browserExecutions);
for (AuthenticationExecutionModel browserExecution : browserExecutions) {
if (browserExecution.isAuthenticatorFlow()) {
if (realm.getAuthenticationExecutionsStream(browserExecution.getFlowId()).anyMatch(e -> e.getAuthenticator().equals("auth-otp-form"))) {
execution.setRequirement(browserExecution.getRequirement());
}
}
}
}
execution.setFlowId(conditionalOTP.getId());
execution.setPriority(20);
execution.setAuthenticatorFlow(true);
realm.addAuthenticatorExecution(execution);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(conditionalOTP.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator("conditional-user-configured");
execution.setPriority(10);
execution.setAuthenticatorFlow(false);
realm.addAuthenticatorExecution(execution);
execution = new AuthenticationExecutionModel();
execution.setParentFlow(conditionalOTP.getId());
execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
execution.setAuthenticator("auth-otp-form");
execution.setPriority(20);
execution.setAuthenticatorFlow(false);
realm.addAuthenticatorExecution(execution);
}
use of org.keycloak.models.AuthenticatorConfigModel in project keycloak by keycloak.
the class IdpReviewProfileAuthenticator method requiresUpdateProfilePage.
protected boolean requiresUpdateProfilePage(AuthenticationFlowContext context, SerializedBrokeredIdentityContext userCtx, BrokeredIdentityContext brokerContext) {
String enforceUpdateProfile = context.getAuthenticationSession().getAuthNote(ENFORCE_UPDATE_PROFILE);
if (Boolean.parseBoolean(enforceUpdateProfile)) {
return true;
}
String updateProfileFirstLogin;
AuthenticatorConfigModel authenticatorConfig = context.getAuthenticatorConfig();
if (authenticatorConfig == null || !authenticatorConfig.getConfig().containsKey(IdpReviewProfileAuthenticatorFactory.UPDATE_PROFILE_ON_FIRST_LOGIN)) {
updateProfileFirstLogin = IdentityProviderRepresentation.UPFLM_MISSING;
} else {
updateProfileFirstLogin = authenticatorConfig.getConfig().get(IdpReviewProfileAuthenticatorFactory.UPDATE_PROFILE_ON_FIRST_LOGIN);
}
if (IdentityProviderRepresentation.UPFLM_MISSING.equals(updateProfileFirstLogin)) {
try {
UserProfileProvider profileProvider = context.getSession().getProvider(UserProfileProvider.class);
profileProvider.create(UserProfileContext.IDP_REVIEW, userCtx.getAttributes()).validate();
return false;
} catch (ValidationException pve) {
return true;
}
} else {
return IdentityProviderRepresentation.UPFLM_ON.equals(updateProfileFirstLogin);
}
}
use of org.keycloak.models.AuthenticatorConfigModel in project keycloak by keycloak.
the class RegistrationRecaptcha method buildPage.
@Override
public void buildPage(FormContext context, LoginFormsProvider form) {
AuthenticatorConfigModel captchaConfig = context.getAuthenticatorConfig();
String userLanguageTag = context.getSession().getContext().resolveLocale(context.getUser()).toLanguageTag();
if (captchaConfig == null || captchaConfig.getConfig() == null || captchaConfig.getConfig().get(SITE_KEY) == null || captchaConfig.getConfig().get(SITE_SECRET) == null) {
form.addError(new FormMessage(null, Messages.RECAPTCHA_NOT_CONFIGURED));
return;
}
String siteKey = captchaConfig.getConfig().get(SITE_KEY);
form.setAttribute("recaptchaRequired", true);
form.setAttribute("recaptchaSiteKey", siteKey);
form.addScript("https://www." + getRecaptchaDomain(captchaConfig) + "/recaptcha/api.js?hl=" + userLanguageTag);
}
use of org.keycloak.models.AuthenticatorConfigModel in project keycloak by keycloak.
the class RegistrationRecaptcha method validate.
@Override
public void validate(ValidationContext context) {
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
List<FormMessage> errors = new ArrayList<>();
boolean success = false;
context.getEvent().detail(Details.REGISTER_METHOD, "form");
String captcha = formData.getFirst(G_RECAPTCHA_RESPONSE);
if (!Validation.isBlank(captcha)) {
AuthenticatorConfigModel captchaConfig = context.getAuthenticatorConfig();
String secret = captchaConfig.getConfig().get(SITE_SECRET);
success = validateRecaptcha(context, success, captcha, secret);
}
if (success) {
context.success();
} else {
errors.add(new FormMessage(null, Messages.RECAPTCHA_FAILED));
formData.remove(G_RECAPTCHA_RESPONSE);
context.error(Errors.INVALID_REGISTRATION);
context.validationError(formData, errors);
context.excludeOtherErrors();
return;
}
}
Aggregations