use of org.keycloak.events.EventBuilder in project keycloak by keycloak.
the class AuthenticationManager method finishBrowserLogout.
public static Response finishBrowserLogout(KeycloakSession session, RealmModel realm, UserSessionModel userSession, UriInfo uriInfo, ClientConnection connection, HttpHeaders headers) {
final AuthenticationSessionManager asm = new AuthenticationSessionManager(session);
AuthenticationSessionModel logoutAuthSession = createOrJoinLogoutSession(session, realm, asm, userSession, true);
checkUserSessionOnlyHasLoggedOutClients(realm, userSession, logoutAuthSession);
// For resolving artifact we don't need any cookie, all details are stored in session storage so we can remove
expireIdentityCookie(realm, uriInfo, connection);
expireRememberMeCookie(realm, uriInfo, connection);
String method = userSession.getNote(KEYCLOAK_LOGOUT_PROTOCOL);
EventBuilder event = new EventBuilder(realm, session, connection);
LoginProtocol protocol = session.getProvider(LoginProtocol.class, method);
protocol.setRealm(realm).setHttpHeaders(headers).setUriInfo(uriInfo).setEventBuilder(event);
Response response = protocol.finishLogout(userSession);
// It may be possible that there are some client sessions that are still in LOGGING_OUT state
long numberOfUnconfirmedSessions = userSession.getAuthenticatedClientSessions().values().stream().filter(clientSessionModel -> CommonClientSessionModel.Action.LOGGING_OUT.name().equals(clientSessionModel.getAction())).count();
// If logout flow end up correctly there should be at maximum 1 client session in LOGGING_OUT action, if there are more, something went wrong
if (numberOfUnconfirmedSessions > 1) {
logger.warnf("There are more than one clientSession in logging_out state. Perhaps some client did not finish logout flow correctly.");
}
// LOGGED_OUT action can remove UserSession
if (numberOfUnconfirmedSessions >= 1) {
userSession.setState(UserSessionModel.State.LOGGED_OUT_UNCONFIRMED);
} else {
userSession.setState(UserSessionModel.State.LOGGED_OUT);
}
// Do not remove user session, it will be removed when last clientSession will be logged out
if (numberOfUnconfirmedSessions < 1) {
session.sessions().removeUserSession(realm, userSession);
}
session.authenticationSessions().removeRootAuthenticationSession(realm, logoutAuthSession.getParentSession());
return response;
}
use of org.keycloak.events.EventBuilder 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.events.EventBuilder in project keycloak by keycloak.
the class ConsoleUpdatePassword method processAction.
@Override
public void processAction(RequiredActionContext context) {
EventBuilder event = context.getEvent();
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(context.getAuthenticationSession().getClient()).user(context.getAuthenticationSession().getAuthenticatedUser());
if (Validation.isBlank(passwordNew)) {
context.challenge(challenge(context).message(Messages.MISSING_PASSWORD));
errorEvent.error(Errors.PASSWORD_MISSING);
return;
} else if (!passwordNew.equals(passwordConfirm)) {
context.challenge(challenge(context).message(Messages.NOTMATCH_PASSWORD));
errorEvent.error(Errors.PASSWORD_CONFIRM_ERROR);
return;
}
try {
context.getSession().userCredentialManager().updateCredential(context.getRealm(), context.getUser(), UserCredentialModel.password(passwordNew, false));
context.success();
} catch (ModelException me) {
errorEvent.detail(Details.REASON, me.getMessage()).error(Errors.PASSWORD_REJECTED);
context.challenge(challenge(context).text(me.getMessage()));
return;
} catch (Exception ape) {
errorEvent.detail(Details.REASON, ape.getMessage()).error(Errors.PASSWORD_REJECTED);
context.challenge(challenge(context).text(ape.getMessage()));
return;
}
}
use of org.keycloak.events.EventBuilder in project keycloak by keycloak.
the class ConsoleUpdateTotp method processAction.
@Override
public void processAction(RequiredActionContext context) {
EventBuilder event = context.getEvent();
event.event(EventType.UPDATE_TOTP);
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
String challengeResponse = formData.getFirst("totp");
String totpSecret = context.getAuthenticationSession().getAuthNote("totpSecret");
String userLabel = formData.getFirst("userLabel");
OTPPolicy policy = context.getRealm().getOTPPolicy();
OTPCredentialModel credentialModel = OTPCredentialModel.createFromPolicy(context.getRealm(), totpSecret, userLabel);
if (Validation.isBlank(challengeResponse)) {
context.challenge(challenge(context).message(Messages.MISSING_TOTP));
return;
} else if (!CredentialValidation.validOTP(challengeResponse, credentialModel, policy.getLookAheadWindow())) {
context.challenge(challenge(context).message(Messages.INVALID_TOTP));
return;
}
if (!CredentialHelper.createOTPCredential(context.getSession(), context.getRealm(), context.getUser(), challengeResponse, credentialModel)) {
context.challenge(challenge(context).message(Messages.INVALID_TOTP));
return;
}
context.getAuthenticationSession().removeAuthNote("totpSecret");
context.success();
}
use of org.keycloak.events.EventBuilder in project keycloak by keycloak.
the class UpdateProfile method processAction.
@Override
public void processAction(RequiredActionContext context) {
EventBuilder event = context.getEvent();
event.event(EventType.UPDATE_PROFILE).detail(Details.CONTEXT, UserProfileContext.UPDATE_PROFILE.name());
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
UserModel user = context.getUser();
UserProfileProvider provider = context.getSession().getProvider(UserProfileProvider.class);
UserProfile profile = provider.create(UserProfileContext.UPDATE_PROFILE, formData, user);
try {
// backward compatibility with old account console where attributes are not removed if missing
profile.update(false, new EventAuditingAttributeChangeListener(profile, event));
context.success();
} catch (ValidationException pve) {
List<FormMessage> errors = Validation.getFormErrorsFromValidation(pve.getErrors());
context.challenge(createResponse(context, formData, errors));
}
}
Aggregations