Search in sources :

Example 1 with FormMessage

use of org.keycloak.models.utils.FormMessage in project keycloak by keycloak.

the class FormAuthenticationFlow method processAction.

@Override
public Response processAction(String actionExecution) {
    if (!actionExecution.equals(formExecution.getId())) {
        throw new AuthenticationFlowException("action is not current execution", AuthenticationFlowError.INTERNAL_ERROR);
    }
    Map<String, AuthenticationSessionModel.ExecutionStatus> executionStatus = new HashMap<>();
    List<FormAction> requiredActions = new LinkedList<>();
    List<ValidationContextImpl> successes = new LinkedList<>();
    List<ValidationContextImpl> errors = new LinkedList<>();
    for (AuthenticationExecutionModel formActionExecution : formActionExecutions) {
        if (!formActionExecution.isEnabled()) {
            executionStatus.put(formActionExecution.getId(), AuthenticationSessionModel.ExecutionStatus.SKIPPED);
            continue;
        }
        FormActionFactory factory = (FormActionFactory) processor.getSession().getKeycloakSessionFactory().getProviderFactory(FormAction.class, formActionExecution.getAuthenticator());
        FormAction action = factory.create(processor.getSession());
        UserModel authUser = processor.getAuthenticationSession().getAuthenticatedUser();
        if (action.requiresUser() && authUser == null) {
            throw new AuthenticationFlowException("form action: " + formExecution.getAuthenticator() + " requires user", AuthenticationFlowError.UNKNOWN_USER);
        }
        boolean configuredFor = false;
        if (action.requiresUser() && authUser != null) {
            configuredFor = action.configuredFor(processor.getSession(), processor.getRealm(), authUser);
            if (!configuredFor) {
                if (formActionExecution.isRequired()) {
                    if (factory.isUserSetupAllowed()) {
                        AuthenticationProcessor.logger.debugv("authenticator SETUP_REQUIRED: {0}", formExecution.getAuthenticator());
                        executionStatus.put(formActionExecution.getId(), AuthenticationSessionModel.ExecutionStatus.SETUP_REQUIRED);
                        requiredActions.add(action);
                        continue;
                    } else {
                        throw new AuthenticationFlowException(AuthenticationFlowError.CREDENTIAL_SETUP_REQUIRED);
                    }
                } else if (formActionExecution.isConditional()) {
                    executionStatus.put(formActionExecution.getId(), AuthenticationSessionModel.ExecutionStatus.SKIPPED);
                    continue;
                }
            }
        }
        ValidationContextImpl result = new ValidationContextImpl(formActionExecution, action);
        action.validate(result);
        if (result.success) {
            executionStatus.put(formActionExecution.getId(), AuthenticationSessionModel.ExecutionStatus.SUCCESS);
            successes.add(result);
        } else {
            executionStatus.put(formActionExecution.getId(), AuthenticationSessionModel.ExecutionStatus.CHALLENGED);
            errors.add(result);
        }
    }
    if (!errors.isEmpty()) {
        processor.logFailure();
        List<FormMessage> messages = new LinkedList<>();
        Set<String> fields = new HashSet<>();
        for (ValidationContextImpl v : errors) {
            for (FormMessage m : v.errors) {
                if (!fields.contains(m.getField())) {
                    if (v.excludeOthers) {
                        fields.clear();
                        messages.clear();
                    }
                    fields.add(m.getField());
                    messages.add(m);
                    if (v.excludeOthers) {
                        break;
                    }
                }
            }
        }
        ValidationContextImpl first = errors.get(0);
        first.getEvent().error(first.error);
        return renderForm(first.formData, messages);
    }
    for (ValidationContextImpl context : successes) {
        context.action.success(context);
    }
    // set status and required actions only if form is fully successful
    for (Map.Entry<String, AuthenticationSessionModel.ExecutionStatus> entry : executionStatus.entrySet()) {
        processor.getAuthenticationSession().setExecutionStatus(entry.getKey(), entry.getValue());
    }
    for (FormAction action : requiredActions) {
        action.setRequiredActions(processor.getSession(), processor.getRealm(), processor.getAuthenticationSession().getAuthenticatedUser());
    }
    processor.getAuthenticationSession().setExecutionStatus(actionExecution, AuthenticationSessionModel.ExecutionStatus.SUCCESS);
    processor.getAuthenticationSession().removeAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION);
    return null;
}
Also used : HashMap(java.util.HashMap) AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) LinkedList(java.util.LinkedList) UserModel(org.keycloak.models.UserModel) FormMessage(org.keycloak.models.utils.FormMessage) HashMap(java.util.HashMap) Map(java.util.Map) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) HashSet(java.util.HashSet)

