mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
UserSessionProvider.removeUserSessions now removes all user sessions (both regular and offline)
Closes #31359 Signed-off-by: Stefan Guilhen <sguilhen@redhat.com>
This commit is contained in:
parent
3c2e53136b
commit
9861acc2aa
@ -92,3 +92,9 @@ expect the database schema being updated to add a new column `DETAILS_JSON` to t
|
||||
The key providers that allow to import externally generated keys (`rsa` and `java-keystore` factories) now check the validity of the associated certificate if present. Therefore a key with a certificate that is expired cannot be imported in {project_name} anymore. If the certificate expires at runtime, the key is converted into a passive key (enabled but not active). A passive key is not used for new tokens, but it is still valid for validating previous issued tokens.
|
||||
|
||||
The default `generated` key providers generate a certificate valid for 10 years (the types that have or can have an associated certificate). Because of the long validity and the recommendation to rotate keys frequently, the generated providers do not perform this check.
|
||||
|
||||
= Sign out all active sessions in admin console now effectively removes all sessions
|
||||
|
||||
In previous versions, clicking on `Sign out all active sessions` in the admin console resulted in the removal of regular sessions only. Offline sessions would still be displayed despite being effectively invalidated.
|
||||
|
||||
This has been changed and now all sessions, regular and offline, are removed when signing out of all active sessions.
|
||||
|
||||
@ -624,6 +624,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider, Sessi
|
||||
|
||||
protected void onRemoveUserSessionsEvent(String realmId) {
|
||||
removeLocalUserSessions(realmId, false);
|
||||
removeLocalUserSessions(realmId, true);
|
||||
}
|
||||
|
||||
// public for usage in the testsuite
|
||||
|
||||
@ -485,7 +485,7 @@ public class PersistentUserSessionProvider implements UserSessionProvider, Sessi
|
||||
RemoveUserSessionsEvent.createEvent(RemoveUserSessionsEvent.class, InfinispanUserSessionProviderFactory.REMOVE_USER_SESSIONS_EVENT, session, realm.getId(), true),
|
||||
ClusterProvider.DCNotify.ALL_DCS);
|
||||
|
||||
session.getProvider(UserSessionPersisterProvider.class).removeUserSessions(realm, false);
|
||||
session.getProvider(UserSessionPersisterProvider.class).removeUserSessions(realm);
|
||||
}
|
||||
|
||||
protected void onRemoveUserSessionsEvent(String realmId) {
|
||||
|
||||
@ -195,7 +195,7 @@ public class RemoteUserSessionProvider implements UserSessionProvider {
|
||||
|
||||
@Override
|
||||
public void removeUserSessions(RealmModel realm) {
|
||||
transaction.removeOnlineSessionsByRealmId(realm.getId());
|
||||
transaction.removeAllSessionsByRealmId(realm.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -191,13 +191,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
|
||||
|
||||
@Override
|
||||
public void onRealmRemoved(RealmModel realm) {
|
||||
em.createNamedQuery("deleteClientSessionsByRealm")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
|
||||
em.createNamedQuery("deleteUserSessionsByRealm")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
this.removeUserSessions(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -760,6 +754,15 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUserSessions(RealmModel realm) {
|
||||
em.createNamedQuery("deleteClientSessionsByRealm")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
em.createNamedQuery("deleteUserSessionsByRealm")
|
||||
.setParameter("realmId", realm.getId())
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
@ -147,4 +147,12 @@ public interface UserSessionPersisterProvider extends Provider {
|
||||
// TODO: remove default implementation
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all user sessions from the specified realm.
|
||||
*/
|
||||
default void removeUserSessions(RealmModel realm) {
|
||||
removeUserSessions(realm, true);
|
||||
removeUserSessions(realm, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -151,9 +151,28 @@ public interface UserSessionProvider extends Provider {
|
||||
*/
|
||||
void removeExpired(RealmModel realm);
|
||||
|
||||
/**
|
||||
* Removes all user sessions (regular and offline) from the specified realm.
|
||||
*
|
||||
* @param realm the realm whose sessions are to be removed.
|
||||
*/
|
||||
void removeUserSessions(RealmModel realm);
|
||||
|
||||
/**
|
||||
* Callback method invoked when a realm is removed. Implementations should clear any sessions associated with the removed
|
||||
* realm.
|
||||
*
|
||||
* @param realm a reference to the realm being removed.
|
||||
*/
|
||||
void onRealmRemoved(RealmModel realm);
|
||||
|
||||
/**
|
||||
* Callback method invoked when a client is removed. Implementations should clear any sessions associated with the
|
||||
* removed client.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param client a reference to the client being removed.
|
||||
*/
|
||||
void onClientRemoved(RealmModel realm, ClientModel client);
|
||||
|
||||
/** Newly created userSession won't contain attached AuthenticatedClientSessions **/
|
||||
|
||||
@ -603,7 +603,7 @@ public class OfflineTokenTest extends AbstractKeycloakTest {
|
||||
setTimeOffset(86400);
|
||||
|
||||
// Remove expired sessions. This will remove "normal" userSession
|
||||
testingClient.testing().removeUserSessions("test");
|
||||
testingClient.testing().removeExpired("test");
|
||||
|
||||
// Refresh with the offline token
|
||||
tokenResponse = oauth.doRefreshTokenRequest(tokenResponse.getRefreshToken(), "secret1");
|
||||
|
||||
@ -708,7 +708,7 @@ public class UserInfoTest extends AbstractKeycloakTest {
|
||||
try {
|
||||
AccessTokenResponse accessTokenResponse = executeGrantAccessTokenRequest(client, true, true);
|
||||
|
||||
testingClient.testing().removeUserSessions("test");
|
||||
testingClient.testing().removeExpired("test");
|
||||
|
||||
Response response = UserInfoClientUtil.executeUserInfoRequest_getMethod(client, accessTokenResponse.getToken());
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ import org.keycloak.models.UserSessionProvider;
|
||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCConfigAttributes;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.services.managers.RealmManager;
|
||||
import org.keycloak.testsuite.model.HotRodServerRule;
|
||||
import org.keycloak.testsuite.model.KeycloakModelTest;
|
||||
import org.keycloak.testsuite.model.RequireProvider;
|
||||
@ -93,10 +94,7 @@ public class SessionTimeoutsTest extends KeycloakModelTest {
|
||||
InfinispanTestUtil.revertTimeService(s);
|
||||
RealmModel realm = s.realms().getRealm(realmId);
|
||||
s.getContext().setRealm(realm);
|
||||
UserModel user1 = s.users().getUserByUsername(realm, "user1");
|
||||
s.sessions().removeUserSessions(realm);
|
||||
s.sessions().getOfflineUserSessionsStream(realm, user1).forEach(us -> s.sessions().removeOfflineUserSession(realm, us));
|
||||
s.realms().removeRealm(realmId);
|
||||
new RealmManager(s).removeRealm(realm);
|
||||
|
||||
super.cleanEnvironment(s);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user