Search in sources :

Example 1 with RequiredActionFactory

use of org.keycloak.authentication.RequiredActionFactory in project keycloak by keycloak.

the class AuthenticationManager method executeAction.

private static Response executeAction(KeycloakSession session, AuthenticationSessionModel authSession, RequiredActionProviderModel model, HttpRequest request, EventBuilder event, RealmModel realm, UserModel user, boolean kcActionExecution) {
    RequiredActionFactory factory = (RequiredActionFactory) session.getKeycloakSessionFactory().getProviderFactory(RequiredActionProvider.class, model.getProviderId());
    if (factory == null) {
        throw new RuntimeException("Unable to find factory for Required Action: " + model.getProviderId() + " did you forget to declare it in a META-INF/services file?");
    }
    RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, user, factory);
    RequiredActionProvider actionProvider = null;
    try {
        actionProvider = createRequiredAction(context);
    } catch (AuthenticationFlowException e) {
        if (e.getResponse() != null) {
            return e.getResponse();
        }
        throw e;
    }
    if (kcActionExecution) {
        if (actionProvider.initiatedActionSupport() == InitiatedActionSupport.NOT_SUPPORTED) {
            logger.debugv("Requested action {0} does not support being invoked with kc_action", factory.getId());
            setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.ERROR, authSession);
            return null;
        } else if (!model.isEnabled()) {
            logger.debugv("Requested action {0} is disabled and can't be invoked with kc_action", factory.getId());
            setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.ERROR, authSession);
            return null;
        } else {
            authSession.setClientNote(Constants.KC_ACTION_EXECUTING, factory.getId());
        }
    }
    actionProvider.requiredActionChallenge(context);
    if (context.getStatus() == RequiredActionContext.Status.FAILURE) {
        LoginProtocol protocol = context.getSession().getProvider(LoginProtocol.class, context.getAuthenticationSession().getProtocol());
        protocol.setRealm(context.getRealm()).setHttpHeaders(context.getHttpRequest().getHttpHeaders()).setUriInfo(context.getUriInfo()).setEventBuilder(event);
        Response response = protocol.sendError(context.getAuthenticationSession(), Error.CONSENT_DENIED);
        event.error(Errors.REJECTED_BY_USER);
        return response;
    } else if (context.getStatus() == RequiredActionContext.Status.CHALLENGE) {
        authSession.setAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION, model.getProviderId());
        return context.getChallenge();
    } else if (context.getStatus() == RequiredActionContext.Status.SUCCESS) {
        event.clone().event(EventType.CUSTOM_REQUIRED_ACTION).detail(Details.CUSTOM_REQUIRED_ACTION, factory.getId()).success();
        // don't have to perform the same action twice, so remove it from both the user and session required actions
        authSession.getAuthenticatedUser().removeRequiredAction(factory.getId());
        authSession.removeRequiredAction(factory.getId());
        setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.SUCCESS, authSession);
    }
    return null;
}
Also used : BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) Response(javax.ws.rs.core.Response) RequiredActionFactory(org.keycloak.authentication.RequiredActionFactory) DisplayTypeRequiredActionFactory(org.keycloak.authentication.DisplayTypeRequiredActionFactory) RequiredActionProvider(org.keycloak.authentication.RequiredActionProvider) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) RequiredActionContextResult(org.keycloak.authentication.RequiredActionContextResult) LoginProtocol(org.keycloak.protocol.LoginProtocol) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol)

Example 2 with RequiredActionFactory

use of org.keycloak.authentication.RequiredActionFactory in project keycloak by keycloak.

the class LoginActionsService method processRequireAction.

