use of org.keycloak.models.UserSessionModel in project keycloak by keycloak.
the class CibaGrantType method cibaGrant.
public Response cibaGrant() {
ProfileHelper.requireFeature(Profile.Feature.CIBA);
if (!realm.getCibaPolicy().isOIDCCIBAGrantEnabled(client)) {
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "Client not allowed OIDC CIBA Grant", Response.Status.BAD_REQUEST);
}
String jwe = formParams.getFirst(AUTH_REQ_ID);
if (jwe == null) {
event.error(Errors.INVALID_CODE);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "Missing parameter: " + AUTH_REQ_ID, Response.Status.BAD_REQUEST);
}
logger.tracev("CIBA Grant :: authReqId = {0}", jwe);
CIBAAuthenticationRequest request;
try {
request = CIBAAuthenticationRequest.deserialize(session, jwe);
} catch (Exception e) {
logger.warnf("illegal format of auth_req_id : e.getMessage() = %s", e.getMessage());
// Auth Req ID has not put onto cache, no need to remove Auth Req ID.
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "Invalid Auth Req ID", Response.Status.BAD_REQUEST);
}
request.setClient(client);
try {
session.clientPolicy().triggerOnEvent(new BackchannelTokenRequestContext(request, formParams));
} catch (ClientPolicyException cpe) {
event.error(cpe.getError());
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, cpe.getErrorDetail(), Response.Status.BAD_REQUEST);
}
OAuth2DeviceTokenStoreProvider store = session.getProvider(OAuth2DeviceTokenStoreProvider.class);
OAuth2DeviceCodeModel deviceCode = store.getByDeviceCode(realm, request.getId());
if (deviceCode == null) {
// Auth Req ID has not put onto cache, no need to remove Auth Req ID.
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "Invalid " + AUTH_REQ_ID, Response.Status.BAD_REQUEST);
}
if (!request.getIssuedFor().equals(client.getClientId())) {
logDebug("invalid client.", request);
// the client sending this Auth Req ID does not match the client to which keycloak had issued Auth Req ID.
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_GRANT, "unauthorized client", Response.Status.BAD_REQUEST);
}
if (deviceCode.isExpired()) {
logDebug("expired.", request);
throw new CorsErrorResponseException(cors, OAuthErrorException.EXPIRED_TOKEN, "authentication timed out", Response.Status.BAD_REQUEST);
}
if (!store.isPollingAllowed(deviceCode)) {
logDebug("pooling.", request);
throw new CorsErrorResponseException(cors, OAuthErrorException.SLOW_DOWN, "too early to access", Response.Status.BAD_REQUEST);
}
if (deviceCode.isDenied()) {
logDebug("denied.", request);
throw new CorsErrorResponseException(cors, OAuthErrorException.ACCESS_DENIED, "not authorized", Response.Status.BAD_REQUEST);
}
// get corresponding Authentication Channel Result entry
if (deviceCode.isPending()) {
logDebug("not yet authenticated by Authentication Device or auth_req_id has already been used to get tokens.", request);
throw new CorsErrorResponseException(cors, OAuthErrorException.AUTHORIZATION_PENDING, "The authorization request is still pending as the end-user hasn't yet been authenticated.", Response.Status.BAD_REQUEST);
}
UserSessionModel userSession = createUserSession(request, deviceCode.getAdditionalParams());
UserModel user = userSession.getUser();
store.removeDeviceCode(realm, request.getId());
// Compute client scopes again from scope parameter. Check if user still has them granted
// (but in code-to-token request, it could just theoretically happen that they are not available)
String scopeParam = request.getScope();
if (!TokenManager.verifyConsentStillAvailable(session, user, client, TokenManager.getRequestedClientScopes(scopeParam, client))) {
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_SCOPE, "Client no longer has requested consent from user", Response.Status.BAD_REQUEST);
}
ClientSessionContext clientSessionCtx = DefaultClientSessionContext.fromClientSessionAndScopeParameter(userSession.getAuthenticatedClientSessionByClient(client.getId()), scopeParam, session);
int authTime = Time.currentTime();
userSession.setNote(AuthenticationManager.AUTH_TIME, String.valueOf(authTime));
return tokenEndpoint.createTokenResponse(user, userSession, clientSessionCtx, scopeParam, true);
}
use of org.keycloak.models.UserSessionModel in project keycloak by keycloak.
the class ClaimsParameterTokenMapper method putClaims.
private void putClaims(String tokenType, String claims, IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession) {
JsonNode requestParams = null;
try {
requestParams = JsonSerialization.readValue(claims, JsonNode.class);
} catch (IOException e) {
return;
}
if (!requestParams.has(tokenType))
return;
JsonNode tokenNode = requestParams.findValue(tokenType);
OIDCWellKnownProvider.DEFAULT_CLAIMS_SUPPORTED.stream().filter(i -> tokenNode.has(i)).filter(i -> tokenNode.findValue(i).has("essential")).filter(i -> tokenNode.findValue(i).findValue("essential").isBoolean()).filter(i -> tokenNode.findValue(i).findValue("essential").asBoolean()).forEach(i -> {
// "name", "given_name", "family_name", "preferred_username", "email" need to be set explicitly using existing mapper.
if (i.equals(IDToken.NAME)) {
FullNameMapper fullNameMapper = new FullNameMapper();
fullNameMapper.setClaim(token, mappingModel, userSession);
} else if (i.equals(IDToken.GIVEN_NAME)) {
UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested firstName", "firstName", IDToken.GIVEN_NAME, "String", false, true), userSession);
} else if (i.equals(IDToken.FAMILY_NAME)) {
UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested lastName", "lastName", IDToken.FAMILY_NAME, "String", false, true), userSession);
} else if (i.equals(IDToken.PREFERRED_USERNAME)) {
UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested username", "username", IDToken.PREFERRED_USERNAME, "String", false, true), userSession);
} else if (i.equals(IDToken.EMAIL)) {
UserPropertyMapper userPropertyMapper = new UserPropertyMapper();
userPropertyMapper.setClaim(token, UserPropertyMapper.createClaimMapper("requested email", "email", IDToken.EMAIL, "String", false, true), userSession);
}
});
}
use of org.keycloak.models.UserSessionModel in project keycloak by keycloak.
the class UserResource method impersonate.
/**
* Impersonate the user
*
* @return
*/
@Path("impersonation")
@POST
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Map<String, Object> impersonate() {
ProfileHelper.requireFeature(Profile.Feature.IMPERSONATION);
auth.users().requireImpersonate(user);
RealmModel authenticatedRealm = auth.adminAuth().getRealm();
// if same realm logout before impersonation
boolean sameRealm = false;
String sessionState = auth.adminAuth().getToken().getSessionState();
if (authenticatedRealm.getId().equals(realm.getId()) && sessionState != null) {
sameRealm = true;
UserSessionModel userSession = session.sessions().getUserSession(authenticatedRealm, sessionState);
AuthenticationManager.expireIdentityCookie(realm, session.getContext().getUri(), clientConnection);
AuthenticationManager.expireRememberMeCookie(realm, session.getContext().getUri(), clientConnection);
AuthenticationManager.backchannelLogout(session, authenticatedRealm, userSession, session.getContext().getUri(), clientConnection, headers, true);
}
EventBuilder event = new EventBuilder(realm, session, clientConnection);
UserSessionModel userSession = session.sessions().createUserSession(realm, user, user.getUsername(), clientConnection.getRemoteAddr(), "impersonate", false, null, null);
UserModel adminUser = auth.adminAuth().getUser();
String impersonatorId = adminUser.getId();
String impersonator = adminUser.getUsername();
userSession.setNote(IMPERSONATOR_ID.toString(), impersonatorId);
userSession.setNote(IMPERSONATOR_USERNAME.toString(), impersonator);
AuthenticationManager.createLoginCookie(session, realm, userSession.getUser(), userSession, session.getContext().getUri(), clientConnection);
URI redirect = AccountFormService.accountServiceBaseUrl(session.getContext().getUri()).build(realm.getName());
Map<String, Object> result = new HashMap<>();
result.put("sameRealm", sameRealm);
result.put("redirect", redirect.toString());
event.event(EventType.IMPERSONATE).session(userSession).user(user).detail(Details.IMPERSONATOR_REALM, authenticatedRealm.getName()).detail(Details.IMPERSONATOR, impersonator).success();
return result;
}
use of org.keycloak.models.UserSessionModel in project keycloak by keycloak.
the class InfinispanUserSessionProvider method createClientSession.
@Override
public AuthenticatedClientSessionModel createClientSession(RealmModel realm, ClientModel client, UserSessionModel userSession) {
final UUID clientSessionId = keyGenerator.generateKeyUUID(session, clientSessionCache);
AuthenticatedClientSessionEntity entity = new AuthenticatedClientSessionEntity(clientSessionId);
entity.setRealmId(realm.getId());
entity.setTimestamp(Time.currentTime());
entity.getNotes().put(AuthenticatedClientSessionModel.STARTED_AT_NOTE, String.valueOf(entity.getTimestamp()));
InfinispanChangelogBasedTransaction<String, UserSessionEntity> userSessionUpdateTx = getTransaction(false);
InfinispanChangelogBasedTransaction<UUID, AuthenticatedClientSessionEntity> clientSessionUpdateTx = getClientSessionTransaction(false);
AuthenticatedClientSessionAdapter adapter = new AuthenticatedClientSessionAdapter(session, this, entity, client, userSession, clientSessionUpdateTx, false);
// For now, the clientSession is considered transient in case that userSession was transient
UserSessionModel.SessionPersistenceState persistenceState = (userSession instanceof UserSessionAdapter && ((UserSessionAdapter) userSession).getPersistenceState() != null) ? ((UserSessionAdapter) userSession).getPersistenceState() : UserSessionModel.SessionPersistenceState.PERSISTENT;
SessionUpdateTask<AuthenticatedClientSessionEntity> createClientSessionTask = Tasks.addIfAbsentSync();
clientSessionUpdateTx.addTask(clientSessionId, createClientSessionTask, entity, persistenceState);
SessionUpdateTask registerClientSessionTask = new RegisterClientSessionTask(client.getId(), clientSessionId);
userSessionUpdateTx.addTask(userSession.getId(), registerClientSessionTask);
return adapter;
}
use of org.keycloak.models.UserSessionModel in project keycloak by keycloak.
the class InfinispanUserSessionProvider method getUserSessionEntityFromPersistenceProvider.
private UserSessionEntity getUserSessionEntityFromPersistenceProvider(RealmModel realm, String sessionId, boolean offline) {
log.debugf("Offline user-session not found in infinispan, attempting UserSessionPersisterProvider lookup for sessionId=%s", sessionId);
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
UserSessionModel persistentUserSession = persister.loadUserSession(realm, sessionId, offline);
if (persistentUserSession == null) {
log.debugf("Offline user-session not found in UserSessionPersisterProvider for sessionId=%s", sessionId);
return null;
}
return importUserSession(realm, offline, persistentUserSession);
}
Aggregations