-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a3aca9a
commit 990a5a4
Showing
3 changed files
with
149 additions
and
0 deletions.
There are no files selected for viewing
72 changes: 72 additions & 0 deletions
72
...4/services/src/main/java/com/github/bcgov/keycloak/authenticators/UserSessionRemover.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package com.github.bcgov.keycloak.authenticators; | ||
|
||
import org.jboss.logging.Logger; | ||
import org.keycloak.authentication.Authenticator; | ||
import org.keycloak.models.KeycloakSession; | ||
import org.keycloak.models.RealmModel; | ||
import org.keycloak.models.UserModel; | ||
import org.keycloak.models.UserSessionProvider; | ||
import org.keycloak.services.managers.AuthenticationManager; | ||
import org.keycloak.authentication.AuthenticationFlowContext; | ||
import org.keycloak.sessions.AuthenticationSessionModel; | ||
|
||
import java.util.Map; | ||
|
||
public class UserSessionRemover implements Authenticator { | ||
|
||
private static final Logger logger = Logger.getLogger(UserSessionRemover.class); | ||
|
||
@Override | ||
public boolean requiresUser() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public void authenticate(AuthenticationFlowContext context) { | ||
AuthenticationSessionModel session = context.getAuthenticationSession(); | ||
AuthenticationManager.AuthResult authResult = AuthenticationManager.authenticateIdentityCookie( | ||
context.getSession(), | ||
context.getRealm(), | ||
true | ||
); | ||
|
||
// 1. If no Cookie session, proceed to next step | ||
if (authResult == null) { | ||
context.attempted(); | ||
return; | ||
} | ||
|
||
// Need to use the KeycloakSession context to get the authenticating client ID. Not available on the AuthenticationFlowContext. | ||
KeycloakSession keycloakSession = context.getSession(); | ||
String authenticatingClientUUID = keycloakSession.getContext().getClient().getId(); | ||
|
||
// Get all existing sessions. If any session is associated with a different client, clear all user sessions. | ||
UserSessionProvider userSessionProvider = keycloakSession.sessions(); | ||
Map<String, Long> activeClientSessionStats = userSessionProvider.getActiveClientSessionStats(context.getRealm(), false); | ||
|
||
for (String activeSessionClientUUID : activeClientSessionStats.keySet()) { | ||
if (!activeSessionClientUUID.equals(authenticatingClientUUID)) { | ||
userSessionProvider.removeUserSession(context.getRealm(), authResult.getSession()); | ||
} | ||
} | ||
|
||
context.attempted(); | ||
} | ||
|
||
@Override | ||
public void action(AuthenticationFlowContext context) { | ||
} | ||
|
||
@Override | ||
public boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user) { | ||
return true; | ||
} | ||
|
||
@Override | ||
public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) { | ||
} | ||
|
||
@Override | ||
public void close() { | ||
} | ||
} |
76 changes: 76 additions & 0 deletions
76
...ces/src/main/java/com/github/bcgov/keycloak/authenticators/UserSessionRemoverFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package com.github.bcgov.keycloak.authenticators; | ||
|
||
import java.util.List; | ||
import org.keycloak.Config; | ||
import org.keycloak.authentication.Authenticator; | ||
import org.keycloak.authentication.AuthenticatorFactory; | ||
import org.keycloak.models.AuthenticationExecutionModel.Requirement; | ||
import org.keycloak.models.KeycloakSession; | ||
import org.keycloak.models.KeycloakSessionFactory; | ||
import org.keycloak.provider.ProviderConfigProperty; | ||
|
||
public class UserSessionRemoverFactory implements AuthenticatorFactory { | ||
|
||
protected static final Requirement[] REQUIREMENT_CHOICES = { | ||
Requirement.REQUIRED, Requirement.ALTERNATIVE, Requirement.DISABLED | ||
}; | ||
|
||
private static final Authenticator AUTHENTICATOR_INSTANCE = new UserSessionRemover(); | ||
|
||
@Override | ||
public String getId() { | ||
return "user-session-remover"; | ||
} | ||
|
||
@Override | ||
public String getDisplayType() { | ||
return "User Session Remover"; | ||
} | ||
|
||
@Override | ||
public String getHelpText() { | ||
return "Checks if the user session is realted to any other client, and removes it if so."; | ||
} | ||
|
||
@Override | ||
public Authenticator create(KeycloakSession session) { | ||
return AUTHENTICATOR_INSTANCE; | ||
} | ||
|
||
@Override | ||
public Requirement[] getRequirementChoices() { | ||
return REQUIREMENT_CHOICES; | ||
} | ||
|
||
@Override | ||
public List<ProviderConfigProperty> getConfigProperties() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public String getReferenceCategory() { | ||
return null; | ||
} | ||
|
||
@Override | ||
public boolean isConfigurable() { | ||
return false; | ||
} | ||
|
||
@Override | ||
public boolean isUserSetupAllowed() { | ||
return true; | ||
} | ||
|
||
@Override | ||
public void init(Config.Scope config) { | ||
} | ||
|
||
@Override | ||
public void postInit(KeycloakSessionFactory factory) { | ||
} | ||
|
||
@Override | ||
public void close() { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters