use of org.keycloak.services.managers.UserSessionManager in project keycloak by keycloak.
the class UserSessionProviderOfflineModelTest method testLoadUserSessionsWithNotDeletedOfflineClientSessions.
@Test
public void testLoadUserSessionsWithNotDeletedOfflineClientSessions() {
// Suspend periodic tasks to avoid race-conditions, which may cause missing updates of lastSessionRefresh times to UserSessionPersisterProvider
TimerProvider timer = kcSession.getProvider(TimerProvider.class);
TimerProvider.TimerTaskContext timerTaskCtx = null;
if (timer != null) {
timerTaskCtx = timer.cancelTask(PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
log.info("Cancelled periodic task " + PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
}
InfinispanTestUtil.setTestingTimeService(kcSession);
try {
UserSessionModel[] origSessions = inComittedTransaction(session -> {
// Create some online sessions in infinispan
return UserSessionPersisterProviderTest.createSessions(session, realmId);
});
inComittedTransaction(session -> {
RealmModel realm = session.realms().getRealm(realmId);
sessionManager = new UserSessionManager(session);
persister = session.getProvider(UserSessionPersisterProvider.class);
session.sessions().getUserSessionsStream(realm, realm.getClientByClientId("test-app")).collect(Collectors.toList()).forEach(userSession -> createOfflineSessionIncludeClientSessions(session, userSession));
});
log.info("Persisted 3 sessions to UserSessionPersisterProvider");
inComittedTransaction(session -> {
persister = session.getProvider(UserSessionPersisterProvider.class);
Assert.assertEquals(3, persister.getUserSessionsCount(true));
});
inComittedTransaction(session -> {
RealmModel realm = session.realms().getRealm(realmId);
persister = session.getProvider(UserSessionPersisterProvider.class);
// Expire everything except offline client sessions
Time.setOffset(7000000);
persister.removeExpired(realm);
});
inComittedTransaction(session -> {
RealmModel realm = session.realms().getRealm(realmId);
sessionManager = new UserSessionManager(session);
persister = session.getProvider(UserSessionPersisterProvider.class);
Assert.assertEquals(0, persister.getUserSessionsCount(true));
// create two offline user sessions
UserSessionModel userSession = session.sessions().createUserSession(realm, session.users().getUserByUsername(realm, "user1"), "user1", "ip1", null, false, null, null);
session.sessions().createOfflineUserSession(userSession);
session.sessions().createOfflineUserSession(origSessions[0]);
// try to load user session from persister
Assert.assertEquals(2, persister.loadUserSessionsStream(0, 10, true, "00000000-0000-0000-0000-000000000000").count());
});
} finally {
Time.setOffset(0);
kcSession.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent());
if (timer != null) {
timer.schedule(timerTaskCtx.getRunnable(), timerTaskCtx.getIntervalMillis(), PersisterLastSessionRefreshStoreFactory.DB_LSR_PERIODIC_TASK_NAME);
}
InfinispanTestUtil.revertTimeService();
}
}
use of org.keycloak.services.managers.UserSessionManager in project keycloak by keycloak.
the class LogoutEndpoint method logoutToken.
/**
* Logout a session via a non-browser invocation. Similar signature to refresh token except there is no grant_type.
* You must pass in the refresh token and
* authenticate the client if it is not public.
*
* If the client is a confidential client
* you must include the client-id and secret in an Basic Auth Authorization header.
*
* If the client is a public client, then you must include a "client_id" form parameter.
*
* returns 204 if successful, 400 if not with a json error response.
*
* @return
*/
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response logoutToken() {
cors = Cors.add(request).auth().allowedMethods("POST").auth().exposedHeaders(Cors.ACCESS_CONTROL_ALLOW_METHODS);
MultivaluedMap<String, String> form = request.getDecodedFormParameters();
checkSsl();
event.event(EventType.LOGOUT);
ClientModel client = authorizeClient();
String refreshToken = form.getFirst(OAuth2Constants.REFRESH_TOKEN);
if (refreshToken == null) {
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, OAuthErrorException.INVALID_REQUEST, "No refresh token", Response.Status.BAD_REQUEST);
}
try {
session.clientPolicy().triggerOnEvent(new LogoutRequestContext(form));
} catch (ClientPolicyException cpe) {
throw new CorsErrorResponseException(cors, cpe.getError(), cpe.getErrorDetail(), cpe.getErrorStatus());
}
RefreshToken token = null;
try {
// KEYCLOAK-6771 Certificate Bound Token
token = tokenManager.verifyRefreshToken(session, realm, client, request, refreshToken, false);
boolean offline = TokenUtil.TOKEN_TYPE_OFFLINE.equals(token.getType());
UserSessionModel userSessionModel;
if (offline) {
UserSessionManager sessionManager = new UserSessionManager(session);
userSessionModel = sessionManager.findOfflineUserSession(realm, token.getSessionState());
} else {
userSessionModel = session.sessions().getUserSession(realm, token.getSessionState());
}
if (userSessionModel != null) {
checkTokenIssuedAt(token, userSessionModel);
logout(userSessionModel, offline);
}
} catch (OAuthErrorException e) {
// KEYCLOAK-6771 Certificate Bound Token
if (MtlsHoKTokenUtil.CERT_VERIFY_ERROR_DESC.equals(e.getDescription())) {
event.error(Errors.NOT_ALLOWED);
throw new CorsErrorResponseException(cors, e.getError(), e.getDescription(), Response.Status.UNAUTHORIZED);
} else {
event.error(Errors.INVALID_TOKEN);
throw new CorsErrorResponseException(cors, e.getError(), e.getDescription(), Response.Status.BAD_REQUEST);
}
}
return cors.builder(Response.noContent()).build();
}
use of org.keycloak.services.managers.UserSessionManager in project keycloak by keycloak.
the class LogoutEndpoint method logoutOfflineUserSessions.
private void logoutOfflineUserSessions(String brokerUserId) {
UserSessionManager userSessionManager = new UserSessionManager(session);
session.sessions().getOfflineUserSessionByBrokerUserIdStream(realm, brokerUserId).collect(Collectors.toList()).forEach(userSessionManager::revokeOfflineUserSession);
}
use of org.keycloak.services.managers.UserSessionManager in project keycloak by keycloak.
the class UserResource method getConsents.
/**
* Get consents granted by the user
*
* @return
*/
@Path("consents")
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Stream<Map<String, Object>> getConsents() {
auth.users().requireView(user);
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
Set<ClientModel> clientsWithUserConsents = new HashSet<>();
List<UserConsentModel> userConsents = session.users().getConsentsStream(realm, user.getId()).peek(ucm -> clientsWithUserConsents.add(ucm.getClient())).collect(Collectors.toList());
return Stream.concat(userConsents.stream().map(consent -> toConsent(consent, offlineClients)), offlineClients.stream().filter(c -> !clientsWithUserConsents.contains(c)).map(this::toConsent));
}
use of org.keycloak.services.managers.UserSessionManager in project keycloak by keycloak.
the class UserSessionProviderOfflineTest method createOfflineSessionIncludeClientSessions.
private static Set<String> createOfflineSessionIncludeClientSessions(KeycloakSession session, UserSessionModel userSession) {
Set<String> offlineSessions = new HashSet<>();
UserSessionManager localManager = new UserSessionManager(session);
for (AuthenticatedClientSessionModel clientSession : userSession.getAuthenticatedClientSessions().values()) {
localManager.createOrUpdateOfflineSession(clientSession, userSession);
offlineSessions.add(clientSession.getClient().getId());
}
return offlineSessions;
}
Aggregations