Search in sources :

Example 21 with AuthenticationSessionModel

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

the class SetClientNoteAuthenticator method authenticate.

@Override
public void authenticate(AuthenticationFlowContext context) {
    MultivaluedMap<String, String> inputData = context.getHttpRequest().getDecodedFormParameters();
    AuthenticationSessionModel authSession = context.getAuthenticationSession();
    inputData.keySet().stream().filter(paramName -> paramName.startsWith(PREFIX)).forEach(paramName -> {
        String key = paramName.substring(PREFIX.length());
        String value = inputData.getFirst(paramName);
        logger.infof("Set authentication session client note %s=%s", key, value);
        authSession.setClientNote(key, value);
    });
    context.success();
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) Authenticator(org.keycloak.authentication.Authenticator) Logger(org.jboss.logging.Logger) ProviderConfigProperty(org.keycloak.provider.ProviderConfigProperty) KeycloakSession(org.keycloak.models.KeycloakSession) Config(org.keycloak.Config) MultivaluedMap(javax.ws.rs.core.MultivaluedMap) List(java.util.List) UserModel(org.keycloak.models.UserModel) AuthenticationExecutionModel(org.keycloak.models.AuthenticationExecutionModel) KeycloakSessionFactory(org.keycloak.models.KeycloakSessionFactory) AuthenticatorFactory(org.keycloak.authentication.AuthenticatorFactory) AuthenticationFlowContext(org.keycloak.authentication.AuthenticationFlowContext) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel)

Example 22 with AuthenticationSessionModel

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

the class LoginTimeoutValidationTest method testIsLoginTimeoutValid.

@Test
@ModelTest
public void testIsLoginTimeoutValid(KeycloakSession keycloakSession) {
    RealmModel realm = keycloakSession.realms().getRealmByName("test");
    UserSessionModel userSession = keycloakSession.sessions().createUserSession(realm, keycloakSession.users().getUserByUsername(realm, "user1"), "user1", "127.0.0.1", "form", true, null, null);
    ClientModel client = realm.getClientByClientId("account");
    AuthenticationSessionModel authSession = keycloakSession.authenticationSessions().createRootAuthenticationSession(realm).createAuthenticationSession(client);
    ClientSessionCode clientSessionCode = new ClientSessionCode(keycloakSession, realm, authSession);
    /*
         * KEYCLOAK-10636 Large Login timeout causes login failure
         * realm > Realm setting > Tokens > Login timeout
         */
    // Login timeout
    int accessCodeLifespanLoginOrig = realm.getAccessCodeLifespanLogin();
    realm.setAccessCodeLifespanLogin(Integer.MAX_VALUE);
    Assert.assertTrue("Login validataion with large Login Timeout failed", clientSessionCode.isActionActive(ClientSessionCode.ActionType.LOGIN));
    realm.setAccessCodeLifespanLogin(accessCodeLifespanLoginOrig);
    /*
         * KEYCLOAK-10637 Large Login Action timeout causes login failure
         * realm > Realm setting > Tokens > Login Action timeout
         */
    // Login Action timeout
    int accessCodeLifespanUserActionOrig = realm.getAccessCodeLifespanUserAction();
    realm.setAccessCodeLifespanUserAction(Integer.MAX_VALUE);
    Assert.assertTrue("Login validataion with large Login Action Timeout failed", clientSessionCode.isActionActive(ClientSessionCode.ActionType.USER));
    realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserActionOrig);
}
Also used : RealmModel(org.keycloak.models.RealmModel) ClientModel(org.keycloak.models.ClientModel) UserSessionModel(org.keycloak.models.UserSessionModel) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) ClientSessionCode(org.keycloak.services.managers.ClientSessionCode) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) ModelTest(org.keycloak.testsuite.arquillian.annotation.ModelTest) Test(org.junit.Test) AbstractTestRealmKeycloakTest(org.keycloak.testsuite.AbstractTestRealmKeycloakTest)

Example 23 with AuthenticationSessionModel

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

