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