Search in sources :

Example 6 with AuthenticationFlowModel

use of org.keycloak.models.AuthenticationFlowModel in project keycloak by keycloak.

the class DefaultAuthenticationFlows method addIdentityProviderAuthenticator.

public static void addIdentityProviderAuthenticator(RealmModel realm, String defaultProvider) {
    String browserFlowId = realm.getAuthenticationFlowsStream().filter(f -> Objects.equals(f.getAlias(), DefaultAuthenticationFlows.BROWSER_FLOW)).map(AuthenticationFlowModel::getId).findFirst().orElse(null);
    if (browserFlowId != null) {
        if (realm.getAuthenticationExecutionsStream(browserFlowId).anyMatch(e -> Objects.equals(e.getAuthenticator(), "identity-provider-redirector")))
            return;
        AuthenticationExecutionModel execution;
        execution = new AuthenticationExecutionModel();
        execution.setParentFlow(browserFlowId);
        execution.setRequirement(AuthenticationExecutionModel.Requirement.ALTERNATIVE);
        execution.setAuthenticator("identity-provider-redirector");
        execution.setPriority(25);
        execution.setAuthenticatorFlow(false);
        if (defaultProvider != null) {
            AuthenticatorConfigModel configModel = new AuthenticatorConfigModel();
            Map<String, String> config = new HashMap<>();
            config.put("defaultProvider", defaultProvider);
            configModel.setConfig(config);
            configModel.setAlias(defaultProvider);
            configModel = realm.addAuthenticatorConfig(configModel);
            execution.setAuthenticatorConfig(configModel.getId());
        }
        realm.addAuthenticatorExecution(execution);
    }
}
Also used : IdentityProviderRepresentation(org.keycloak.representations.idm.IdentityProviderRepresentation) RequiredCredentialModel(org.keycloak.models.RequiredCredentialModel) java.util(java.util) RealmModel(org.keycloak.models.RealmModel) AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel) AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel) AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel)

Example 7 with AuthenticationFlowModel

use of org.keycloak.models.AuthenticationFlowModel in project keycloak by keycloak.

the class DefaultAuthenticationFlows method directGrantFlow.

public static void directGrantFlow(RealmModel realm, boolean migrate) {
    AuthenticationFlowModel grant = new AuthenticationFlowModel();
    grant.setAlias(DIRECT_GRANT_FLOW);
    grant.setDescription("OpenID Connect Resource Owner Grant");
    grant.setProviderId("basic-flow");
    grant.setTopLevel(true);
    grant.setBuiltIn(true);
    grant = realm.addAuthenticationFlow(grant);
    realm.setDirectGrantFlow(grant);
    // username
    AuthenticationExecutionModel execution = new AuthenticationExecutionModel();
    execution.setParentFlow(grant.getId());
    execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
    execution.setAuthenticator("direct-grant-validate-username");
    execution.setPriority(10);
    execution.setAuthenticatorFlow(false);
    realm.addAuthenticatorExecution(execution);
    // password
    execution = new AuthenticationExecutionModel();
    execution.setParentFlow(grant.getId());
    execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
    if (migrate && !hasCredentialType(realm, RequiredCredentialModel.PASSWORD.getType())) {
        execution.setRequirement(AuthenticationExecutionModel.Requirement.DISABLED);
    }
    execution.setAuthenticator("direct-grant-validate-password");
    execution.setPriority(20);
    execution.setAuthenticatorFlow(false);
    realm.addAuthenticatorExecution(execution);
    // otp
    AuthenticationFlowModel conditionalOTP = new AuthenticationFlowModel();
    conditionalOTP.setTopLevel(false);
    conditionalOTP.setBuiltIn(true);
    conditionalOTP.setAlias("Direct Grant - 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(grant.getId());
    execution.setRequirement(AuthenticationExecutionModel.Requirement.CONDITIONAL);
    if (migrate && hasCredentialType(realm, RequiredCredentialModel.TOTP.getType())) {
        execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
    }
    execution.setFlowId(conditionalOTP.getId());
    execution.setPriority(30);
    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("direct-grant-validate-otp");
    execution.setPriority(20);
    execution.setAuthenticatorFlow(false);
    realm.addAuthenticatorExecution(execution);
}
Also used : AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel)

Example 8 with AuthenticationFlowModel

use of org.keycloak.models.AuthenticationFlowModel in project keycloak by keycloak.

