Search in sources :

Example 6 with UserSessionModel

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

the class CibaGrantType method cibaGrant.

public Response cibaGrant() {
    ProfileHelper.requireFeature(Profile.Feature.CIBA);
    if (!realm.getCibaPolicy().isOIDCCIBAGrantEnabled(client)) {
        event.error(Errors.NOT_ALLOWED);
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "Client not allowed OIDC CIBA Grant", Response.Status.BAD_REQUEST);
    }
    String jwe = formParams.getFirst(AUTH_REQ_ID);
    if (jwe == null) {
        event.error(Errors.INVALID_CODE);
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Missing parameter: " + AUTH_REQ_ID, Response.Status.BAD_REQUEST);
    }
    logger.tracev("CIBA Grant :: authReqId = {0}", jwe);
    CIBAAuthenticationRequest request;
    try {
        request = CIBAAuthenticationRequest.deserialize(session, jwe);
    } catch (Exception e) {
        logger.warnf("illegal format of auth_req_id : e.getMessage() = %s", e.getMessage());
        // Auth Req ID has not put onto cache, no need to remove Auth Req ID.
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "Invalid Auth Req ID", Response.Status.BAD_REQUEST);
    }
    request.setClient(client);
    try {
        session.clientPolicy().triggerOnEvent(new BackchannelTokenRequestContext(request, formParams));
    } catch (ClientPolicyException cpe) {
        event.error(cpe.getError());
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, cpe.getErrorDetail(), Response.Status.BAD_REQUEST);
    }
    OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
    OAuth2DeviceCodeModel deviceCode = store.getByDeviceCode(realm, request.getId());
    if (deviceCode == null) {
        // Auth Req ID has not put onto cache, no need to remove Auth Req ID.
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "Invalid " + AUTH_REQ_ID, Response.Status.BAD_REQUEST);
    }
    if (!request.getIssuedFor().equals(client.getClientId())) {
        logDebug("invalid client.", request);
        // the client sending this Auth Req ID does not match the client to which keycloak had issued Auth Req ID.
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "unauthorized client", Response.Status.BAD_REQUEST);
    }
    if (deviceCode.isExpired()) {
        logDebug("expired.", request);
        throw new CorsErrorResponseException(cors, OAuthErrorException.EXPIRED_TOKEN, "authentication timed out", Response.Status.BAD_REQUEST);
    }
    if (!store.isPollingAllowed(deviceCode)) {
        logDebug("pooling.", request);
        throw new CorsErrorResponseException(cors, OAuthErrorException.SLOW_DOWN, "too early to access", Response.Status.BAD_REQUEST);
    }
    if (deviceCode.isDenied()) {
        logDebug("denied.", request);
        throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "not authorized", Response.Status.BAD_REQUEST);
    }
    // get corresponding Authentication Channel Result entry
    if (deviceCode.isPending()) {
        logDebug("not yet authenticated by Authentication Device or auth_req_id has already been used to get tokens.", request);
        throw new CorsErrorResponseException(cors, OAuthErrorException.AUTHORIZATION_PENDING, "The authorization request is still pending as the end-user hasn't yet been authenticated.", Response.Status.BAD_REQUEST);
    }
    UserSessionModel userSession = createUserSession(request, deviceCode.getAdditionalParams());
    UserModel user = userSession.getUser();
    store.removeDeviceCode(realm, request.getId());
    // Compute client scopes again from scope parameter. Check if user still has them granted
    // (but in code-to-token request, it could just theoretically happen that they are not available)
    String scopeParam = request.getScope();
    if (!TokenManager.verifyConsentStillAvailable(session, user, client, TokenManager.getRequestedClientScopes(scopeParam, client))) {
        event.error(Errors.NOT_ALLOWED);
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_SCOPE, "Client no longer has requested consent from user", Response.Status.BAD_REQUEST);
    }
    ClientSessionContext clientSessionCtx = DefaultClientSessionContext.fromClientSessionAndScopeParameter(userSession.getAuthenticatedClientSessionByClient(client.getId()), scopeParam, session);
    int authTime = Time.currentTime();
    userSession.setNote(AuthenticationManager.AUTH_TIME, String.valueOf(authTime));
    return tokenEndpoint.createTokenResponse(user, userSession, clientSessionCtx, scopeParam, true);
}
Also used : OAuth2DeviceTokenStoreProvider(org.keycloak.models.OAuth2DeviceTokenStoreProvider) UserModel(org.keycloak.models.UserModel) UserSessionModel(org.keycloak.models.UserSessionModel) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) ClientSessionContext(org.keycloak.models.ClientSessionContext) OAuth2DeviceCodeModel(org.keycloak.models.OAuth2DeviceCodeModel) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) BackchannelTokenRequestContext(org.keycloak.protocol.oidc.grants.ciba.clientpolicy.context.BackchannelTokenRequestContext) CIBAAuthenticationRequest(org.keycloak.protocol.oidc.grants.ciba.channel.CIBAAuthenticationRequest) OAuthErrorException(org.keycloak.OAuthErrorException) ErrorResponseException(org.keycloak.services.ErrorResponseException) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) CibaRootEndpoint(org.keycloak.protocol.oidc.grants.ciba.endpoints.CibaRootEndpoint) TokenEndpoint(org.keycloak.protocol.oidc.endpoints.TokenEndpoint) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException)

