Search in sources :

Example 71 with AuthenticationSessionModel

use of org.keycloak.sessions.AuthenticationSessionModel in project keycloak by keycloak.

the class AuthenticationManager method redirectToRequiredActions.

public static Response redirectToRequiredActions(KeycloakSession session, RealmModel realm, AuthenticationSessionModel authSession, UriInfo uriInfo, String requiredAction) {
    // redirect to non-action url so browser refresh button works without reposting past data
    ClientSessionCode<AuthenticationSessionModel> accessCode = new ClientSessionCode<>(session, realm, authSession);
    accessCode.setAction(AuthenticationSessionModel.Action.REQUIRED_ACTIONS.name());
    authSession.setAuthNote(AuthenticationProcessor.CURRENT_FLOW_PATH, LoginActionsService.REQUIRED_ACTION);
    authSession.setAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION, requiredAction);
    UriBuilder uriBuilder = LoginActionsService.loginActionsBaseUrl(uriInfo).path(LoginActionsService.REQUIRED_ACTION);
    if (requiredAction != null) {
        uriBuilder.queryParam(Constants.EXECUTION, requiredAction);
    }
    uriBuilder.queryParam(Constants.CLIENT_ID, authSession.getClient().getClientId());
    uriBuilder.queryParam(Constants.TAB_ID, authSession.getTabId());
    if (uriInfo.getQueryParameters().containsKey(LoginActionsService.AUTH_SESSION_ID)) {
        uriBuilder.queryParam(LoginActionsService.AUTH_SESSION_ID, authSession.getParentSession().getId());
    }
    URI redirect = uriBuilder.build(realm.getName());
    return Response.status(302).location(redirect).build();
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UriBuilder(javax.ws.rs.core.UriBuilder) URI(java.net.URI)

Example 72 with AuthenticationSessionModel

use of org.keycloak.sessions.AuthenticationSessionModel in project keycloak by keycloak.

the class AuthenticationManager method backchannelLogoutClientSession.

/**
 * Logs out the given client session and records the result into {@code logoutAuthSession} if set.
 *
 * @param session
 * @param realm
 * @param clientSession
 * @param logoutAuthSession auth session used for recording result of logout. May be {@code null}
 * @param uriInfo
 * @param headers
 * @return {@code http status OK} if the client was or is already being logged out, {@code null} if it is
 *         not known how to log it out and no request is made, otherwise the response of the logout request.
 */
private static Response backchannelLogoutClientSession(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 Response.ok().build();
    }
    if (!client.isEnabled()) {
        return null;
    }
    try {
        setClientLogoutAction(logoutAuthSession, client.getId(), AuthenticationSessionModel.Action.LOGGING_OUT);
        String authMethod = clientSession.getProtocol();
        // must be a keycloak service like account
        if (authMethod == null)
            return Response.ok().build();
        logger.debugv("backchannel logout to: {0}", client.getClientId());
        LoginProtocol protocol = session.getProvider(LoginProtocol.class, authMethod);
        protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(uriInfo);
        Response clientSessionLogout = protocol.backchannelLogout(userSession, clientSession);
        setClientLogoutAction(logoutAuthSession, client.getId(), AuthenticationSessionModel.Action.LOGGED_OUT);
        return clientSessionLogout;
    } catch (Exception ex) {
        ServicesLogger.LOGGER.failedToLogoutClient(ex);
        return Response.serverError().build();
    }
}
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) 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)

Example 73 with AuthenticationSessionModel

use of org.keycloak.sessions.AuthenticationSessionModel in project keycloak by keycloak.

the class AuthorizationTokenService method createAuthorizationResponse.

