Search in sources :

Example 6 with AuthenticationSessionManager

use of org.keycloak.services.managers.AuthenticationSessionManager in project keycloak by keycloak.

the class OIDCLoginProtocol method sendError.

@Override
public Response sendError(AuthenticationSessionModel authSession, Error error) {
    if (isOAuth2DeviceVerificationFlow(authSession)) {
        return denyOAuth2DeviceAuthorization(authSession, error, session);
    }
    String responseTypeParam = authSession.getClientNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM);
    String responseModeParam = authSession.getClientNote(OIDCLoginProtocol.RESPONSE_MODE_PARAM);
    setupResponseTypeAndMode(responseTypeParam, responseModeParam);
    String redirect = authSession.getRedirectUri();
    String state = authSession.getClientNote(OIDCLoginProtocol.STATE_PARAM);
    OIDCRedirectUriBuilder redirectUri = OIDCRedirectUriBuilder.fromUri(redirect, responseMode, session, null);
    if (error != Error.CANCELLED_AIA_SILENT) {
        redirectUri.addParam(OAuth2Constants.ERROR, translateError(error));
    }
    if (error == Error.CANCELLED_AIA) {
        redirectUri.addParam(OAuth2Constants.ERROR_DESCRIPTION, "User cancelled aplication-initiated action.");
    }
    if (state != null) {
        redirectUri.addParam(OAuth2Constants.STATE, state);
    }
    new AuthenticationSessionManager(session).removeAuthenticationSession(realm, authSession, true);
    return redirectUri.build();
}
Also used : AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) OIDCRedirectUriBuilder(org.keycloak.protocol.oidc.utils.OIDCRedirectUriBuilder)

Example 7 with AuthenticationSessionManager

use of org.keycloak.services.managers.AuthenticationSessionManager in project keycloak by keycloak.

the class AuthorizationEndpointBase method createAuthenticationSession.

protected AuthenticationSessionModel createAuthenticationSession(ClientModel client, String requestState) {
    AuthenticationSessionManager manager = new AuthenticationSessionManager(session);
    RootAuthenticationSessionModel rootAuthSession = manager.getCurrentRootAuthenticationSession(realm);
    AuthenticationSessionModel authSession;
    if (rootAuthSession != null) {
        authSession = rootAuthSession.createAuthenticationSession(client);
        logger.debugf("Sent request to authz endpoint. Root authentication session with ID '%s' exists. Client is '%s' . Created new authentication session with tab ID: %s", rootAuthSession.getId(), client.getClientId(), authSession.getTabId());
    } else {
        UserSessionCrossDCManager userSessionCrossDCManager = new UserSessionCrossDCManager(session);
        UserSessionModel userSession = userSessionCrossDCManager.getUserSessionIfExistsRemotely(manager, realm);
        if (userSession != null) {
            UserModel user = userSession.getUser();
            if (user != null && !user.isEnabled()) {
                authSession = createNewAuthenticationSession(manager, client);
                AuthenticationManager.backchannelLogout(session, userSession, true);
            } else {
                String userSessionId = userSession.getId();
                rootAuthSession = session.authenticationSessions().createRootAuthenticationSession(realm, userSessionId);
                authSession = rootAuthSession.createAuthenticationSession(client);
                logger.debugf("Sent request to authz endpoint. We don't have root authentication session with ID '%s' but we have userSession." + "Re-created root authentication session with same ID. Client is: %s . New authentication session tab ID: %s", userSessionId, client.getClientId(), authSession.getTabId());
            }
        } else {
            authSession = createNewAuthenticationSession(manager, client);
        }
    }
    session.getProvider(LoginFormsProvider.class).setAuthenticationSession(authSession);
    return authSession;
}
Also used : AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) UserModel(org.keycloak.models.UserModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) LoginFormsProvider(org.keycloak.forms.login.LoginFormsProvider) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UserSessionCrossDCManager(org.keycloak.services.managers.UserSessionCrossDCManager)

Example 8 with AuthenticationSessionManager

use of org.keycloak.services.managers.AuthenticationSessionManager 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 9 with AuthenticationSessionManager

use of org.keycloak.services.managers.AuthenticationSessionManager in project keycloak by keycloak.

the class LoginActionsService method handleActionToken.

