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();
}
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;
}
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);
}
}
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);
}
}
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);
}
}
}
Aggregations