private AuthorizationResponse createAuthorizationResponse(KeycloakIdentity identity, Collection<Permission> entitlements, KeycloakAuthorizationRequest request, ClientModel targetClient) {
    KeycloakSession keycloakSession = request.getKeycloakSession();
    AccessToken accessToken = identity.getAccessToken();
    RealmModel realm = request.getRealm();
    UserSessionProvider sessions = keycloakSession.sessions();
    UserSessionModel userSessionModel;
    if (accessToken.getSessionState() == null) {
        // Create temporary (request-scoped) transient session
        UserModel user = TokenManager.lookupUserFromStatelessToken(keycloakSession, realm, accessToken);
        userSessionModel = sessions.createUserSession(KeycloakModelUtils.generateId(), realm, user, user.getUsername(), request.getClientConnection().getRemoteAddr(), ServiceAccountConstants.CLIENT_AUTH, false, null, null, UserSessionModel.SessionPersistenceState.TRANSIENT);
    } else {
        userSessionModel = sessions.getUserSession(realm, accessToken.getSessionState());
        if (userSessionModel == null) {
            userSessionModel = sessions.getOfflineUserSession(realm, accessToken.getSessionState());
        }
    }
    ClientModel client = realm.getClientByClientId(accessToken.getIssuedFor());
    AuthenticatedClientSessionModel clientSession = userSessionModel.getAuthenticatedClientSessionByClient(targetClient.getId());
    ClientSessionContext clientSessionCtx;
    if (clientSession == null) {
        RootAuthenticationSessionModel rootAuthSession = keycloakSession.authenticationSessions().getRootAuthenticationSession(realm, userSessionModel.getId());
        if (rootAuthSession == null) {
            if (userSessionModel.getUser().getServiceAccountClientLink() == null) {
                rootAuthSession = keycloakSession.authenticationSessions().createRootAuthenticationSession(realm, userSessionModel.getId());
            } else {
                // if the user session is associated with a service account
                rootAuthSession = new AuthenticationSessionManager(keycloakSession).createAuthenticationSession(realm, false);
            }
        }
        AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(targetClient);
        authSession.setAuthenticatedUser(userSessionModel.getUser());
        authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
        authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(keycloakSession.getContext().getUri().getBaseUri(), realm.getName()));
        AuthenticationManager.setClientScopesInSession(authSession);
        clientSessionCtx = TokenManager.attachAuthenticationSession(keycloakSession, userSessionModel, authSession);
    } else {
        clientSessionCtx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession, keycloakSession);
    }
    TokenManager tokenManager = request.getTokenManager();
    EventBuilder event = request.getEvent();
    AccessTokenResponseBuilder responseBuilder = tokenManager.responseBuilder(realm, client, event, keycloakSession, userSessionModel, clientSessionCtx).generateAccessToken();
    AccessToken rpt = responseBuilder.getAccessToken();
    Authorization authorization = new Authorization();
    authorization.setPermissions(entitlements);
    rpt.setAuthorization(authorization);
    if (accessToken.getSessionState() == null) {
        // Skip generating refresh token for accessToken without sessionState claim. This is "stateless" accessToken not pointing to any real persistent userSession
        rpt.setSessionState(null);
    } else {
        if (OIDCAdvancedConfigWrapper.fromClientModel(client).isUseRefreshToken()) {
            responseBuilder.generateRefreshToken();
            RefreshToken refreshToken = responseBuilder.getRefreshToken();
            refreshToken.issuedFor(client.getClientId());
            refreshToken.setAuthorization(authorization);
        }
    }
    if (!rpt.hasAudience(targetClient.getClientId())) {
        rpt.audience(targetClient.getClientId());
    }
    return new AuthorizationResponse(responseBuilder.build(), isUpgraded(request, authorization));
}
Also used : UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) AuthorizationResponse(org.keycloak.representations.idm.authorization.AuthorizationResponse) RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) Authorization(org.keycloak.representations.AccessToken.Authorization) UserSessionProvider(org.keycloak.models.UserSessionProvider) ClientModel(org.keycloak.models.ClientModel) EventBuilder(org.keycloak.events.EventBuilder) RefreshToken(org.keycloak.representations.RefreshToken) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) ClientSessionContext(org.keycloak.models.ClientSessionContext) AccessToken(org.keycloak.representations.AccessToken) KeycloakSession(org.keycloak.models.KeycloakSession) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) AccessTokenResponseBuilder(org.keycloak.protocol.oidc.TokenManager.AccessTokenResponseBuilder) TokenManager(org.keycloak.protocol.oidc.TokenManager)