the class TokenEndpoint method clientCredentialsGrant.

public Response clientCredentialsGrant() {
    if (client.isBearerOnly()) {
        event.error(Errors.INVALID_CLIENT);
        throw new CorsErrorResponseException(cors, OAuthErrorException.UNAUTHORIZED_CLIENT, "Bearer-only client not allowed to retrieve service account", Response.Status.UNAUTHORIZED);
    }
    if (client.isPublicClient()) {
        event.error(Errors.INVALID_CLIENT);
        throw new CorsErrorResponseException(cors, OAuthErrorException.UNAUTHORIZED_CLIENT, "Public client not allowed to retrieve service account", Response.Status.UNAUTHORIZED);
    }
    if (!client.isServiceAccountsEnabled()) {
        event.error(Errors.INVALID_CLIENT);
        throw new CorsErrorResponseException(cors, OAuthErrorException.UNAUTHORIZED_CLIENT, "Client not enabled to retrieve service account", Response.Status.UNAUTHORIZED);
    }
    UserModel clientUser = session.users().getServiceAccount(client);
    if (clientUser == null || client.getProtocolMapperByName(OIDCLoginProtocol.LOGIN_PROTOCOL, ServiceAccountConstants.CLIENT_ID_PROTOCOL_MAPPER) == null) {
        // May need to handle bootstrap here as well
        logger.debugf("Service account user for client '%s' not found or default protocol mapper for service account not found. Creating now", client.getClientId());
        new ClientManager(new RealmManager(session)).enableServiceAccount(client);
        clientUser = session.users().getServiceAccount(client);
    }
    String clientUsername = clientUser.getUsername();
    event.detail(Details.USERNAME, clientUsername);
    event.user(clientUser);
    if (!clientUser.isEnabled()) {
        event.error(Errors.USER_DISABLED);
        throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "User '" + clientUsername + "' disabled", Response.Status.UNAUTHORIZED);
    }
    String scope = getRequestedScopes();
    RootAuthenticationSessionModel rootAuthSession = new AuthenticationSessionManager(session).createAuthenticationSession(realm, false);
    AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(client);
    authSession.setAuthenticatedUser(clientUser);
    authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
    authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName()));
    authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, scope);
    // persisting of userSession by default
    UserSessionModel.SessionPersistenceState sessionPersistenceState = UserSessionModel.SessionPersistenceState.PERSISTENT;
    boolean useRefreshToken = OIDCAdvancedConfigWrapper.fromClientModel(client).isUseRefreshTokenForClientCredentialsGrant();
    if (!useRefreshToken) {
        // we don't want to store a session hence we mark it as transient, see KEYCLOAK-9551
        sessionPersistenceState = UserSessionModel.SessionPersistenceState.TRANSIENT;
    }
    UserSessionModel userSession = session.sessions().createUserSession(authSession.getParentSession().getId(), realm, clientUser, clientUsername, clientConnection.getRemoteAddr(), ServiceAccountConstants.CLIENT_AUTH, false, null, null, sessionPersistenceState);
    event.session(userSession);
    AuthenticationManager.setClientScopesInSession(authSession);
    ClientSessionContext clientSessionCtx = TokenManager.attachAuthenticationSession(session, userSession, authSession);
    // Notes about client details
    userSession.setNote(ServiceAccountConstants.CLIENT_ID, client.getClientId());
    userSession.setNote(ServiceAccountConstants.CLIENT_HOST, clientConnection.getRemoteHost());
    userSession.setNote(ServiceAccountConstants.CLIENT_ADDRESS, clientConnection.getRemoteAddr());
    try {
        session.clientPolicy().triggerOnEvent(new ServiceAccountTokenRequestContext(formParams, clientSessionCtx.getClientSession()));
    } catch (ClientPolicyException cpe) {
        event.error(cpe.getError());
        throw new CorsErrorResponseException(cors, cpe.getError(), cpe.getErrorDetail(), Response.Status.BAD_REQUEST);
    }
    updateUserSessionFromClientAuth(userSession);
    TokenManager.AccessTokenResponseBuilder responseBuilder = tokenManager.responseBuilder(realm, client, event, session, userSession, clientSessionCtx).generateAccessToken();
    // Make refresh token generation optional, see KEYCLOAK-9551
    if (useRefreshToken) {
        responseBuilder = responseBuilder.generateRefreshToken();
    } else {
        responseBuilder.getAccessToken().setSessionState(null);
    }
    checkMtlsHoKToken(responseBuilder, useRefreshToken);
    String scopeParam = clientSessionCtx.getClientSession().getNote(OAuth2Constants.SCOPE);
    if (TokenUtil.isOIDCRequest(scopeParam)) {
        responseBuilder.generateIDToken().generateAccessTokenHash();
    }
    // TODO : do the same as codeToToken()
    AccessTokenResponse res = responseBuilder.build();
    event.success();
    return cors.builder(Response.ok(res, MediaType.APPLICATION_JSON_TYPE)).build();
}
Also used : AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) UserSessionModel(org.keycloak.models.UserSessionModel) RealmManager(org.keycloak.services.managers.RealmManager) ServiceAccountTokenRequestContext(org.keycloak.services.clientpolicy.context.ServiceAccountTokenRequestContext) ClientPolicyException(org.keycloak.services.clientpolicy.ClientPolicyException) UserModel(org.keycloak.models.UserModel) AuthenticationSessionManager(org.keycloak.services.managers.AuthenticationSessionManager) DefaultClientSessionContext(org.keycloak.services.util.DefaultClientSessionContext) ClientSessionContext(org.keycloak.models.ClientSessionContext) ClientManager(org.keycloak.services.managers.ClientManager) RootAuthenticationSessionModel(org.keycloak.sessions.RootAuthenticationSessionModel) CorsErrorResponseException(org.keycloak.services.CorsErrorResponseException) TokenManager(org.keycloak.protocol.oidc.TokenManager) AccessTokenResponse(org.keycloak.representations.AccessTokenResponse)