the class DefaultAuthenticationFlows method dockerAuthenticationFlow.

public static void dockerAuthenticationFlow(final RealmModel realm) {
    AuthenticationFlowModel dockerAuthFlow = new AuthenticationFlowModel();
    dockerAuthFlow.setAlias(DOCKER_AUTH);
    dockerAuthFlow.setDescription("Used by Docker clients to authenticate against the IDP");
    dockerAuthFlow.setProviderId("basic-flow");
    dockerAuthFlow.setTopLevel(true);
    dockerAuthFlow.setBuiltIn(true);
    dockerAuthFlow = realm.addAuthenticationFlow(dockerAuthFlow);
    realm.setDockerAuthenticationFlow(dockerAuthFlow);
    AuthenticationExecutionModel execution = new AuthenticationExecutionModel();
    execution.setParentFlow(dockerAuthFlow.getId());
    execution.setRequirement(AuthenticationExecutionModel.Requirement.REQUIRED);
    execution.setAuthenticator("docker-http-basic-authenticator");
    execution.setPriority(10);
    execution.setAuthenticatorFlow(false);
    realm.addAuthenticatorExecution(execution);
}
Also used : AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel)

Example 9 with AuthenticationFlowModel

use of org.keycloak.models.AuthenticationFlowModel in project keycloak by keycloak.

the class IdentityBrokerService method browserAuthentication.

protected Response browserAuthentication(AuthenticationSessionModel authSession, String errorMessage) {
    this.event.event(EventType.LOGIN);
    AuthenticationFlowModel flow = AuthenticationFlowResolver.resolveBrowserFlow(authSession);
    String flowId = flow.getId();
    AuthenticationProcessor processor = new AuthenticationProcessor();
    processor.setAuthenticationSession(authSession).setFlowPath(LoginActionsService.AUTHENTICATE_PATH).setFlowId(flowId).setBrowserFlow(true).setConnection(clientConnection).setEventBuilder(event).setRealm(realmModel).setSession(session).setUriInfo(session.getContext().getUri()).setRequest(request);
    if (errorMessage != null)
        processor.setForwardedErrorMessage(new FormMessage(null, errorMessage));
    try {
        CacheControlUtil.noBackButtonCacheControlHeader();
        return processor.authenticate();
    } catch (Exception e) {
        return processor.handleBrowserException(e);
    }
}
Also used : AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel) AuthenticationProcessor(org.keycloak.authentication.AuthenticationProcessor) FormMessage(org.keycloak.models.utils.FormMessage) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) WebApplicationException(javax.ws.rs.WebApplicationException) IOException(java.io.IOException) IdentityBrokerException(org.keycloak.broker.provider.IdentityBrokerException) OAuthErrorException(org.keycloak.OAuthErrorException) NotFoundException(javax.ws.rs.NotFoundException) ErrorPageException(org.keycloak.services.ErrorPageException)

Example 10 with AuthenticationFlowModel

use of org.keycloak.models.AuthenticationFlowModel in project keycloak by keycloak.

the class LoginActionsService method brokerLoginFlow.