Example 74 with AuthenticationSessionModel

use of org.keycloak.sessions.AuthenticationSessionModel in project keycloak by keycloak.

the class PolicyEvaluationService method createIdentity.

private CloseableKeycloakIdentity createIdentity(PolicyEvaluationRequest representation) {
    KeycloakSession keycloakSession = this.authorization.getKeycloakSession();
    RealmModel realm = keycloakSession.getContext().getRealm();
    AccessToken accessToken = null;
    String subject = representation.getUserId();
    UserSessionModel userSession = null;
    if (subject != null) {
        UserModel userModel = keycloakSession.users().getUserById(realm, subject);
        if (userModel == null) {
            userModel = keycloakSession.users().getUserByUsername(realm, subject);
        }
        if (userModel != null) {
            String clientId = representation.getClientId();
            if (clientId == null) {
                clientId = resourceServer.getId();
            }
            if (clientId != null) {
                ClientModel clientModel = realm.getClientById(clientId);
                AuthenticationSessionModel authSession = keycloakSession.authenticationSessions().createRootAuthenticationSession(realm).createAuthenticationSession(clientModel);
                authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
                authSession.setAuthenticatedUser(userModel);
                userSession = keycloakSession.sessions().createUserSession(authSession.getParentSession().getId(), realm, userModel, userModel.getUsername(), "127.0.0.1", "passwd", false, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT);
                AuthenticationManager.setClientScopesInSession(authSession);
                ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(keycloakSession, userSession, authSession);
                accessToken = new TokenManager().createClientAccessToken(keycloakSession, realm, clientModel, userModel, userSession, clientSessionCtx);
            }
        }
    }
    if (accessToken == null) {
        accessToken = new AccessToken();
        accessToken.subject(representation.getUserId());
        ClientModel client = null;
        String clientId = representation.getClientId();
        if (clientId != null) {
            client = realm.getClientById(clientId);
        }
        if (client == null) {
            client = realm.getClientById(resourceServer.getId());
        }
        accessToken.issuedFor(client.getClientId());
        accessToken.audience(client.getId());
        accessToken.issuer(Urls.realmIssuer(keycloakSession.getContext().getUri().getBaseUri(), realm.getName()));
        accessToken.setRealmAccess(new AccessToken.Access());
    }
    if (representation.getRoleIds() != null && !representation.getRoleIds().isEmpty()) {
        if (accessToken.getRealmAccess() == null) {
            accessToken.setRealmAccess(new AccessToken.Access());
        }
        AccessToken.Access realmAccess = accessToken.getRealmAccess();
        representation.getRoleIds().forEach(realmAccess::addRole);
    }
    return new CloseableKeycloakIdentity(accessToken, keycloakSession, userSession);
}
Also used : UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) ClientModel(org.keycloak.models.ClientModel) ClientSessionContext(org.keycloak.models.ClientSessionContext) AccessToken(org.keycloak.representations.AccessToken) KeycloakSession(org.keycloak.models.KeycloakSession) TokenManager(org.keycloak.protocol.oidc.TokenManager)

Example 75 with AuthenticationSessionModel

use of org.keycloak.sessions.AuthenticationSessionModel in project keycloak by keycloak.

the class UpdatePassword method processAction.