Example 2 with FormMessage

use of org.keycloak.models.utils.FormMessage in project keycloak by keycloak.

the class X509ClientCertificateAuthenticator method createResponse.

private Response createResponse(AuthenticationFlowContext context, String subjectDN, boolean isUserEnabled, String errorMessage, Object[] errorParameters) {
    LoginFormsProvider form = context.form();
    if (errorMessage != null && errorMessage.trim().length() > 0) {
        List<FormMessage> errors = new LinkedList<>();
        errors.add(new FormMessage(errorMessage));
        if (errorParameters != null) {
            for (Object errorParameter : errorParameters) {
                if (errorParameter == null)
                    continue;
                for (String part : errorParameter.toString().split("\n")) {
                    errors.add(new FormMessage(part));
                }
            }
        }
        form.setErrors(errors);
    }
    MultivaluedMap<String, String> formData = new MultivaluedHashMap<>();
    formData.add("username", context.getUser() != null ? context.getUser().getUsername() : "unknown user");
    formData.add("subjectDN", subjectDN);
    formData.add("isUserEnabled", String.valueOf(isUserEnabled));
    form.setFormData(formData);
    return form.createX509ConfirmPage();
}
Also used : MultivaluedHashMap(javax.ws.rs.core.MultivaluedHashMap) LoginFormsProvider(org.keycloak.forms.login.LoginFormsProvider) FormMessage(org.keycloak.models.utils.FormMessage) LinkedList(java.util.LinkedList)

Example 3 with FormMessage

use of org.keycloak.models.utils.FormMessage in project keycloak by keycloak.

the class UpdateTotp method processAction.

@Override
public void processAction(RequiredActionContext context) {
    EventBuilder event = context.getEvent();
    event.event(EventType.UPDATE_TOTP);
    MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
    String challengeResponse = formData.getFirst("totp");
    String totpSecret = formData.getFirst("totpSecret");
    String mode = formData.getFirst("mode");
    String userLabel = formData.getFirst("userLabel");
    OTPPolicy policy = context.getRealm().getOTPPolicy();
    OTPCredentialModel credentialModel = OTPCredentialModel.createFromPolicy(context.getRealm(), totpSecret, userLabel);
    if (Validation.isBlank(challengeResponse)) {
        Response challenge = context.form().setAttribute("mode", mode).addError(new FormMessage(Validation.FIELD_OTP_CODE, Messages.MISSING_TOTP)).createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
        context.challenge(challenge);
        return;
    } else if (!validateOTPCredential(context, challengeResponse, credentialModel, policy)) {
        Response challenge = context.form().setAttribute("mode", mode).addError(new FormMessage(Validation.FIELD_OTP_CODE, Messages.INVALID_TOTP)).createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
        context.challenge(challenge);
        return;
    }
    OTPCredentialProvider otpCredentialProvider = (OTPCredentialProvider) context.getSession().getProvider(CredentialProvider.class, "keycloak-otp");
    final Stream<CredentialModel> otpCredentials = (otpCredentialProvider.isConfiguredFor(context.getRealm(), context.getUser())) ? context.getSession().userCredentialManager().getStoredCredentialsByTypeStream(context.getRealm(), context.getUser(), OTPCredentialModel.TYPE) : Stream.empty();
    if (otpCredentials.count() >= 1 && Validation.isBlank(userLabel)) {
        Response challenge = context.form().setAttribute("mode", mode).addError(new FormMessage(Validation.FIELD_OTP_LABEL, Messages.MISSING_TOTP_DEVICE_NAME)).createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
        context.challenge(challenge);
        return;
    }
    if (!CredentialHelper.createOTPCredential(context.getSession(), context.getRealm(), context.getUser(), challengeResponse, credentialModel)) {
        Response challenge = context.form().setAttribute("mode", mode).addError(new FormMessage(Validation.FIELD_OTP_CODE, Messages.INVALID_TOTP)).createResponse(UserModel.RequiredAction.CONFIGURE_TOTP);
        context.challenge(challenge);
        return;
    }
    context.success();
}
Also used : Response(javax.ws.rs.core.Response) EventBuilder(org.keycloak.events.EventBuilder) CredentialModel(org.keycloak.credential.CredentialModel) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) OTPCredentialProvider(org.keycloak.credential.OTPCredentialProvider) CredentialProvider(org.keycloak.credential.CredentialProvider) OTPCredentialModel(org.keycloak.models.credential.OTPCredentialModel) OTPPolicy(org.keycloak.models.OTPPolicy) FormMessage(org.keycloak.models.utils.FormMessage) OTPCredentialProvider(org.keycloak.credential.OTPCredentialProvider)