private Response processRequireAction(final String authSessionId, final String code, String action, String clientId, String tabId) {
    event.event(EventType.CUSTOM_REQUIRED_ACTION);
    SessionCodeChecks checks = checksForCode(authSessionId, code, action, clientId, tabId, REQUIRED_ACTION);
    if (!checks.verifyRequiredAction(action)) {
        return checks.getResponse();
    }
    AuthenticationSessionModel authSession = checks.getAuthenticationSession();
    processLocaleParam(authSession);
    if (!checks.isActionRequest()) {
        initLoginEvent(authSession);
        event.event(EventType.CUSTOM_REQUIRED_ACTION);
        return AuthenticationManager.nextActionAfterAuthentication(session, authSession, clientConnection, request, session.getContext().getUri(), event);
    }
    initLoginEvent(authSession);
    event.event(EventType.CUSTOM_REQUIRED_ACTION);
    event.detail(Details.CUSTOM_REQUIRED_ACTION, action);
    RequiredActionFactory factory = (RequiredActionFactory) session.getKeycloakSessionFactory().getProviderFactory(RequiredActionProvider.class, action);
    if (factory == null) {
        ServicesLogger.LOGGER.actionProviderNull();
        event.error(Errors.INVALID_CODE);
        throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, Messages.INVALID_CODE));
    }
    RequiredActionContextResult context = new RequiredActionContextResult(authSession, realm, event, session, request, authSession.getAuthenticatedUser(), factory) {

        @Override
        public void ignore() {
            throw new RuntimeException("Cannot call ignore within processAction()");
        }
    };
    RequiredActionProvider provider = null;
    try {
        provider = AuthenticationManager.createRequiredAction(context);
    } catch (AuthenticationFlowException e) {
        if (e.getResponse() != null) {
            return e.getResponse();
        }
        throw new WebApplicationException(ErrorPage.error(session, authSession, Response.Status.BAD_REQUEST, Messages.DISPLAY_UNSUPPORTED));
    }
    Response response;
    if (isCancelAppInitiatedAction(factory.getId(), authSession, context)) {
        provider.initiatedActionCanceled(session, authSession);
        AuthenticationManager.setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.CANCELLED, authSession);
        context.success();
    } else {
        provider.processAction(context);
    }
    if (action != null) {
        authSession.setAuthNote(AuthenticationProcessor.LAST_PROCESSED_EXECUTION, action);
    }
    if (context.getStatus() == RequiredActionContext.Status.SUCCESS) {
        event.clone().success();
        initLoginEvent(authSession);
        event.event(EventType.LOGIN);
        authSession.removeRequiredAction(factory.getId());
        authSession.getAuthenticatedUser().removeRequiredAction(factory.getId());
        authSession.removeAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION);
        AuthenticationManager.setKcActionStatus(factory.getId(), RequiredActionContext.KcActionStatus.SUCCESS, authSession);
        response = AuthenticationManager.nextActionAfterAuthentication(session, authSession, clientConnection, request, session.getContext().getUri(), event);
    } else if (context.getStatus() == RequiredActionContext.Status.CHALLENGE) {
        response = context.getChallenge();
    } else if (context.getStatus() == RequiredActionContext.Status.FAILURE) {
        response = interruptionResponse(context, authSession, action, Error.CONSENT_DENIED);
    } else {
        throw new RuntimeException("Unreachable");
    }
    return BrowserHistoryHelper.getInstance().saveResponseAndRedirect(session, authSession, response, true, request);
}
Also used : Response(javax.ws.rs.core.Response) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) RequiredActionFactory(org.keycloak.authentication.RequiredActionFactory) WebApplicationException(javax.ws.rs.WebApplicationException) RequiredActionProvider(org.keycloak.authentication.RequiredActionProvider) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) RequiredActionContextResult(org.keycloak.authentication.RequiredActionContextResult)

Example 3 with RequiredActionFactory

use of org.keycloak.authentication.RequiredActionFactory in project keycloak by keycloak.

the class AuthenticationManagementResource method getUnregisteredRequiredActions.

/**
 * Get unregistered required actions
 *
 * Returns a stream of unregistered required actions.
 */
