Search in sources :

Example 1 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol 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 LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class AuthenticationManager method frontchannelLogoutClientSession.

private static Response frontchannelLogoutClientSession(KeycloakSession session, RealmModel realm, AuthenticatedClientSessionModel clientSession, AuthenticationSessionModel logoutAuthSession, UriInfo uriInfo, HttpHeaders headers) {
    UserSessionModel userSession = clientSession.getUserSession();
    ClientModel client = clientSession.getClient();
    if (!client.isFrontchannelLogout() || AuthenticationSessionModel.Action.LOGGED_OUT.name().equals(clientSession.getAction())) {
        return null;
    }
    final AuthenticationSessionModel.Action logoutState = getClientLogoutAction(logoutAuthSession, client.getId());
    if (logoutState == AuthenticationSessionModel.Action.LOGGED_OUT || logoutState == AuthenticationSessionModel.Action.LOGGING_OUT) {
        return null;
    }
    try {
        session.clientPolicy().triggerOnEvent(new LogoutRequestContext());
    } catch (ClientPolicyException cpe) {
        throw new ErrorResponseException(cpe.getError(), cpe.getErrorDetail(), cpe.getErrorStatus());
    }
    try {
        setClientLogoutAction(logoutAuthSession, client.getId(), AuthenticationSessionModel.Action.LOGGING_OUT);
        String authMethod = clientSession.getProtocol();
        // must be a keycloak service like account
        if (authMethod == null)
            return null;
        logger.debugv("frontchannel logout to: {0}", client.getClientId());
        LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
        protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(uriInfo);
        Response response = protocol.frontchannelLogout(userSession, clientSession);
        if (response != null) {
            logger.debug("returning frontchannel logout request to client");
            if (!AuthenticationSessionModel.Action.LOGGING_OUT.name().equals(clientSession.getAction())) {
                setClientLogoutAction(logoutAuthSession, client.getId(), AuthenticationSessionModel.Action.LOGGED_OUT);
            }
            return response;
        }
    } catch (Exception e) {
        ServicesLogger.LOGGER.failedToLogoutClient(e);
    }
    return null;
}
Also used : BackchannelLogoutResponse(org.keycloak.protocol.oidc.BackchannelLogoutResponse) Response(javax.ws.rs.core.Response) ClientModel(org.keycloak.models.ClientModel) UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) ErrorResponseException(org.keycloak.services.ErrorResponseException) LogoutRequestContext(org.keycloak.services.clientpolicy.context.LogoutRequestContext) LoginProtocol(org.keycloak.protocol.LoginProtocol) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) ErrorResponseException(org.keycloak.services.ErrorResponseException) AuthenticationFlowException(org.keycloak.authentication.AuthenticationFlowException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) VerificationException(org.keycloak.common.VerificationException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException)

Example 3 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol 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)

Example 4 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class LoginActionsService method interruptionResponse.

private Response interruptionResponse(RequiredActionContextResult context, AuthenticationSessionModel authSession, String action, Error error) {
    LoginProtocol protocol = context.getSession().getProvider(LoginProtocol.class, authSession.getProtocol());
    protocol.setRealm(context.getRealm()).setHttpHeaders(context.getHttpRequest().getHttpHeaders()).setUriInfo(context.getUriInfo()).setEventBuilder(event);
    event.detail(Details.CUSTOM_REQUIRED_ACTION, action);
    event.error(Errors.REJECTED_BY_USER);
    return protocol.sendError(authSession, error);
}
Also used : OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) LoginProtocol(org.keycloak.protocol.LoginProtocol)

Example 5 with LoginProtocol

use of org.keycloak.protocol.LoginProtocol in project keycloak by keycloak.

the class ResourceAdminManager method sendPushRevocationPolicyRequest.

protected boolean sendPushRevocationPolicyRequest(RealmModel realm, ClientModel resource, int notBefore, String managementUrl) {
    String protocol = resource.getProtocol();
    if (protocol == null) {
        protocol = OIDCLoginProtocol.LOGIN_PROTOCOL;
    }
    LoginProtocol loginProtocol = (LoginProtocol) session.getProvider(LoginProtocol.class, protocol);
    return loginProtocol == null ? false : loginProtocol.sendPushRevocationPolicyRequest(realm, resource, notBefore, managementUrl);
}
Also used : OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) LoginProtocol(org.keycloak.protocol.LoginProtocol)

Aggregations

LoginProtocol (org.keycloak.protocol.LoginProtocol)11 OIDCLoginProtocol (org.keycloak.protocol.oidc.OIDCLoginProtocol)10 Response (javax.ws.rs.core.Response)6 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)6 RootAuthenticationSessionModel (org.keycloak.sessions.RootAuthenticationSessionModel)5 AuthenticationFlowException (org.keycloak.authentication.AuthenticationFlowException)4 ClientModel (org.keycloak.models.ClientModel)4 BackchannelLogoutResponse (org.keycloak.protocol.oidc.BackchannelLogoutResponse)4 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 VerificationException (org.keycloak.common.VerificationException)3 UserSessionModel (org.keycloak.models.UserSessionModel)3 ErrorResponseException (org.keycloak.services.ErrorResponseException)3 ClientPolicyException (org.keycloak.services.clientpolicy.ClientPolicyException)3 ClientScopeModel (org.keycloak.models.ClientScopeModel)2 ClientSessionContext (org.keycloak.models.ClientSessionContext)2 UserConsentModel (org.keycloak.models.UserConsentModel)2 UserModel (org.keycloak.models.UserModel)2 URI (java.net.URI)1 URLDecoder (java.net.URLDecoder)1 URLEncoder (java.net.URLEncoder)1