Example 4 with FormMessage

use of org.keycloak.models.utils.FormMessage in project keycloak by keycloak.

the class AccountFormService method forwardToPage.

private Response forwardToPage(String path, AccountPages page) {
    if (auth != null) {
        try {
            auth.require(AccountRoles.MANAGE_ACCOUNT);
        } catch (ForbiddenException e) {
            return session.getProvider(LoginFormsProvider.class).setError(Messages.NO_ACCESS).createErrorPage(Response.Status.FORBIDDEN);
        }
        setReferrerOnPage();
        UserSessionModel userSession = auth.getSession();
        String tabId = session.getContext().getUri().getQueryParameters().getFirst(org.keycloak.models.Constants.TAB_ID);
        if (tabId != null) {
            AuthenticationSessionModel authSession = new AuthenticationSessionManager(session).getAuthenticationSessionByIdAndClient(realm, userSession.getId(), client, tabId);
            if (authSession != null) {
                String forwardedError = authSession.getAuthNote(ACCOUNT_MGMT_FORWARDED_ERROR_NOTE);
                if (forwardedError != null) {
                    try {
                        FormMessage errorMessage = JsonSerialization.readValue(forwardedError, FormMessage.class);
                        account.setError(Response.Status.INTERNAL_SERVER_ERROR, errorMessage.getMessage(), errorMessage.getParameters());
                        authSession.removeAuthNote(ACCOUNT_MGMT_FORWARDED_ERROR_NOTE);
                    } catch (IOException ioe) {
                        throw new RuntimeException(ioe);
                    }
                }
            }
        }
        String locale = session.getContext().getUri().getQueryParameters().getFirst(LocaleSelectorProvider.KC_LOCALE_PARAM);
        if (locale != null) {
            LocaleUpdaterProvider updater = session.getProvider(LocaleUpdaterProvider.class);
            updater.updateUsersLocale(auth.getUser(), locale);
        }
        return account.createResponse(page);
    } else {
        return login(path);
    }
}
Also used : AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) ForbiddenException(org.keycloak.services.ForbiddenException) LoginFormsProvider(org.keycloak.forms.login.LoginFormsProvider) UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) LocaleUpdaterProvider(org.keycloak.locale.LocaleUpdaterProvider) IOException(java.io.IOException) FormMessage(org.keycloak.models.utils.FormMessage)

Example 5 with FormMessage

use of org.keycloak.models.utils.FormMessage in project keycloak by keycloak.

the class IdentityBrokerService method redirectToAccountErrorPage.

private Response redirectToAccountErrorPage(AuthenticationSessionModel authSession, String message, Object... parameters) {
    fireErrorEvent(message);
    FormMessage errorMessage = new FormMessage(message, parameters);
    try {
        String serializedError = JsonSerialization.writeValueAsString(errorMessage);
        authSession.setAuthNote(AccountFormService.ACCOUNT_MGMT_FORWARDED_ERROR_NOTE, serializedError);
    } catch (IOException ioe) {
        throw new RuntimeException(ioe);
    }
    URI accountServiceUri = UriBuilder.fromUri(authSession.getRedirectUri()).queryParam(Constants.TAB_ID, authSession.getTabId()).build();
    return Response.status(302).location(accountServiceUri).build();
}
Also used : IOException(java.io.IOException) FormMessage(org.keycloak.models.utils.FormMessage) URI(java.net.URI)

Aggregations

FormMessage (org.keycloak.models.utils.FormMessage)20 Response (javax.ws.rs.core.Response)5 IOException (java.io.IOException)4 EventBuilder (org.keycloak.events.EventBuilder)4 LoginFormsProvider (org.keycloak.forms.login.LoginFormsProvider)3 UserModel (org.keycloak.models.UserModel)3 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 WebApplicationException (javax.ws.rs.WebApplicationException)2 AuthenticatorConfigModel (org.keycloak.models.AuthenticatorConfigModel)2 RealmModel (org.keycloak.models.RealmModel)2 MessageBean (org.keycloak.theme.beans.MessageBean)2 MessagesPerFieldBean (org.keycloak.theme.beans.MessagesPerFieldBean)2 URI (java.net.URI)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Locale (java.util.Locale)1 Map (java.util.Map)1