@Path("unregistered-required-actions")
@GET
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public Stream<Map<String, String>> getUnregisteredRequiredActions() {
    auth.realm().requireViewRealm();
    Set<String> providerIds = realm.getRequiredActionProvidersStream().map(RequiredActionProviderModel::getProviderId).collect(Collectors.toSet());
    return session.getKeycloakSessionFactory().getProviderFactoriesStream(RequiredActionProvider.class).filter(factory -> !providerIds.contains(factory.getId())).map(factory -> {
        RequiredActionFactory r = (RequiredActionFactory) factory;
        Map<String, String> m = new HashMap<>();
        m.put("name", r.getDisplayText());
        m.put("providerId", r.getId());
        return m;
    });
}
Also used : ConfigPropertyRepresentation(org.keycloak.representations.idm.ConfigPropertyRepresentation) ResourceType(org.keycloak.events.admin.ResourceType) Produces(javax.ws.rs.Produces) RequiredActionFactory(org.keycloak.authentication.RequiredActionFactory) Path(javax.ws.rs.Path) ClientAuthenticatorFactory(org.keycloak.authentication.ClientAuthenticatorFactory) DefaultAuthenticationFlows(org.keycloak.models.utils.DefaultAuthenticationFlows) RepresentationToModel(org.keycloak.models.utils.RepresentationToModel) MediaType(javax.ws.rs.core.MediaType) Consumes(javax.ws.rs.Consumes) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) AuthenticationExecutionRepresentation(org.keycloak.representations.idm.AuthenticationExecutionRepresentation) FormAuthenticator(org.keycloak.authentication.FormAuthenticator) BadRequestException(javax.ws.rs.BadRequestException) UriBuilder(javax.ws.rs.core.UriBuilder) DELETE(javax.ws.rs.DELETE) RealmModel(org.keycloak.models.RealmModel) NOT_FOUND(javax.ws.rs.core.Response.Status.NOT_FOUND) CredentialHelper(org.keycloak.utils.CredentialHelper) Set(java.util.Set) Collectors(java.util.stream.Collectors) NotFoundException(javax.ws.rs.NotFoundException) ReservedCharValidator(org.keycloak.utils.ReservedCharValidator) Objects(java.util.Objects) ClientAuthenticator(org.keycloak.authentication.ClientAuthenticator) ModelToRepresentation(org.keycloak.models.utils.ModelToRepresentation) List(java.util.List) Stream(java.util.stream.Stream) Response(javax.ws.rs.core.Response) Optional(java.util.Optional) RequiredActionProviderModel(org.keycloak.models.RequiredActionProviderModel) OperationType(org.keycloak.events.admin.OperationType) PathParam(javax.ws.rs.PathParam) AuthenticationFlow(org.keycloak.authentication.AuthenticationFlow) AuthenticatorConfigInfoRepresentation(org.keycloak.representations.idm.AuthenticatorConfigInfoRepresentation) GET(javax.ws.rs.GET) Logger(org.jboss.logging.Logger) ProviderConfigProperty(org.keycloak.provider.ProviderConfigProperty) HashMap(java.util.HashMap) AuthenticationExecutionInfoRepresentation(org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation) AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) AuthenticationFlowRepresentation(org.keycloak.representations.idm.AuthenticationFlowRepresentation) AuthenticatorConfigModel(org.keycloak.models.AuthenticatorConfigModel) AuthenticationFlowModel(org.keycloak.models.AuthenticationFlowModel) ConfigurableAuthenticatorFactory(org.keycloak.authentication.ConfigurableAuthenticatorFactory) LinkedList(java.util.LinkedList) ProviderFactory(org.keycloak.provider.ProviderFactory) FormAction(org.keycloak.authentication.FormAction) POST(javax.ws.rs.POST) Authenticator(org.keycloak.authentication.Authenticator) AdminPermissionEvaluator(org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator) KeycloakSession(org.keycloak.models.KeycloakSession) RequiredActionProviderRepresentation(org.keycloak.representations.idm.RequiredActionProviderRepresentation) RequiredActionProvider(org.keycloak.authentication.RequiredActionProvider) AuthenticatorConfigRepresentation(org.keycloak.representations.idm.AuthenticatorConfigRepresentation) NoCache(org.jboss.resteasy.annotations.cache.NoCache) PUT(javax.ws.rs.PUT) Collections(java.util.Collections) ErrorResponse(org.keycloak.services.ErrorResponse) RequiredActionFactory(org.keycloak.authentication.RequiredActionFactory) HashMap(java.util.HashMap) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) GET(javax.ws.rs.GET) NoCache(org.jboss.resteasy.annotations.cache.NoCache)

Aggregations

Response (javax.ws.rs.core.Response)3 RequiredActionFactory (org.keycloak.authentication.RequiredActionFactory)3 RequiredActionProvider (org.keycloak.authentication.RequiredActionProvider)3 AuthenticationFlowException (org.keycloak.authentication.AuthenticationFlowException)2 RequiredActionContextResult (org.keycloak.authentication.RequiredActionContextResult)2 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Set (java.util.Set)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Collectors (java.util.stream.Collectors)1 Stream (java.util.stream.Stream)1 BadRequestException (javax.ws.rs.BadRequestException)1 Consumes (javax.ws.rs.Consumes)1 DELETE (javax.ws.rs.DELETE)1 GET (javax.ws.rs.GET)1