Search in sources :

Example 21 with AuthenticatorConfigModel

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);
}
Also used : RealmModel(org.keycloak.models.RealmModel) HashMap(java.util.HashMap) AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel) AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel) Before(org.junit.Before)

Example 22 with AuthenticatorConfigModel

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);
}
Also used : AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel) AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel)

Example 23 with AuthenticatorConfigModel

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);
    }
}
Also used : ValidationException(org.keycloak.userprofile.ValidationException) UserProfileProvider(org.keycloak.userprofile.UserProfileProvider) AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel)

Example 24 with AuthenticatorConfigModel

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);
}
Also used : AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel) FormMessage(org.keycloak.models.utils.FormMessage)

Example 25 with AuthenticatorConfigModel

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;
    }
}
Also used : ArrayList(java.util.ArrayList) AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel) FormMessage(org.keycloak.models.utils.FormMessage)

Aggregations

AuthenticatorConfigModel (org.keycloak.models.AuthenticatorConfigModel)28 AuthenticationExecutionModel (org.keycloak.models.AuthenticationExecutionModel)13 AuthenticationFlowModel (org.keycloak.models.AuthenticationFlowModel)9 RealmModel (org.keycloak.models.RealmModel)9 HashMap (java.util.HashMap)6 NotFoundException (javax.ws.rs.NotFoundException)5 Path (javax.ws.rs.Path)5 NoCache (org.jboss.resteasy.annotations.cache.NoCache)5 List (java.util.List)4 Consumes (javax.ws.rs.Consumes)4 Response (javax.ws.rs.core.Response)4 KeycloakSession (org.keycloak.models.KeycloakSession)4 UserModel (org.keycloak.models.UserModel)4 Map (java.util.Map)3 Optional (java.util.Optional)3 POST (javax.ws.rs.POST)3 Before (org.junit.Before)3 Authenticator (org.keycloak.authentication.Authenticator)3 Collections (java.util.Collections)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2