protected <T extends JsonWebToken & ActionTokenKeyModel> Response handleActionToken(String tokenString, String execution, String clientId, String tabId) {
    T token;
    ActionTokenHandler<T> handler;
    ActionTokenContext<T> tokenContext;
    String eventError = null;
    String defaultErrorMessage = null;
    AuthenticationSessionModel authSession = null;
    // Setup client, so error page will contain "back to application" link
    ClientModel client = null;
    if (clientId != null) {
        client = realm.getClientByClientId(clientId);
    }
    AuthenticationSessionManager authenticationSessionManager = new AuthenticationSessionManager(session);
    if (client != null) {
        session.getContext().setClient(client);
        authSession = authenticationSessionManager.getCurrentAuthenticationSession(realm, client, tabId);
    }
    event.event(EventType.EXECUTE_ACTION_TOKEN);
    // First resolve action token handler
    try {
        if (tokenString == null) {
            throw new ExplainedTokenVerificationException(null, Errors.NOT_ALLOWED, Messages.INVALID_REQUEST);
        }
        TokenVerifier<DefaultActionTokenKey> tokenVerifier = TokenVerifier.create(tokenString, DefaultActionTokenKey.class);
        DefaultActionTokenKey aToken = tokenVerifier.getToken();
        event.detail(Details.TOKEN_ID, aToken.getId()).detail(Details.ACTION, aToken.getActionId()).user(aToken.getUserId());
        handler = resolveActionTokenHandler(aToken.getActionId());
        eventError = handler.getDefaultEventError();
        defaultErrorMessage = handler.getDefaultErrorMessage();
        if (!realm.isEnabled()) {
            throw new ExplainedTokenVerificationException(aToken, Errors.REALM_DISABLED, Messages.REALM_NOT_ENABLED);
        }
        if (!checkSsl()) {
            throw new ExplainedTokenVerificationException(aToken, Errors.SSL_REQUIRED, Messages.HTTPS_REQUIRED);
        }
        TokenVerifier<DefaultActionTokenKey> verifier = tokenVerifier.withChecks(// Token introspection checks
        TokenVerifier.IS_ACTIVE, new TokenVerifier.RealmUrlCheck(Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName())), ACTION_TOKEN_BASIC_CHECKS);
        String kid = verifier.getHeader().getKeyId();
        String algorithm = verifier.getHeader().getAlgorithm().name();
        SignatureVerifierContext signatureVerifier = session.getProvider(SignatureProvider.class, algorithm).verifier(kid);
        verifier.verifierContext(signatureVerifier);
        verifier.verify();
        token = TokenVerifier.create(tokenString, handler.getTokenClass()).getToken();
    } catch (TokenNotActiveException ex) {
        if (authSession != null) {
            event.clone().error(Errors.EXPIRED_CODE);
            String flowPath = authSession.getClientNote(AuthorizationEndpointBase.APP_INITIATED_FLOW);
            if (flowPath == null) {
                flowPath = AUTHENTICATE_PATH;
            }
            AuthenticationProcessor.resetFlow(authSession, flowPath);
            // Process correct flow
            return processFlowFromPath(flowPath, authSession, Messages.EXPIRED_ACTION_TOKEN_SESSION_EXISTS);
        }
        return handleActionTokenVerificationException(null, ex, Errors.EXPIRED_CODE, Messages.EXPIRED_ACTION_TOKEN_NO_SESSION);
    } catch (ExplainedTokenVerificationException ex) {
        return handleActionTokenVerificationException(null, ex, ex.getErrorEvent(), ex.getMessage());
    } catch (ExplainedVerificationException ex) {
        return handleActionTokenVerificationException(null, ex, ex.getErrorEvent(), ex.getMessage());
    } catch (VerificationException ex) {
        return handleActionTokenVerificationException(null, ex, eventError, defaultErrorMessage);
    }
    // Now proceed with the verification and handle the token
    tokenContext = new ActionTokenContext(session, realm, session.getContext().getUri(), clientConnection, request, event, handler, execution, this::processFlow, this::brokerLoginFlow);
    try {
        String tokenAuthSessionCompoundId = handler.getAuthenticationSessionIdFromToken(token, tokenContext, authSession);
        if (tokenAuthSessionCompoundId != null) {
            // This can happen if the token contains ID but user opens the link in a new browser
            String sessionId = AuthenticationSessionCompoundId.encoded(tokenAuthSessionCompoundId).getRootSessionId();
            LoginActionsServiceChecks.checkNotLoggedInYet(tokenContext, authSession, sessionId);
        }
        if (authSession == null) {
            authSession = handler.startFreshAuthenticationSession(token, tokenContext);
            tokenContext.setAuthenticationSession(authSession, true);
        } else if (tokenAuthSessionCompoundId == null || !LoginActionsServiceChecks.doesAuthenticationSessionFromCookieMatchOneFromToken(tokenContext, authSession, tokenAuthSessionCompoundId)) {
            // There exists an authentication session but no auth session ID was received in the action token
            logger.debugf("Authentication session in progress but no authentication session ID was found in action token %s, restarting.", token.getId());
            authenticationSessionManager.removeAuthenticationSession(realm, authSession, false);
            authSession = handler.startFreshAuthenticationSession(token, tokenContext);
            tokenContext.setAuthenticationSession(authSession, true);
            processLocaleParam(authSession);
        }
        initLoginEvent(authSession);
        event.event(handler.eventType());
        LoginActionsServiceChecks.checkIsUserValid(token, tokenContext);
        LoginActionsServiceChecks.checkIsClientValid(token, tokenContext);
        session.getContext().setClient(authSession.getClient());
        TokenVerifier.createWithoutSignature(token).withChecks(handler.getVerifiers(tokenContext)).verify();
        authSession = tokenContext.getAuthenticationSession();
        event = tokenContext.getEvent();
        event.event(handler.eventType());
        if (!handler.canUseTokenRepeatedly(token, tokenContext)) {
            LoginActionsServiceChecks.checkTokenWasNotUsedYet(token, tokenContext);
            authSession.setAuthNote(AuthenticationManager.INVALIDATE_ACTION_TOKEN, token.serializeKey());
        }
        authSession.setAuthNote(DefaultActionTokenKey.ACTION_TOKEN_USER_ID, token.getUserId());
        authSession.setAuthNote(Constants.KEY, tokenString);
        return handler.handleToken(token, tokenContext);
    } catch (ExplainedTokenVerificationException ex) {
        return handleActionTokenVerificationException(tokenContext, ex, ex.getErrorEvent(), ex.getMessage());
    } catch (LoginActionsServiceException ex) {
        Response response = ex.getResponse();
        return response == null ? handleActionTokenVerificationException(tokenContext, ex, eventError, defaultErrorMessage) : response;
    } catch (VerificationException ex) {
        return handleActionTokenVerificationException(tokenContext, ex, eventError, defaultErrorMessage);
    }
}
Also used : TokenNotActiveException(org.keycloak.exceptions.TokenNotActiveException) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) SignatureVerifierContext(org.keycloak.crypto.SignatureVerifierContext) ExplainedVerificationException(org.keycloak.authentication.ExplainedVerificationException) ActionTokenContext(org.keycloak.authentication.actiontoken.ActionTokenContext) DefaultActionTokenKey(org.keycloak.authentication.actiontoken.DefaultActionTokenKey) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Response(javax.ws.rs.core.Response) ClientModel(org.keycloak.models.ClientModel) SignatureProvider(org.keycloak.crypto.SignatureProvider) GET(javax.ws.rs.GET) POST(javax.ws.rs.POST) ExplainedTokenVerificationException(org.keycloak.authentication.actiontoken.ExplainedTokenVerificationException) TokenVerifier(org.keycloak.TokenVerifier) VerificationException(org.keycloak.common.VerificationException) ExplainedVerificationException(org.keycloak.authentication.ExplainedVerificationException) ExplainedTokenVerificationException(org.keycloak.authentication.actiontoken.ExplainedTokenVerificationException)