Example 7 with UserSessionModel

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

the class ClaimsParameterTokenMapper method putClaims.

private void putClaims(String tokenType, String claims, IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
    JsonNode requestParams = null;
    try {
        requestParams = JsonSerialization.readValue(claims, JsonNode.class);
    } catch (IOException e) {
        return;
    }
    if (!requestParams.has(tokenType))
        return;
    JsonNode tokenNode = requestParams.findValue(tokenType);
    OIDCWellKnownProvider.DEFAULT_CLAIMS_SUPPORTED.stream().filter(i -> tokenNode.has(i)).filter(i -> tokenNode.findValue(i).has("essential")).filter(i -> tokenNode.findValue(i).findValue("essential").isBoolean()).filter(i -> tokenNode.findValue(i).findValue("essential").asBoolean()).forEach(i -> {
        // "name", "given_name", "family_name", "preferred_username", "email" need to be set explicitly using existing mapper.
        if (i.equals(IDToken.NAME)) {
            FullNameMapper fullNameMapper = new FullNameMapper();
            fullNameMapper.setClaim(token, mappingModel, userSession);
        } else if (i.equals(IDToken.GIVEN_NAME)) {
            UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
            userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested firstName", "firstName", IDToken.GIVEN_NAME, "String", false, true), userSession);
        } else if (i.equals(IDToken.FAMILY_NAME)) {
            UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
            userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested lastName", "lastName", IDToken.FAMILY_NAME, "String", false, true), userSession);
        } else if (i.equals(IDToken.PREFERRED_USERNAME)) {
            UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
            userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested username", "username", IDToken.PREFERRED_USERNAME, "String", false, true), userSession);
        } else if (i.equals(IDToken.EMAIL)) {
            UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
            userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested email", "email", IDToken.EMAIL, "String", false, true), userSession);
        }
    });
}
Also used : ProtocolMapperModel(org.keycloak.models.ProtocolMapperModel) ProviderConfigProperty(org.keycloak.provider.ProviderConfigProperty) KeycloakSession(org.keycloak.models.KeycloakSession) IOException(java.io.IOException) HashMap(java.util.HashMap) UserSessionModel(org.keycloak.models.UserSessionModel) IDToken(org.keycloak.representations.IDToken) OIDCWellKnownProvider(org.keycloak.protocol.oidc.OIDCWellKnownProvider) ArrayList(java.util.ArrayList) JsonSerialization(org.keycloak.util.JsonSerialization) List(java.util.List) TokenUtil(org.keycloak.util.TokenUtil) ClientSessionContext(org.keycloak.models.ClientSessionContext) Map(java.util.Map) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) JsonNode(com.fasterxml.jackson.databind.JsonNode) JsonNode(com.fasterxml.jackson.databind.JsonNode) IOException(java.io.IOException)

Example 8 with UserSessionModel

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

the class UserResource method impersonate.

/**
 * Impersonate the user
 *
 * @return
 */
@Path("impersonation")
@POST
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Map<String, Object> impersonate() {
    ProfileHelper.requireFeature(Profile.Feature.IMPERSONATION);
    auth.users().requireImpersonate(user);
    RealmModel authenticatedRealm = auth.adminAuth().getRealm();
    // if same realm logout before impersonation
    boolean sameRealm = false;
    String sessionState = auth.adminAuth().getToken().getSessionState();
    if (authenticatedRealm.getId().equals(realm.getId()) && sessionState != null) {
        sameRealm = true;
        UserSessionModel userSession = session.sessions().getUserSession(authenticatedRealm, sessionState);
        AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection);
        AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), clientConnection);
        AuthenticationManager.backchannelLogout(session, authenticatedRealm, userSession, session.getContext().getUri(), clientConnection, headers, true);
    }
    EventBuilder event = new EventBuilder(realm, session, clientConnection);
    UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), "impersonate", false, null, null);
    UserModel adminUser = auth.adminAuth().getUser();
    String impersonatorId = adminUser.getId();
    String impersonator = adminUser.getUsername();
    userSession.setNote(IMPERSONATOR_ID.toString(), impersonatorId);
    userSession.setNote(IMPERSONATOR_USERNAME.toString(), impersonator);
    AuthenticationManager.createLoginCookie(session, realm, userSession.getUser(), userSession, session.getContext().getUri(), clientConnection);
    URI redirect = AccountFormService.accountServiceBaseUrl(session.getContext().getUri()).build(realm.getName());
    Map<String, Object> result = new HashMap<>();
    result.put("sameRealm", sameRealm);
    result.put("redirect", redirect.toString());
    event.event(EventType.IMPERSONATE).session(userSession).user(user).detail(Details.IMPERSONATOR_REALM, authenticatedRealm.getName()).detail(Details.IMPERSONATOR, impersonator).success();
    return result;
}
Also used : RealmModel(org.keycloak.models.RealmModel) UserModel(org.keycloak.models.UserModel) UserSessionModel(org.keycloak.models.UserSessionModel) EventBuilder(org.keycloak.events.EventBuilder) HashMap(java.util.HashMap) URI(java.net.URI) Path(javax.ws.rs.Path) POST(javax.ws.rs.POST) Produces(javax.ws.rs.Produces) NoCache(org.jboss.resteasy.annotations.cache.NoCache)

