Fix multi-tenancy on EAP63/AS7
This commit is contained in:
parent
44d4f6eb95
commit
82af7cbfa2
7 changed files with 37 additions and 31 deletions
|
@ -1,7 +1,7 @@
|
|||
Keycloak Example - Multi Tenancy
|
||||
=======================================
|
||||
|
||||
The following example was tested on Wildfly 8.1.0.Final and should be compatible with any JBoss AS, JBoss EAP or Wildfly that supports Java EE 7.
|
||||
The following example was tested on Wildfly 8.1.0.Final and JBoss EAP 6.3. It should be compatible with any JBoss AS, JBoss EAP or Wildfly that supports Java EE 7.
|
||||
|
||||
This example demonstrates the simplest possible scenario for Keycloak Multi Tenancy support. Multi Tenancy is understood on this context as a single application (WAR) that is deployed on a single or clustered application server, authenticating users from *different realms* against a single or clustered Keycloak server.
|
||||
|
||||
|
|
|
@ -49,6 +49,12 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
|
|||
if (authenticatedPrincipal != null) {
|
||||
log.debug("remote logged in already. Establish state from cookie");
|
||||
RefreshableKeycloakSecurityContext securityContext = authenticatedPrincipal.getKeycloakSecurityContext();
|
||||
|
||||
if (!securityContext.getRealm().equals(deployment.getRealm())) {
|
||||
log.debug("Account from cookie is from a different realm than for the request.");
|
||||
return false;
|
||||
}
|
||||
|
||||
securityContext.setCurrentRequestInfo(deployment, this);
|
||||
Set<String> roles = AdapterUtils.getRolesFromSecurityContext(securityContext);
|
||||
GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), authenticatedPrincipal, roles, securityContext);
|
||||
|
@ -97,11 +103,6 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
|
|||
|
||||
RefreshableKeycloakSecurityContext session = principal.getKeycloakSecurityContext();
|
||||
|
||||
if (!session.getRealm().equals(deployment.getRealm())) {
|
||||
log.debug("Account from cookie is from a different realm than for the request.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) return principal;
|
||||
boolean success = session.refreshExpiredToken(false);
|
||||
if (success && session.isActive()) return principal;
|
||||
|
|
|
@ -38,11 +38,6 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore {
|
|||
RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) request.getSessionInternal().getNote(KeycloakSecurityContext.class.getName());
|
||||
if (session == null) return;
|
||||
|
||||
if (!deployment.getRealm().equals(session.getRealm())) {
|
||||
log.debug("Account from cookie is from a different realm than for the request.");
|
||||
return;
|
||||
}
|
||||
|
||||
// just in case session got serialized
|
||||
if (session.getDeployment() == null) session.setCurrentRequestInfo(deployment, this);
|
||||
|
||||
|
@ -69,16 +64,23 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore {
|
|||
if (request.getSessionInternal(false) == null || request.getSessionInternal().getPrincipal() == null)
|
||||
return false;
|
||||
log.debug("remote logged in already. Establish state from session");
|
||||
GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||
request.setUserPrincipal(principal);
|
||||
request.setAuthType("KEYCLOAK");
|
||||
|
||||
RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext) request.getSessionInternal().getNote(KeycloakSecurityContext.class.getName());
|
||||
if (securityContext != null) {
|
||||
|
||||
if (!deployment.getRealm().equals(securityContext.getRealm())) {
|
||||
log.debug("Account from cookie is from a different realm than for the request.");
|
||||
return false;
|
||||
}
|
||||
|
||||
securityContext.setCurrentRequestInfo(deployment, this);
|
||||
request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext);
|
||||
}
|
||||
|
||||
GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||
request.setUserPrincipal(principal);
|
||||
request.setAuthType("KEYCLOAK");
|
||||
|
||||
((CatalinaRequestAuthenticator)authenticator).restoreRequest();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -66,12 +66,12 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
public void logout(Request request) throws ServletException {
|
||||
KeycloakSecurityContext ksc = (KeycloakSecurityContext)request.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
if (ksc != null) {
|
||||
request.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(request, null);
|
||||
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
|
||||
|
||||
AdapterTokenStore tokenStore = getTokenStore(request, facade, deployment);
|
||||
tokenStore.logout();
|
||||
request.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
}
|
||||
super.logout(request);
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
// 4) The deployment doesn't have a keycloak.config.resolver nor keycloak.json (or equivalent)
|
||||
// Outcome: adapter is left unconfigured
|
||||
|
||||
String configResolverClass = (String) context.getServletContext().getAttribute("keycloak.config.resolver");
|
||||
String configResolverClass = context.getServletContext().getInitParameter("keycloak.config.resolver");
|
||||
if (configResolverClass != null) {
|
||||
try {
|
||||
KeycloakConfigResolver configResolver = (KeycloakConfigResolver) context.getLoader().getClassLoader().loadClass(configResolverClass).newInstance();
|
||||
|
|
|
@ -47,6 +47,12 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
|
|||
if (authenticatedPrincipal != null) {
|
||||
log.fine("remote logged in already. Establish state from cookie");
|
||||
RefreshableKeycloakSecurityContext securityContext = authenticatedPrincipal.getKeycloakSecurityContext();
|
||||
|
||||
if (!securityContext.getRealm().equals(deployment.getRealm())) {
|
||||
log.fine("Account from cookie is from a different realm than for the request.");
|
||||
return false;
|
||||
}
|
||||
|
||||
securityContext.setCurrentRequestInfo(deployment, this);
|
||||
Set<String> roles = AdapterUtils.getRolesFromSecurityContext(securityContext);
|
||||
GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), authenticatedPrincipal, roles, securityContext);
|
||||
|
@ -95,11 +101,6 @@ public class CatalinaCookieTokenStore implements AdapterTokenStore {
|
|||
|
||||
RefreshableKeycloakSecurityContext session = principal.getKeycloakSecurityContext();
|
||||
|
||||
if (!session.getRealm().equals(deployment.getRealm())) {
|
||||
log.fine("Account from cookie is from a different realm than for the request.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (session.isActive() && !session.getDeployment().isAlwaysRefreshToken()) return principal;
|
||||
boolean success = session.refreshExpiredToken(false);
|
||||
if (success && session.isActive()) return principal;
|
||||
|
|
|
@ -36,11 +36,6 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore {
|
|||
RefreshableKeycloakSecurityContext session = (RefreshableKeycloakSecurityContext) request.getSessionInternal().getNote(KeycloakSecurityContext.class.getName());
|
||||
if (session == null) return;
|
||||
|
||||
if (!deployment.getRealm().equals(session.getRealm())) {
|
||||
log.fine("Account from cookie is from a different realm than for the request.");
|
||||
return;
|
||||
}
|
||||
|
||||
// just in case session got serialized
|
||||
if (session.getDeployment() == null) session.setCurrentRequestInfo(deployment, this);
|
||||
|
||||
|
@ -67,16 +62,23 @@ public class CatalinaSessionTokenStore implements AdapterTokenStore {
|
|||
if (request.getSessionInternal(false) == null || request.getSessionInternal().getPrincipal() == null)
|
||||
return false;
|
||||
log.fine("remote logged in already. Establish state from session");
|
||||
GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||
request.setUserPrincipal(principal);
|
||||
request.setAuthType("KEYCLOAK");
|
||||
|
||||
RefreshableKeycloakSecurityContext securityContext = (RefreshableKeycloakSecurityContext) request.getSessionInternal().getNote(KeycloakSecurityContext.class.getName());
|
||||
if (securityContext != null) {
|
||||
|
||||
if (!deployment.getRealm().equals(securityContext.getRealm())) {
|
||||
log.fine("Account from cookie is from a different realm than for the request.");
|
||||
return false;
|
||||
}
|
||||
|
||||
securityContext.setCurrentRequestInfo(deployment, this);
|
||||
request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext);
|
||||
}
|
||||
|
||||
GenericPrincipal principal = (GenericPrincipal) request.getSessionInternal().getPrincipal();
|
||||
request.setUserPrincipal(principal);
|
||||
request.setAuthType("KEYCLOAK");
|
||||
|
||||
((CatalinaRequestAuthenticator)authenticator).restoreRequest();
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -73,12 +73,12 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
public void logout(Request request) throws ServletException {
|
||||
KeycloakSecurityContext ksc = (KeycloakSecurityContext)request.getAttribute(KeycloakSecurityContext.class.getName());
|
||||
if (ksc != null) {
|
||||
request.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
CatalinaHttpFacade facade = new CatalinaHttpFacade(request, null);
|
||||
KeycloakDeployment deployment = deploymentContext.resolveDeployment(facade);
|
||||
|
||||
AdapterTokenStore tokenStore = getTokenStore(request, facade, deployment);
|
||||
tokenStore.logout();
|
||||
request.removeAttribute(KeycloakSecurityContext.class.getName());
|
||||
}
|
||||
super.logout(request);
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ public class KeycloakAuthenticatorValve extends FormAuthenticator implements Lif
|
|||
// 4) The deployment doesn't have a keycloak.config.resolver nor keycloak.json (or equivalent)
|
||||
// Outcome: adapter is left unconfigured
|
||||
|
||||
String configResolverClass = (String) context.getServletContext().getAttribute("keycloak.config.resolver");
|
||||
String configResolverClass = context.getServletContext().getInitParameter("keycloak.config.resolver");
|
||||
if (configResolverClass != null) {
|
||||
try {
|
||||
KeycloakConfigResolver configResolver = (KeycloakConfigResolver) context.getLoader().getClassLoader().loadClass(configResolverClass).newInstance();
|
||||
|
|
Loading…
Reference in a new issue