@Override
public void processAction(RequiredActionContext context) {
    EventBuilder event = context.getEvent();
    AuthenticationSessionModel authSession = context.getAuthenticationSession();
    RealmModel realm = context.getRealm();
    UserModel user = context.getUser();
    KeycloakSession session = context.getSession();
    MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
    event.event(EventType.UPDATE_PASSWORD);
    String passwordNew = formData.getFirst("password-new");
    String passwordConfirm = formData.getFirst("password-confirm");
    EventBuilder errorEvent = event.clone().event(EventType.UPDATE_PASSWORD_ERROR).client(authSession.getClient()).user(authSession.getAuthenticatedUser());
    if (Validation.isBlank(passwordNew)) {
        Response challenge = context.form().setAttribute("username", authSession.getAuthenticatedUser().getUsername()).addError(new FormMessage(Validation.FIELD_PASSWORD, Messages.MISSING_PASSWORD)).createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
        context.challenge(challenge);
        errorEvent.error(Errors.PASSWORD_MISSING);
        return;
    } else if (!passwordNew.equals(passwordConfirm)) {
        Response challenge = context.form().setAttribute("username", authSession.getAuthenticatedUser().getUsername()).addError(new FormMessage(Validation.FIELD_PASSWORD_CONFIRM, Messages.NOTMATCH_PASSWORD)).createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
        context.challenge(challenge);
        errorEvent.error(Errors.PASSWORD_CONFIRM_ERROR);
        return;
    }
    if (getId().equals(authSession.getClientNote(Constants.KC_ACTION_EXECUTING)) && "on".equals(formData.getFirst("logout-sessions"))) {
        session.sessions().getUserSessionsStream(realm, user).filter(s -> !Objects.equals(s.getId(), authSession.getParentSession().getId())).collect(// collect to avoid concurrent modification as backchannelLogout removes the user sessions.
        Collectors.toList()).forEach(s -> AuthenticationManager.backchannelLogout(session, realm, s, session.getContext().getUri(), context.getConnection(), context.getHttpRequest().getHttpHeaders(), true));
    }
    try {
        session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password(passwordNew, false));
        context.success();
    } catch (ModelException me) {
        errorEvent.detail(Details.REASON, me.getMessage()).error(Errors.PASSWORD_REJECTED);
        Response challenge = context.form().setAttribute("username", authSession.getAuthenticatedUser().getUsername()).setError(me.getMessage(), me.getParameters()).createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
        context.challenge(challenge);
        return;
    } catch (Exception ape) {
        errorEvent.detail(Details.REASON, ape.getMessage()).error(Errors.PASSWORD_REJECTED);
        Response challenge = context.form().setAttribute("username", authSession.getAuthenticatedUser().getUsername()).setError(ape.getMessage()).createResponse(UserModel.RequiredAction.UPDATE_PASSWORD);
        context.challenge(challenge);
        return;
    }
}
Also used : RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) Response(javax.ws.rs.core.Response) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) EventBuilder(org.keycloak.events.EventBuilder) ModelException(org.keycloak.models.ModelException) KeycloakSession(org.keycloak.models.KeycloakSession) FormMessage(org.keycloak.models.utils.FormMessage) ModelException(org.keycloak.models.ModelException)

Aggregations

AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)89 RootAuthenticationSessionModel (org.keycloak.sessions.RootAuthenticationSessionModel)48 ClientModel (org.keycloak.models.ClientModel)27 UserModel (org.keycloak.models.UserModel)24 Response (javax.ws.rs.core.Response)23 RealmModel (org.keycloak.models.RealmModel)20 UserSessionModel (org.keycloak.models.UserSessionModel)20 AuthenticationSessionManager (org.keycloak.services.managers.AuthenticationSessionManager)18 KeycloakSession (org.keycloak.models.KeycloakSession)16 ClientSessionContext (org.keycloak.models.ClientSessionContext)13 LoginFormsProvider (org.keycloak.forms.login.LoginFormsProvider)10 URI (java.net.URI)9 UriBuilder (javax.ws.rs.core.UriBuilder)9 EventBuilder (org.keycloak.events.EventBuilder)9 LoginProtocol (org.keycloak.protocol.LoginProtocol)9 GET (javax.ws.rs.GET)8 Path (javax.ws.rs.Path)8 AuthenticationFlowException (org.keycloak.authentication.AuthenticationFlowException)8 OIDCLoginProtocol (org.keycloak.protocol.oidc.OIDCLoginProtocol)8 Map (java.util.Map)7