Example 9 with UserSessionModel

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

the class InfinispanUserSessionProvider method createClientSession.

@Override
public AuthenticatedClientSessionModel createClientSession(RealmModel realm, ClientModel client, UserSessionModel userSession) {
    final UUID clientSessionId = keyGenerator.generateKeyUUID(session, clientSessionCache);
    AuthenticatedClientSessionEntity entity = new AuthenticatedClientSessionEntity(clientSessionId);
    entity.setRealmId(realm.getId());
    entity.setTimestamp(Time.currentTime());
    entity.getNotes().put(AuthenticatedClientSessionModel.STARTED_AT_NOTE, String.valueOf(entity.getTimestamp()));
    InfinispanChangelogBasedTransaction<String, UserSessionEntity> userSessionUpdateTx = getTransaction(false);
    InfinispanChangelogBasedTransaction<UUID, AuthenticatedClientSessionEntity> clientSessionUpdateTx = getClientSessionTransaction(false);
    AuthenticatedClientSessionAdapter adapter = new AuthenticatedClientSessionAdapter(session, this, entity, client, userSession, clientSessionUpdateTx, false);
    // For now, the clientSession is considered transient in case that userSession was transient
    UserSessionModel.SessionPersistenceState persistenceState = (userSession instanceof UserSessionAdapter && ((UserSessionAdapter) userSession).getPersistenceState() != null) ? ((UserSessionAdapter) userSession).getPersistenceState() : UserSessionModel.SessionPersistenceState.PERSISTENT;
    SessionUpdateTask<AuthenticatedClientSessionEntity> createClientSessionTask = Tasks.addIfAbsentSync();
    clientSessionUpdateTx.addTask(clientSessionId, createClientSessionTask, entity, persistenceState);
    SessionUpdateTask registerClientSessionTask = new RegisterClientSessionTask(client.getId(), clientSessionId);
    userSessionUpdateTx.addTask(userSession.getId(), registerClientSessionTask);
    return adapter;
}
Also used : OfflineUserSessionModel(org.keycloak.models.OfflineUserSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) SessionUpdateTask(org.keycloak.models.sessions.infinispan.changes.SessionUpdateTask) AuthenticatedClientSessionEntity(org.keycloak.models.sessions.infinispan.entities.AuthenticatedClientSessionEntity) UUID(java.util.UUID) UserSessionEntity(org.keycloak.models.sessions.infinispan.entities.UserSessionEntity)

Example 10 with UserSessionModel

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

the class InfinispanUserSessionProvider method getUserSessionEntityFromPersistenceProvider.

private UserSessionEntity getUserSessionEntityFromPersistenceProvider(RealmModel realm, String sessionId, boolean offline) {
    log.debugf("Offline user-session not found in infinispan, attempting UserSessionPersisterProvider lookup for sessionId=%s", sessionId);
    UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
    UserSessionModel persistentUserSession = persister.loadUserSession(realm, sessionId, offline);
    if (persistentUserSession == null) {
        log.debugf("Offline user-session not found in UserSessionPersisterProvider for sessionId=%s", sessionId);
        return null;
    }
    return importUserSession(realm, offline, persistentUserSession);
}
Also used : OfflineUserSessionModel(org.keycloak.models.OfflineUserSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) UserSessionPersisterProvider(org.keycloak.models.session.UserSessionPersisterProvider)

Aggregations

UserSessionModel (org.keycloak.models.UserSessionModel)133 RealmModel (org.keycloak.models.RealmModel)68 Test (org.junit.Test)53 ClientModel (org.keycloak.models.ClientModel)44 UserModel (org.keycloak.models.UserModel)43 AuthenticatedClientSessionModel (org.keycloak.models.AuthenticatedClientSessionModel)38 AbstractTestRealmKeycloakTest (org.keycloak.testsuite.AbstractTestRealmKeycloakTest)29 KeycloakSession (org.keycloak.models.KeycloakSession)26 ModelTest (org.keycloak.testsuite.arquillian.annotation.ModelTest)26 AuthenticationSessionModel (org.keycloak.sessions.AuthenticationSessionModel)21 ClientSessionContext (org.keycloak.models.ClientSessionContext)20 AtomicReference (java.util.concurrent.atomic.AtomicReference)18 RootAuthenticationSessionModel (org.keycloak.sessions.RootAuthenticationSessionModel)17 KeycloakModelTest (org.keycloak.testsuite.model.KeycloakModelTest)17 Response (javax.ws.rs.core.Response)15 ClientPolicyException (org.keycloak.services.clientpolicy.ClientPolicyException)14 List (java.util.List)13 CorsErrorResponseException (org.keycloak.services.CorsErrorResponseException)13 Map (java.util.Map)12 UserSessionPersisterProvider (org.keycloak.models.session.UserSessionPersisterProvider)12