protected Response brokerLoginFlow(String authSessionId, String code, String execution, String clientId, String tabId, String flowPath) {
    boolean firstBrokerLogin = flowPath.equals(FIRST_BROKER_LOGIN_PATH);
    EventType eventType = firstBrokerLogin ? EventType.IDENTITY_PROVIDER_FIRST_LOGIN : EventType.IDENTITY_PROVIDER_POST_LOGIN;
    event.event(eventType);
    SessionCodeChecks checks = checksForCode(authSessionId, code, execution, clientId, tabId, flowPath);
    if (!checks.verifyActiveAndValidAction(AuthenticationSessionModel.Action.AUTHENTICATE.name(), ClientSessionCode.ActionType.LOGIN)) {
        return checks.getResponse();
    }
    event.detail(Details.CODE_ID, code);
    final AuthenticationSessionModel authSession = checks.getAuthenticationSession();
    processLocaleParam(authSession);
    String noteKey = firstBrokerLogin ? AbstractIdpAuthenticator.BROKERED_CONTEXT_NOTE : PostBrokerLoginConstants.PBL_BROKERED_IDENTITY_CONTEXT;
    SerializedBrokeredIdentityContext serializedCtx = SerializedBrokeredIdentityContext.readFromAuthenticationSession(authSession, noteKey);
    if (serializedCtx == null) {
        ServicesLogger.LOGGER.notFoundSerializedCtxInClientSession(noteKey);
        throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, "Not found serialized context in authenticationSession."));
    }
    BrokeredIdentityContext brokerContext = serializedCtx.deserialize(session, authSession);
    final String identityProviderAlias = brokerContext.getIdpConfig().getAlias();
    String flowId = firstBrokerLogin ? brokerContext.getIdpConfig().getFirstBrokerLoginFlowId() : brokerContext.getIdpConfig().getPostBrokerLoginFlowId();
    if (flowId == null) {
        ServicesLogger.LOGGER.flowNotConfigForIDP(identityProviderAlias);
        throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, "Flow not configured for identity provider"));
    }
    AuthenticationFlowModel brokerLoginFlow = realm.getAuthenticationFlowById(flowId);
    if (brokerLoginFlow == null) {
        ServicesLogger.LOGGER.flowNotFoundForIDP(flowId, identityProviderAlias);
        throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, "Flow not found for identity provider"));
    }
    event.detail(Details.IDENTITY_PROVIDER, identityProviderAlias).detail(Details.IDENTITY_PROVIDER_USERNAME, brokerContext.getUsername());
    AuthenticationProcessor processor = new AuthenticationProcessor() {

        @Override
        public Response authenticateOnly() throws AuthenticationFlowException {
            Response challenge = super.authenticateOnly();
            if (challenge != null) {
                if ("true".equals(authenticationSession.getAuthNote(FORWARDED_PASSIVE_LOGIN))) {
                    // forwarded passive login is incompatible with challenges created by the broker flows.
                    logger.errorf("Challenge encountered when executing %s flow. Auth requests with prompt=none are incompatible with challenges", flowPath);
                    LoginProtocol protocol = session.getProvider(LoginProtocol.class, authSession.getProtocol());
                    protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(session.getContext().getUri()).setEventBuilder(event);
                    return protocol.sendError(authSession, Error.PASSIVE_INTERACTION_REQUIRED);
                }
            }
            return challenge;
        }

        @Override
        protected Response authenticationComplete() {
            if (firstBrokerLogin) {
                authSession.setAuthNote(AbstractIdpAuthenticator.FIRST_BROKER_LOGIN_SUCCESS, identityProviderAlias);
            } else {
                String authStateNoteKey = PostBrokerLoginConstants.PBL_AUTH_STATE_PREFIX + identityProviderAlias;
                authSession.setAuthNote(authStateNoteKey, "true");
            }
            return redirectToAfterBrokerLoginEndpoint(authSession, firstBrokerLogin);
        }
    };
    return processFlow(checks.isActionRequest(), execution, authSession, flowPath, brokerLoginFlow, null, processor);
}
Also used : Response(javax.ws.rs.core.Response) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) WebApplicationException(javax.ws.rs.WebApplicationException) EventType(org.keycloak.events.EventType) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext) AuthenticationProcessor(org.keycloak.authentication.AuthenticationProcessor) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) LoginProtocol(org.keycloak.protocol.LoginProtocol) BrokeredIdentityContext(org.keycloak.broker.provider.BrokeredIdentityContext) SerializedBrokeredIdentityContext(org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext)

Aggregations

AuthenticationFlowModel (org.keycloak.models.AuthenticationFlowModel)60 AuthenticationExecutionModel (org.keycloak.models.AuthenticationExecutionModel)32 Path (javax.ws.rs.Path)14 RealmModel (org.keycloak.models.RealmModel)13 NoCache (org.jboss.resteasy.annotations.cache.NoCache)12 NotFoundException (javax.ws.rs.NotFoundException)9 AuthenticatorConfigModel (org.keycloak.models.AuthenticatorConfigModel)8 Consumes (javax.ws.rs.Consumes)7 POST (javax.ws.rs.POST)7 AuthenticationProcessor (org.keycloak.authentication.AuthenticationProcessor)7 BadRequestException (javax.ws.rs.BadRequestException)6 Produces (javax.ws.rs.Produces)6 Before (org.junit.Before)5 ClientModel (org.keycloak.models.ClientModel)5 HashMap (java.util.HashMap)4 GET (javax.ws.rs.GET)4 Response (javax.ws.rs.core.Response)3 IdentityProviderModel (org.keycloak.models.IdentityProviderModel)3 ModelException (org.keycloak.models.ModelException)3 ArrayList (java.util.ArrayList)2