use of org.keycloak.sessions.RootAuthenticationSessionModel in project keycloak by keycloak.
the class ActionTokenContext method createAuthenticationSessionForClient.
public AuthenticationSessionModel createAuthenticationSessionForClient(String clientId) throws UriBuilderException, IllegalArgumentException {
AuthenticationSessionModel authSession;
// set up the account service as the endpoint to call.
ClientModel client = clientId != null ? realm.getClientByClientId(clientId) : SystemClientUtil.getSystemClient(realm);
RootAuthenticationSessionModel rootAuthSession = new AuthenticationSessionManager(session).createAuthenticationSession(realm, true);
authSession = rootAuthSession.createAuthenticationSession(client);
authSession.setAction(AuthenticationSessionModel.Action.AUTHENTICATE.name());
authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
String redirectUri = Urls.accountBase(uriInfo.getBaseUri()).path("/").build(realm.getName()).toString();
authSession.setRedirectUri(redirectUri);
authSession.setClientNote(OIDCLoginProtocol.REDIRECT_URI_PARAM, redirectUri);
authSession.setClientNote(OIDCLoginProtocol.RESPONSE_TYPE_PARAM, OAuth2Constants.CODE);
authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(uriInfo.getBaseUri(), realm.getName()));
return authSession;
}
use of org.keycloak.sessions.RootAuthenticationSessionModel in project keycloak by keycloak.
the class CibaGrantType method createUserSession.
private UserSessionModel createUserSession(CIBAAuthenticationRequest request, Map<String, String> additionalParams) {
RootAuthenticationSessionModel rootAuthSession = session.authenticationSessions().createRootAuthenticationSession(realm);
// here Client Model of CD(Consumption Device) needs to be used to bind its Client Session with User Session.
AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(client);
authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
authSession.setAction(AuthenticatedClientSessionModel.Action.AUTHENTICATE.name());
authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName()));
authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, request.getScope());
if (additionalParams != null) {
for (String paramName : additionalParams.keySet()) {
authSession.setClientNote(ADDITIONAL_CALLBACK_PARAMS_PREFIX + paramName, additionalParams.get(paramName));
}
}
if (request.getOtherClaims() != null) {
for (String paramName : request.getOtherClaims().keySet()) {
authSession.setClientNote(ADDITIONAL_BACKCHANNEL_REQ_PARAMS_PREFIX + paramName, request.getOtherClaims().get(paramName).toString());
}
}
UserModel user = session.users().getUserById(realm, request.getSubject());
if (user == null) {
event.error(Errors.USERNAME_MISSING);
throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "Could not identify user", Response.Status.BAD_REQUEST);
}
if (!user.isEnabled()) {
event.error(Errors.USER_DISABLED);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "User disabled", Response.Status.BAD_REQUEST);
}
logger.debugf("CIBA Grant :: user model found. user.getId() = %s, user.getEmail() = %s, user.getUsername() = %s.", user.getId(), user.getEmail(), user.getUsername());
authSession.setAuthenticatedUser(user);
if (user.getRequiredActionsStream().count() > 0) {
event.error(Errors.RESOLVE_REQUIRED_ACTIONS);
throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "Account is not fully set up", Response.Status.BAD_REQUEST);
}
AuthenticationManager.setClientScopesInSession(authSession);
ClientSessionContext context = AuthenticationProcessor.attachSession(authSession, null, session, realm, session.getContext().getConnection(), event);
UserSessionModel userSession = context.getClientSession().getUserSession();
if (userSession == null) {
event.error(Errors.USER_SESSION_NOT_FOUND);
throw new ErrorResponseException(OAuthErrorException.INVALID_GRANT, "User session is not found", Response.Status.BAD_REQUEST);
}
// authorization (consent)
UserConsentModel grantedConsent = session.users().getConsentByClient(realm, user.getId(), client.getId());
if (grantedConsent == null) {
grantedConsent = new UserConsentModel(client);
session.users().addConsent(realm, user.getId(), grantedConsent);
if (logger.isTraceEnabled()) {
grantedConsent.getGrantedClientScopes().forEach(i -> logger.tracef("CIBA Grant :: Consent granted. %s", i.getName()));
}
}
boolean updateConsentRequired = false;
for (String clientScopeId : authSession.getClientScopes()) {
ClientScopeModel clientScope = KeycloakModelUtils.findClientScopeById(realm, client, clientScopeId);
if (clientScope != null && !grantedConsent.isClientScopeGranted(clientScope) && clientScope.isDisplayOnConsentScreen()) {
grantedConsent.addGrantedClientScope(clientScope);
updateConsentRequired = true;
}
}
if (updateConsentRequired) {
session.users().updateConsent(realm, user.getId(), grantedConsent);
if (logger.isTraceEnabled()) {
grantedConsent.getGrantedClientScopes().forEach(i -> logger.tracef("CIBA Grant :: Consent updated. %s", i.getName()));
}
}
event.detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED);
event.detail(Details.CODE_ID, userSession.getId());
event.session(userSession.getId());
event.user(user);
logger.debugf("Successfully verified Authe Req Id '%s'. User session: '%s', client: '%s'", request, userSession.getId(), client.getId());
return userSession;
}
use of org.keycloak.sessions.RootAuthenticationSessionModel in project keycloak by keycloak.
the class AuthenticationManager method backchannelLogout.
/**
* @param session
* @param realm
* @param userSession
* @param uriInfo
* @param connection
* @param headers
* @param logoutBroker
* @param offlineSession
*
* @return BackchannelLogoutResponse with logout information
*/
public static BackchannelLogoutResponse backchannelLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers, boolean logoutBroker, boolean offlineSession) {
BackchannelLogoutResponse backchannelLogoutResponse = new BackchannelLogoutResponse();
if (userSession == null) {
backchannelLogoutResponse.setLocalLogoutSucceeded(true);
return backchannelLogoutResponse;
}
UserModel user = userSession.getUser();
if (userSession.getState() != UserSessionModel.State.LOGGING_OUT) {
userSession.setState(UserSessionModel.State.LOGGING_OUT);
}
logger.debugv("Logging out: {0} ({1}) offline: {2}", user.getUsername(), userSession.getId(), userSession.isOffline());
boolean expireUserSessionCookieSucceeded = expireUserSessionCookie(session, userSession, realm, uriInfo, headers, connection);
final AuthenticationSessionManager asm = new AuthenticationSessionManager(session);
AuthenticationSessionModel logoutAuthSession = createOrJoinLogoutSession(session, realm, asm, userSession, false);
boolean userSessionOnlyHasLoggedOutClients = false;
try {
backchannelLogoutResponse = backchannelLogoutAll(session, realm, userSession, logoutAuthSession, uriInfo, headers, logoutBroker);
userSessionOnlyHasLoggedOutClients = checkUserSessionOnlyHasLoggedOutClients(realm, userSession, logoutAuthSession);
} finally {
RootAuthenticationSessionModel rootAuthSession = logoutAuthSession.getParentSession();
rootAuthSession.removeAuthenticationSessionByTabId(logoutAuthSession.getTabId());
}
userSession.setState(UserSessionModel.State.LOGGED_OUT);
if (offlineSession) {
new UserSessionManager(session).revokeOfflineUserSession(userSession);
// Check if "online" session still exists and remove it too
String onlineUserSessionId = userSession.getNote(CORRESPONDING_SESSION_ID);
UserSessionModel onlineUserSession = (onlineUserSessionId != null) ? session.sessions().getUserSession(realm, onlineUserSessionId) : session.sessions().getUserSession(realm, userSession.getId());
if (onlineUserSession != null) {
session.sessions().removeUserSession(realm, onlineUserSession);
}
} else {
session.sessions().removeUserSession(realm, userSession);
}
backchannelLogoutResponse.setLocalLogoutSucceeded(expireUserSessionCookieSucceeded && userSessionOnlyHasLoggedOutClients);
return backchannelLogoutResponse;
}
use of org.keycloak.sessions.RootAuthenticationSessionModel 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();
}
use of org.keycloak.sessions.RootAuthenticationSessionModel 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;
}
Aggregations