Example 24 with AuthenticationSessionModel

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

the class DockerAuthV2Protocol method authenticated.

@Override
public Response authenticated(final AuthenticationSessionModel authSession, final UserSessionModel userSession, final ClientSessionContext clientSessionCtx) {
    // First, create a base response token with realm + user values populated
    final AuthenticatedClientSessionModel clientSession = clientSessionCtx.getClientSession();
    final ClientModel client = clientSession.getClient();
    DockerResponseToken responseToken = new DockerResponseToken().id(KeycloakModelUtils.generateId()).type(TokenUtil.TOKEN_TYPE_BEARER).issuer(authSession.getClientNote(DockerAuthV2Protocol.ISSUER)).subject(userSession.getUser().getUsername()).issuedNow().audience(client.getClientId()).issuedFor(client.getClientId());
    // since realm access token is given in seconds
    final int accessTokenLifespan = realm.getAccessTokenLifespan();
    responseToken.notBefore(responseToken.getIssuedAt()).expiration(responseToken.getIssuedAt() + accessTokenLifespan);
    // Next, allow mappers to decorate the token to add/remove scopes as appropriate
    AtomicReference<DockerResponseToken> finalResponseToken = new AtomicReference<>(responseToken);
    ProtocolMapperUtils.getSortedProtocolMappers(session, clientSessionCtx).filter(mapper -> mapper.getValue() instanceof DockerAuthV2AttributeMapper).filter(mapper -> ((DockerAuthV2AttributeMapper) mapper.getValue()).appliesTo(finalResponseToken.get())).forEach(mapper -> finalResponseToken.set(((DockerAuthV2AttributeMapper) mapper.getValue()).transformDockerResponseToken(finalResponseToken.get(), mapper.getKey(), session, userSession, clientSession)));
    responseToken = finalResponseToken.get();
    try {
        // Finally, construct the response to the docker client with the token + metadata
        if (event.getEvent() != null && EventType.LOGIN.equals(event.getEvent().getType())) {
            final KeyManager.ActiveRsaKey activeKey = session.keys().getActiveRsaKey(realm);
            final String encodedToken = new JWSBuilder().kid(new DockerKeyIdentifier(activeKey.getPublicKey()).toString()).type("JWT").jsonContent(responseToken).rsa256(activeKey.getPrivateKey());
            final String expiresInIso8601String = new SimpleDateFormat(ISO_8601_DATE_FORMAT).format(new Date(responseToken.getIssuedAt() * 1000L));
            final DockerResponse responseEntity = new DockerResponse().setToken(encodedToken).setExpires_in(accessTokenLifespan).setIssued_at(expiresInIso8601String);
            return new ResponseBuilderImpl().status(Response.Status.OK).header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON).entity(responseEntity).build();
        } else {
            logger.errorv("Unable to handle request for event type {0}.  Currently only LOGIN event types are supported by docker protocol.", event.getEvent() == null ? "null" : event.getEvent().getType());
            throw new ErrorResponseException("invalid_request", "Event type not supported", Response.Status.BAD_REQUEST);
        }
    } catch (final InstantiationException e) {
        logger.errorv("Error attempting to create Key ID for Docker JOSE header: ", e.getMessage());
        throw new ErrorResponseException("token_error", "Unable to construct JOSE header for JWT", Response.Status.INTERNAL_SERVER_ERROR);
    }
}
Also used : DockerAuthV2AttributeMapper(org.keycloak.protocol.docker.mapper.DockerAuthV2AttributeMapper) ClientModel(org.keycloak.models.ClientModel) KeycloakModelUtils(org.keycloak.models.utils.KeycloakModelUtils) Date(java.util.Date) Logger(org.jboss.logging.Logger) SimpleDateFormat(java.text.SimpleDateFormat) ResponseBuilderImpl(org.jboss.resteasy.specimpl.ResponseBuilderImpl) AtomicReference(java.util.concurrent.atomic.AtomicReference) KeyManager(org.keycloak.models.KeyManager) TokenUtil(org.keycloak.util.TokenUtil) MediaType(javax.ws.rs.core.MediaType) ClientSessionContext(org.keycloak.models.ClientSessionContext) JWSBuilder(org.keycloak.jose.jws.JWSBuilder) EventBuilder(org.keycloak.events.EventBuilder) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) ErrorResponseException(org.keycloak.services.ErrorResponseException) DockerResponseToken(org.keycloak.representations.docker.DockerResponseToken) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) KeycloakSession(org.keycloak.models.KeycloakSession) EventType(org.keycloak.events.EventType) UserSessionModel(org.keycloak.models.UserSessionModel) DockerResponse(org.keycloak.representations.docker.DockerResponse) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) ProtocolMapperUtils(org.keycloak.protocol.ProtocolMapperUtils) UriInfo(javax.ws.rs.core.UriInfo) DockerAuthV2AttributeMapper(org.keycloak.protocol.docker.mapper.DockerAuthV2AttributeMapper) LoginProtocol(org.keycloak.protocol.LoginProtocol) DockerResponse(org.keycloak.representations.docker.DockerResponse) AuthenticatedClientSessionModel(org.keycloak.models.AuthenticatedClientSessionModel) AtomicReference(java.util.concurrent.atomic.AtomicReference) DockerResponseToken(org.keycloak.representations.docker.DockerResponseToken) Date(java.util.Date) JWSBuilder(org.keycloak.jose.jws.JWSBuilder) ClientModel(org.keycloak.models.ClientModel) ResponseBuilderImpl(org.jboss.resteasy.specimpl.ResponseBuilderImpl) ErrorResponseException(org.keycloak.services.ErrorResponseException) KeyManager(org.keycloak.models.KeyManager) SimpleDateFormat(java.text.SimpleDateFormat)

Example 25 with AuthenticationSessionModel

use of org.keycloak.sessions.AuthenticationSessionModel 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)

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