Example 10 with AuthenticationSessionManager

use of org.keycloak.services.managers.AuthenticationSessionManager in project keycloak by keycloak.

the class ClientScopeEvaluateResource method sessionAware.

private <R> R sessionAware(UserModel user, String scopeParam, BiFunction<UserSessionModel, ClientSessionContext, R> function) {
    AuthenticationSessionModel authSession = null;
    AuthenticationSessionManager authSessionManager = new AuthenticationSessionManager(session);
    try {
        RootAuthenticationSessionModel rootAuthSession = authSessionManager.createAuthenticationSession(realm, false);
        authSession = rootAuthSession.createAuthenticationSession(client);
        authSession.setAuthenticatedUser(user);
        authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
        authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
        authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, scopeParam);
        UserSessionModel userSession = session.sessions().createUserSession(authSession.getParentSession().getId(), realm, user, user.getUsername(), clientConnection.getRemoteAddr(), "example-auth", false, null, null, UserSessionModel.SessionPersistenceState.TRANSIENT);
        AuthenticationManager.setClientScopesInSession(authSession);
        ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(session, userSession, authSession);
        return function.apply(userSession, clientSessionCtx);
    } finally {
        if (authSession != null) {
            authSessionManager.removeAuthenticationSession(realm, authSession, false);
        }
    }
}
Also used : AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) ClientSessionContext(org.keycloak.models.ClientSessionContext) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel)

Aggregations

AuthenticationSessionManager (org.keycloak.services.managers.AuthenticationSessionManager)22 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)18 RootAuthenticationSessionModel (org.keycloak.sessions.RootAuthenticationSessionModel)15 UserSessionModel (org.keycloak.models.UserSessionModel)11 ClientModel (org.keycloak.models.ClientModel)10 UserModel (org.keycloak.models.UserModel)8 ClientSessionContext (org.keycloak.models.ClientSessionContext)7 GET (javax.ws.rs.GET)4 Response (javax.ws.rs.core.Response)4 UriBuilder (javax.ws.rs.core.UriBuilder)4 LoginFormsProvider (org.keycloak.forms.login.LoginFormsProvider)4 DefaultClientSessionContext (org.keycloak.services.util.DefaultClientSessionContext)4 URI (java.net.URI)3 HashMap (java.util.HashMap)3 Path (javax.ws.rs.Path)3 AuthenticatedClientSessionModel (org.keycloak.models.AuthenticatedClientSessionModel)3 TokenManager (org.keycloak.protocol.oidc.TokenManager)3 AccessTokenResponse (org.keycloak.representations.AccessTokenResponse)3 IOException (java.io.IOException)2 Map (java.util.Map)2