From e8363718872784031715a38078f6a32a7f6bb455 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Tue, 11 Mar 2014 17:40:53 -0400 Subject: [PATCH] security context propagation --- .../src/main/xslt/standalone.xsl | 12 ++ distribution/as7-adapter-zip/assembly.xml | 1 + distribution/modules/build.xml | 8 ++ distribution/modules/pom.xml | 10 ++ .../main/module.xml | 37 +++++ .../keycloak-wildfly-adapter/main/module.xml | 46 ++++++ .../keycloak/adapters/KeycloakAccount.java | 19 +++ .../adapters/KeycloakDeploymentBuilder.java | 1 + .../RefreshableKeycloakSecurityContext.java | 4 + .../adapters/RequestAuthenticator.java | 8 +- .../KeycloakDependencyProcessor.java | 2 + integration/as7-eap6/adapter/pom.xml | 5 + .../as7/CatalinaRequestAuthenticator.java | 9 +- .../as7/CatalinaSecurityContextHelper.java | 25 +++- integration/jboss-adapter-core/pom.xml | 83 +++++++++++ .../adapters/jboss/KeycloakLoginModule.java | 100 +++++++++++++ integration/pom.xml | 2 + .../undertow/KeycloakServletExtension.java | 7 +- .../undertow/KeycloakUndertowAccount.java | 38 ++--- .../undertow/ServletKeycloakAuthMech.java | 8 +- .../undertow/ServletRequestAuthenticator.java | 6 +- .../UndertowRequestAuthenticator.java | 3 +- integration/wildfly-adapter/pom.xml | 108 ++++++++++++++ .../adapters/wildfly/SecurityInfoHelper.java | 116 +++++++++++++++ .../WildflyAuthenticationMechanism.java | 29 ++++ .../WildflyKeycloakServletExtension.java | 24 ++++ .../wildfly/WildflyRequestAuthenticator.java | 136 ++++++++++++++++++ .../io.undertow.servlet.ServletExtension | 1 + ...cloakAdapterConfigDeploymentProcessor.java | 24 +++- .../KeycloakDependencyProcessor.java | 6 +- .../resources/admin/AdminService.java | 2 +- 31 files changed, 847 insertions(+), 33 deletions(-) create mode 100755 distribution/modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml create mode 100755 distribution/modules/src/main/resources/modules/org/keycloak/keycloak-wildfly-adapter/main/module.xml create mode 100755 integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakAccount.java create mode 100755 integration/jboss-adapter-core/pom.xml create mode 100755 integration/jboss-adapter-core/src/main/java/org/keycloak/adapters/jboss/KeycloakLoginModule.java create mode 100755 integration/wildfly-adapter/pom.xml create mode 100755 integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java create mode 100755 integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java create mode 100755 integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java create mode 100755 integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java create mode 100755 integration/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension diff --git a/distribution/appliance-dist/src/main/xslt/standalone.xsl b/distribution/appliance-dist/src/main/xslt/standalone.xsl index 8f8011b082..64fda3328a 100755 --- a/distribution/appliance-dist/src/main/xslt/standalone.xsl +++ b/distribution/appliance-dist/src/main/xslt/standalone.xsl @@ -38,6 +38,18 @@ + + + + + + + + + + + + diff --git a/distribution/as7-adapter-zip/assembly.xml b/distribution/as7-adapter-zip/assembly.xml index f4b56a1961..6a507fdf99 100755 --- a/distribution/as7-adapter-zip/assembly.xml +++ b/distribution/as7-adapter-zip/assembly.xml @@ -12,6 +12,7 @@ org/keycloak/keycloak-undertow-adapter/** org/keycloak/keycloak-wildfly-subsystem/** + org/keycloak/keycloak-wildfly-adapter/** modules diff --git a/distribution/modules/build.xml b/distribution/modules/build.xml index 16694d4fb2..8503475736 100755 --- a/distribution/modules/build.xml +++ b/distribution/modules/build.xml @@ -59,6 +59,10 @@ + + + + @@ -67,6 +71,10 @@ + + + + diff --git a/distribution/modules/pom.xml b/distribution/modules/pom.xml index ee3c31f295..107a06d7d5 100755 --- a/distribution/modules/pom.xml +++ b/distribution/modules/pom.xml @@ -49,6 +49,11 @@ keycloak-adapter-core ${project.version} + + org.keycloak + keycloak-jboss-adapter-core + ${project.version} + org.keycloak keycloak-as7-adapter @@ -59,6 +64,11 @@ keycloak-undertow-adapter ${project.version} + + org.keycloak + keycloak-wildfly-adapter + ${project.version} + org.keycloak keycloak-wildfly-subsystem diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml new file mode 100755 index 0000000000..5ecc097b6e --- /dev/null +++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-jboss-adapter-core/main/module.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-wildfly-adapter/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-wildfly-adapter/main/module.xml new file mode 100755 index 0000000000..a89bac4e34 --- /dev/null +++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-wildfly-adapter/main/module.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakAccount.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakAccount.java new file mode 100755 index 0000000000..4bc9dd4d09 --- /dev/null +++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakAccount.java @@ -0,0 +1,19 @@ +package org.keycloak.adapters; + +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.RefreshableKeycloakSecurityContext; +import org.keycloak.representations.AccessToken; + +import java.security.Principal; +import java.util.Set; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public interface KeycloakAccount { + Principal getPrincipal(); + Set getRoles(); + KeycloakSecurityContext getKeycloakSecurityContext(); +} diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java index 5a326b8438..d497c0d92d 100755 --- a/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java +++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/KeycloakDeploymentBuilder.java @@ -48,6 +48,7 @@ public class KeycloakDeploymentBuilder { deployment.setSslRequired(!adapterConfig.isSslNotRequired()); deployment.setResourceCredentials(adapterConfig.getCredentials()); deployment.setPublicClient(adapterConfig.isPublicClient()); + deployment.setUseResourceRoleMappings(adapterConfig.isUseResourceRoleMappings()); if (adapterConfig.isBearerOnly()) { deployment.setBearerOnly(true); diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java index 5ddbc58449..644249904f 100755 --- a/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java +++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/RefreshableKeycloakSecurityContext.java @@ -46,6 +46,10 @@ public class RefreshableKeycloakSecurityContext extends KeycloakSecurityContext return this.token.isActive() && this.token.getIssuedAt() > deployment.getNotBefore(); } + public KeycloakDeployment getDeployment() { + return deployment; + } + public void setDeployment(KeycloakDeployment deployment) { this.deployment = deployment; } diff --git a/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java b/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java index f0d697cdbd..103098ae40 100755 --- a/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java +++ b/integration/adapter-core/src/main/java/org/keycloak/adapters/RequestAuthenticator.java @@ -8,7 +8,7 @@ import org.keycloak.KeycloakPrincipal; * @version $Revision: 1 $ */ public abstract class RequestAuthenticator { - protected Logger log = Logger.getLogger(RequestAuthenticator.class); + protected static Logger log = Logger.getLogger(RequestAuthenticator.class); protected HttpFacade facade; protected KeycloakDeployment deployment; @@ -33,19 +33,25 @@ public abstract class RequestAuthenticator { public AuthOutcome authenticate() { log.info("--> authenticate()"); BearerTokenRequestAuthenticator bearer = createBearerTokenAuthenticator(); + log.info("try bearer"); AuthOutcome outcome = bearer.authenticate(facade); if (outcome == AuthOutcome.FAILED) { challenge = bearer.getChallenge(); + log.info("Bearer FAILED"); return AuthOutcome.FAILED; } else if (outcome == AuthOutcome.AUTHENTICATED) { completeAuthentication(bearer); + log.info("Bearer AUTHENTICATED"); return AuthOutcome.AUTHENTICATED; } else if (deployment.isBearerOnly()) { challenge = bearer.getChallenge(); + log.info("NOT_ATTEMPTED: bearer only"); return AuthOutcome.NOT_ATTEMPTED; } + log.info("try oauth"); if (isCached()) { + log.info("AUTHENTICATED: was cached"); return AuthOutcome.AUTHENTICATED; } diff --git a/integration/as7-eap-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java b/integration/as7-eap-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java index 2ac2ccfb88..c9a32d6dba 100755 --- a/integration/as7-eap-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java +++ b/integration/as7-eap-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java @@ -36,6 +36,7 @@ public class KeycloakDependencyProcessor implements DeploymentUnitProcessor { private static final ModuleIdentifier KEYCLOAK_AS7_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-as7-adapter"); private static final ModuleIdentifier KEYCLOAK_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-adapter-core"); + private static final ModuleIdentifier KEYCLOAK_JBOSS_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-jboss-adapter-core"); private static final ModuleIdentifier KEYCLOAK_CORE = ModuleIdentifier.create("org.keycloak.keycloak-core"); //private static final ModuleIdentifier APACHE_HTTPCOMPONENTS = ModuleIdentifier.create("org.apache.httpcomponents"); @@ -51,6 +52,7 @@ public class KeycloakDependencyProcessor implements DeploymentUnitProcessor { final ModuleLoader moduleLoader = Module.getBootModuleLoader(); moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_AS7_ADAPTER, false, false, true, false)); + moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false)); moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE_ADAPTER, false, false, false, false)); moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE, false, false, false, false)); //moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, APACHE_HTTPCOMPONENTS, false, false, true, false)); diff --git a/integration/as7-eap6/adapter/pom.xml b/integration/as7-eap6/adapter/pom.xml index ea2c35e468..07dc6e35b1 100755 --- a/integration/as7-eap6/adapter/pom.xml +++ b/integration/as7-eap6/adapter/pom.xml @@ -23,6 +23,11 @@ keycloak-adapter-core ${project.version} + + org.keycloak + keycloak-jboss-adapter-core + ${project.version} + org.apache.httpcomponents httpclient diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaRequestAuthenticator.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaRequestAuthenticator.java index 1188e6d1ea..9e211b237c 100755 --- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaRequestAuthenticator.java +++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaRequestAuthenticator.java @@ -4,6 +4,7 @@ import org.apache.catalina.Session; import org.apache.catalina.authenticator.Constants; import org.apache.catalina.connector.Request; import org.apache.catalina.realm.GenericPrincipal; +import org.jboss.logging.Logger; import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakSecurityContext; import org.keycloak.adapters.KeycloakDeployment; @@ -22,6 +23,7 @@ import java.util.Set; * @version $Revision: 1 $ */ public class CatalinaRequestAuthenticator extends RequestAuthenticator { + private static final Logger log = Logger.getLogger(CatalinaRequestAuthenticator.class); protected KeycloakAuthenticatorValve valve; protected CatalinaUserSessionManagement userSessionManagement; protected Request request; @@ -53,7 +55,7 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator { @Override protected void completeOAuthAuthentication(KeycloakPrincipal skp, RefreshableKeycloakSecurityContext securityContext) { Set roles = getRolesFromToken(securityContext); - GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skp, roles); + GenericPrincipal principal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), skp, roles, securityContext); Session session = request.getSessionInternal(true); session.setPrincipal(principal); session.setAuthType("OAUTH"); @@ -66,7 +68,10 @@ public class CatalinaRequestAuthenticator extends RequestAuthenticator { @Override protected void completeBearerAuthentication(KeycloakPrincipal principal, RefreshableKeycloakSecurityContext securityContext) { Set roles = getRolesFromToken(securityContext); - Principal generalPrincipal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), principal, roles); + for (String role : roles) { + log.info("Bearer role: " + role); + } + Principal generalPrincipal = new CatalinaSecurityContextHelper().createPrincipal(request.getContext().getRealm(), principal, roles, securityContext); request.setUserPrincipal(generalPrincipal); request.setAuthType("KEYCLOAK"); request.setAttribute(KeycloakSecurityContext.class.getName(), securityContext); diff --git a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java index 8cfbcb58d1..f33c4631a2 100755 --- a/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java +++ b/integration/as7-eap6/adapter/src/main/java/org/keycloak/adapters/as7/CatalinaSecurityContextHelper.java @@ -9,6 +9,8 @@ import org.jboss.security.SecurityContext; import org.jboss.security.SecurityContextAssociation; import org.jboss.security.SimpleGroup; import org.jboss.security.SimplePrincipal; +import org.keycloak.KeycloakSecurityContext; +import org.keycloak.adapters.KeycloakAccount; import javax.security.auth.Subject; import java.security.Principal; @@ -25,9 +27,24 @@ import java.util.Set; * @version $Revision: 1 $ */ public class CatalinaSecurityContextHelper { - public GenericPrincipal createPrincipal(Realm realm, Principal identity, Collection roleSet) { + public GenericPrincipal createPrincipal(Realm realm, final Principal identity, final Set roleSet, final KeycloakSecurityContext securityContext) { + KeycloakAccount account = new KeycloakAccount() { + @Override + public Principal getPrincipal() { + return identity; + } + + @Override + public Set getRoles() { + return roleSet; + } + + @Override + public KeycloakSecurityContext getKeycloakSecurityContext() { + return securityContext; + } + }; Subject subject = new Subject(); - String credentials = ""; Set principals = subject.getPrincipals(); principals.add(identity); Group[] roleSets = getRoleSets(roleSet); @@ -56,11 +73,11 @@ public class CatalinaSecurityContextHelper { principals.add(callerGroup); SecurityContext sc = SecurityContextAssociation.getSecurityContext(); Principal userPrincipal = getPrincipal(subject); - sc.getUtil().createSubjectInfo(userPrincipal, credentials, subject); + sc.getUtil().createSubjectInfo(userPrincipal, account, subject); List rolesAsStringList = new ArrayList(); rolesAsStringList.addAll(roleSet); return new JBossGenericPrincipal(realm, userPrincipal.getName(), null, rolesAsStringList, - userPrincipal, null, credentials, null, subject); + userPrincipal, null, account, null, subject); } diff --git a/integration/jboss-adapter-core/pom.xml b/integration/jboss-adapter-core/pom.xml new file mode 100755 index 0000000000..0d599a555a --- /dev/null +++ b/integration/jboss-adapter-core/pom.xml @@ -0,0 +1,83 @@ + + + + keycloak-parent + org.keycloak + 1.0-alpha-3-SNAPSHOT + ../../pom.xml + + 4.0.0 + + keycloak-jboss-adapter-core + Common JBoss/Wildfly Core Classes + + + + + org.jboss.logging + jboss-logging + 3.1.2.GA + provided + + + org.keycloak + keycloak-core + ${project.version} + + + org.keycloak + keycloak-adapter-core + ${project.version} + + + org.apache.httpcomponents + httpclient + ${keycloak.apache.httpcomponents.version} + + + net.iharder + base64 + + + org.bouncycastle + bcprov-jdk16 + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-mapper-asl + + + org.codehaus.jackson + jackson-xc + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + provided + + + org.picketbox + picketbox + 4.0.20.Final + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + diff --git a/integration/jboss-adapter-core/src/main/java/org/keycloak/adapters/jboss/KeycloakLoginModule.java b/integration/jboss-adapter-core/src/main/java/org/keycloak/adapters/jboss/KeycloakLoginModule.java new file mode 100755 index 0000000000..e3db8c5418 --- /dev/null +++ b/integration/jboss-adapter-core/src/main/java/org/keycloak/adapters/jboss/KeycloakLoginModule.java @@ -0,0 +1,100 @@ +package org.keycloak.adapters.jboss; + +import org.jboss.logging.Logger; +import org.jboss.security.SimpleGroup; +import org.jboss.security.SimplePrincipal; +import org.jboss.security.auth.callback.ObjectCallback; +import org.jboss.security.auth.spi.AbstractServerLoginModule; +import org.keycloak.adapters.KeycloakAccount; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.auth.login.LoginException; +import java.io.IOException; +import java.security.Principal; +import java.security.acl.Group; +import java.util.Set; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class KeycloakLoginModule extends AbstractServerLoginModule { + protected static Logger log = Logger.getLogger(KeycloakLoginModule.class); + protected Set roleSet; + protected Principal identity; + + + @SuppressWarnings("unchecked") + @Override + public boolean login() throws LoginException { + log.info("KeycloakLoginModule.login()"); + if (super.login() == true) { + log.info("super.login()==true"); + return true; + } + + Object credential = getCredential(); + if (credential != null && (credential instanceof KeycloakAccount)) { + log.info("Found Account"); + KeycloakAccount account = (KeycloakAccount)credential; + roleSet = account.getRoles(); + identity = account.getPrincipal(); + sharedState.put("javax.security.auth.login.name", identity); + sharedState.put("javax.security.auth.login.password", credential); + loginOk = true; + return true; + } + + // We return false to allow the next module to attempt authentication, maybe a + // username and password has been supplied to a web auth. + return false; + } + + + @Override + protected Principal getIdentity() { + return identity; + } + + /* + @Override + protected Group[] getRoleSets() throws LoginException { + return new Group[0]; + } + */ + + @Override + protected Group[] getRoleSets() throws LoginException { + //log.info("getRoleSets"); + SimpleGroup roles = new SimpleGroup("Roles"); + Group[] roleSets = {roles}; + for (String role : roleSet) { + //log.info(" adding role: " + role); + roles.addMember(new SimplePrincipal(role)); + } + return roleSets; + } + + protected Object getCredential() throws LoginException { + NameCallback nc = new NameCallback("Alias: "); + ObjectCallback oc = new ObjectCallback("Credential: "); + Callback[] callbacks = { nc, oc }; + + try { + callbackHandler.handle(callbacks); + + return oc.getCredential(); + } catch (IOException ioe) { + LoginException le = new LoginException(); + le.initCause(ioe); + throw le; + } catch (UnsupportedCallbackException uce) { + LoginException le = new LoginException(); + le.initCause(uce); + throw le; + } + } + +} diff --git a/integration/pom.xml b/integration/pom.xml index f52c6e65f5..d07f29b174 100755 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -18,8 +18,10 @@ adapter-core jaxrs-oauth-client servlet-oauth-client + jboss-adapter-core as7-eap6/adapter undertow + wildfly-adapter wildfly-subsystem as7-eap-subsystem js diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java index 50895c6cf5..4c074807d8 100755 --- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java +++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakServletExtension.java @@ -65,7 +65,7 @@ public class KeycloakServletExtension implements ServletExtension { if (is == null) throw new RuntimeException("Unable to find realm config in /WEB-INF/keycloak.json or in keycloak subsystem."); KeycloakDeployment deployment = KeycloakDeploymentBuilder.build(is); UndertowUserSessionManagement userSessionManagement = new UndertowUserSessionManagement(deployment); - final ServletKeycloakAuthMech mech = new ServletKeycloakAuthMech(deployment, userSessionManagement, deploymentInfo.getConfidentialPortManager()); + final ServletKeycloakAuthMech mech = createAuthenticationMechanism(deploymentInfo, deployment, userSessionManagement); UndertowAuthenticatedActionsHandler.Wrapper actions = new UndertowAuthenticatedActionsHandler.Wrapper(deployment); @@ -102,4 +102,9 @@ public class KeycloakServletExtension implements ServletExtension { cookieConfig.setPath(deploymentInfo.getContextPath()); deploymentInfo.setServletSessionConfig(cookieConfig); } + + protected ServletKeycloakAuthMech createAuthenticationMechanism(DeploymentInfo deploymentInfo, KeycloakDeployment deployment, UndertowUserSessionManagement userSessionManagement) { + log.info("creating ServletKeycloakAuthMech"); + return new ServletKeycloakAuthMech(deployment, userSessionManagement, deploymentInfo.getConfidentialPortManager()); + } } diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java index 310958adef..be721845fb 100755 --- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java +++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/KeycloakUndertowAccount.java @@ -3,6 +3,7 @@ package org.keycloak.adapters.undertow; import io.undertow.security.idm.Account; import org.jboss.logging.Logger; import org.keycloak.KeycloakPrincipal; +import org.keycloak.adapters.KeycloakAccount; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.RefreshableKeycloakSecurityContext; import org.keycloak.representations.AccessToken; @@ -16,7 +17,7 @@ import java.util.Set; * @author Bill Burke * @version $Revision: 1 $ */ -public class KeycloakUndertowAccount implements Account, Serializable { +public class KeycloakUndertowAccount implements Account, Serializable, KeycloakAccount { protected static Logger log = Logger.getLogger(KeycloakUndertowAccount.class); protected RefreshableKeycloakSecurityContext session; protected KeycloakPrincipal principal; @@ -25,19 +26,27 @@ public class KeycloakUndertowAccount implements Account, Serializable { public KeycloakUndertowAccount(KeycloakPrincipal principal, RefreshableKeycloakSecurityContext session, KeycloakDeployment deployment) { this.principal = principal; this.session = session; - setRoles(session.getToken(), deployment); + setRoles(session.getToken()); } - protected void setRoles(AccessToken accessToken, KeycloakDeployment deployment) { + protected void setRoles(AccessToken accessToken) { Set roles = null; - if (deployment.isUseResourceRoleMappings()) { - AccessToken.Access access = accessToken.getResourceAccess(deployment.getResourceName()); + if (session.getDeployment().isUseResourceRoleMappings()) { + log.info("useResourceRoleMappings"); + AccessToken.Access access = accessToken.getResourceAccess(session.getDeployment().getResourceName()); if (access != null) roles = access.getRoles(); } else { + log.info("use realm role mappings"); AccessToken.Access access = accessToken.getRealmAccess(); if (access != null) roles = access.getRoles(); } if (roles == null) roles = Collections.emptySet(); + /* + log.info("Setting roles: "); + for (String role : roles) { + log.info(" role: " + role); + } + */ this.accountRoles = roles; } @@ -51,22 +60,17 @@ public class KeycloakUndertowAccount implements Account, Serializable { return accountRoles; } - public AccessToken getAccessToken() { - return session.getToken(); - } - - public String getEncodedAccessToken() { - return session.getTokenString(); - } - + @Override public RefreshableKeycloakSecurityContext getKeycloakSecurityContext() { return session; } - public boolean isActive(KeycloakDeployment deployment) { - // this object may have been serialized, so we need to reset realm config/metadata + public void setDeployment(KeycloakDeployment deployment) { session.setDeployment(deployment); - log.info("realmConfig notBefore: " + deployment.getNotBefore()); + } + + public boolean isActive() { + // this object may have been serialized, so we need to reset realm config/metadata if (session.isActive()) { log.info("session is active"); return true; @@ -81,7 +85,7 @@ public class KeycloakUndertowAccount implements Account, Serializable { } log.info("refresh succeeded"); - setRoles(session.getToken(), deployment); + setRoles(session.getToken()); return true; } diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java index 2ce8f066d0..42b9237170 100755 --- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java +++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletKeycloakAuthMech.java @@ -29,8 +29,7 @@ public class ServletKeycloakAuthMech implements AuthenticationMechanism { @Override public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) { UndertowHttpFacade facade = new UndertowHttpFacade(exchange); - ServletRequestAuthenticator authenticator = new ServletRequestAuthenticator(facade, deployment, - portManager.getConfidentialPort(exchange), securityContext, exchange, userSessionManagement); + ServletRequestAuthenticator authenticator = createRequestAuthenticator(exchange, securityContext, facade); AuthOutcome outcome = authenticator.authenticate(); if (outcome == AuthOutcome.AUTHENTICATED) { return AuthenticationMechanismOutcome.AUTHENTICATED; @@ -46,6 +45,11 @@ public class ServletKeycloakAuthMech implements AuthenticationMechanism { return AuthenticationMechanismOutcome.NOT_ATTEMPTED; } + protected ServletRequestAuthenticator createRequestAuthenticator(HttpServerExchange exchange, SecurityContext securityContext, UndertowHttpFacade facade) { + return new ServletRequestAuthenticator(facade, deployment, + portManager.getConfidentialPort(exchange), securityContext, exchange, userSessionManagement); + } + @Override public ChallengeResult sendChallenge(HttpServerExchange exchange, SecurityContext securityContext) { AuthChallenge challenge = exchange.getAttachment(KEYCLOAK_CHALLENGE_ATTACHMENT_KEY); diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java index f294eb7ae6..f9c2edf736 100755 --- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java +++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/ServletRequestAuthenticator.java @@ -5,6 +5,7 @@ import io.undertow.server.HttpServerExchange; import io.undertow.servlet.handlers.ServletRequestContext; import org.keycloak.KeycloakSecurityContext; import org.keycloak.adapters.HttpFacade; +import org.keycloak.adapters.KeycloakAccount; import org.keycloak.adapters.KeycloakDeployment; import javax.servlet.http.HttpServletRequest; @@ -39,7 +40,8 @@ public class ServletRequestAuthenticator extends UndertowRequestAuthenticator { log.info("Account was not in session, returning null"); return false; } - if (account.isActive(deployment)) { + account.setDeployment(deployment); + if (account.isActive()) { log.info("Cached account found"); securityContext.authenticationComplete(account, "KEYCLOAK", false); propagateKeycloakContext( account); @@ -59,7 +61,7 @@ public class ServletRequestAuthenticator extends UndertowRequestAuthenticator { } @Override - protected void login(KeycloakUndertowAccount account) { + protected void login(KeycloakAccount account) { final ServletRequestContext servletRequestContext = exchange.getAttachment(ServletRequestContext.ATTACHMENT_KEY); HttpServletRequest req = (HttpServletRequest) servletRequestContext.getServletRequest(); HttpSession session = req.getSession(true); diff --git a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowRequestAuthenticator.java b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowRequestAuthenticator.java index 89b2e11a4b..cd5fdaa4bc 100755 --- a/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowRequestAuthenticator.java +++ b/integration/undertow/src/main/java/org/keycloak/adapters/undertow/UndertowRequestAuthenticator.java @@ -4,6 +4,7 @@ import io.undertow.security.api.SecurityContext; import io.undertow.server.HttpServerExchange; import org.keycloak.KeycloakPrincipal; import org.keycloak.adapters.HttpFacade; +import org.keycloak.adapters.KeycloakAccount; import org.keycloak.adapters.KeycloakDeployment; import org.keycloak.adapters.OAuthRequestAuthenticator; import org.keycloak.adapters.RefreshableKeycloakSecurityContext; @@ -46,7 +47,7 @@ public class UndertowRequestAuthenticator extends RequestAuthenticator { login(account); } - protected void login(KeycloakUndertowAccount account) { + protected void login(KeycloakAccount account) { } diff --git a/integration/wildfly-adapter/pom.xml b/integration/wildfly-adapter/pom.xml new file mode 100755 index 0000000000..7ed0602da9 --- /dev/null +++ b/integration/wildfly-adapter/pom.xml @@ -0,0 +1,108 @@ + + + + keycloak-parent + org.keycloak + 1.0-alpha-3-SNAPSHOT + ../../pom.xml + + 4.0.0 + + keycloak-wildfly-adapter + Keycloak Wildfly Integration + + + + + org.jboss.logging + jboss-logging + 3.1.2.GA + provided + + + org.keycloak + keycloak-core + ${project.version} + + + org.keycloak + keycloak-adapter-core + ${project.version} + + + org.keycloak + keycloak-undertow-adapter + ${project.version} + + + org.keycloak + keycloak-jboss-adapter-core + ${project.version} + + + org.apache.httpcomponents + httpclient + ${keycloak.apache.httpcomponents.version} + + + net.iharder + base64 + + + org.bouncycastle + bcprov-jdk16 + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-mapper-asl + + + org.codehaus.jackson + jackson-xc + + + org.picketbox + picketbox + 4.0.20.Final + provided + + + org.jboss.spec.javax.servlet + jboss-servlet-api_3.0_spec + provided + + + + io.undertow + undertow-servlet + provided + + + io.undertow + undertow-core + provided + + + junit + junit + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + + + + + diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java new file mode 100755 index 0000000000..9838772b12 --- /dev/null +++ b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/SecurityInfoHelper.java @@ -0,0 +1,116 @@ +package org.keycloak.adapters.wildfly; + +import org.jboss.security.NestableGroup; +import org.jboss.security.SecurityConstants; +import org.jboss.security.SecurityContextAssociation; +import org.jboss.security.SimpleGroup; +import org.jboss.security.SimplePrincipal; +import org.keycloak.adapters.KeycloakAccount; + +import javax.security.auth.Subject; +import java.security.Principal; +import java.security.acl.Group; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Set; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class SecurityInfoHelper { + public static void propagateSessionInfo(KeycloakAccount account) { + Subject subject = new Subject(); + Set principals = subject.getPrincipals(); + principals.add(account.getPrincipal()); + Group[] roleSets = getRoleSets(account.getRoles()); + for (int g = 0; g < roleSets.length; g++) { + Group group = roleSets[g]; + String name = group.getName(); + Group subjectGroup = createGroup(name, principals); + if (subjectGroup instanceof NestableGroup) { + /* A NestableGroup only allows Groups to be added to it so we + need to add a SimpleGroup to subjectRoles to contain the roles + */ + SimpleGroup tmp = new SimpleGroup("Roles"); + subjectGroup.addMember(tmp); + subjectGroup = tmp; + } + // Copy the group members to the Subject group + Enumeration members = group.members(); + while (members.hasMoreElements()) { + Principal role = (Principal) members.nextElement(); + subjectGroup.addMember(role); + } + } + // add the CallerPrincipal group if none has been added in getRoleSets + Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP); + callerGroup.addMember(account.getPrincipal()); + principals.add(callerGroup); + org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext(); + Principal userPrincipal = getPrincipal(subject); + sc.getUtil().createSubjectInfo(userPrincipal, account, subject); + } + + /** + * Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is + * considered or the single subject inside the CallerPrincipal group. + * + * @param subject + * @return the authenticated subject + */ + protected static Principal getPrincipal(Subject subject) { + Principal principal = null; + Principal callerPrincipal = null; + if (subject != null) { + Set principals = subject.getPrincipals(); + if (principals != null && !principals.isEmpty()) { + for (Principal p : principals) { + if (!(p instanceof Group) && principal == null) { + principal = p; + } + if (p instanceof Group) { + Group g = Group.class.cast(p); + if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) { + Enumeration e = g.members(); + if (e.hasMoreElements()) + callerPrincipal = e.nextElement(); + } + } + } + } + } + return callerPrincipal == null ? principal : callerPrincipal; + } + + protected static Group createGroup(String name, Set principals) { + Group roles = null; + Iterator iter = principals.iterator(); + while (iter.hasNext()) { + Object next = iter.next(); + if ((next instanceof Group) == false) + continue; + Group grp = (Group) next; + if (grp.getName().equals(name)) { + roles = grp; + break; + } + } + // If we did not find a group create one + if (roles == null) { + roles = new SimpleGroup(name); + principals.add(roles); + } + return roles; + } + + protected static Group[] getRoleSets(Collection roleSet) { + SimpleGroup roles = new SimpleGroup("Roles"); + Group[] roleSets = {roles}; + for (String role : roleSet) { + roles.addMember(new SimplePrincipal(role)); + } + return roleSets; + } +} diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java new file mode 100755 index 0000000000..99c411c8c2 --- /dev/null +++ b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyAuthenticationMechanism.java @@ -0,0 +1,29 @@ +package org.keycloak.adapters.wildfly; + +import io.undertow.security.api.SecurityContext; +import io.undertow.server.HttpServerExchange; +import io.undertow.servlet.api.ConfidentialPortManager; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.undertow.ServletKeycloakAuthMech; +import org.keycloak.adapters.undertow.ServletRequestAuthenticator; +import org.keycloak.adapters.undertow.UndertowHttpFacade; +import org.keycloak.adapters.undertow.UndertowUserSessionManagement; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class WildflyAuthenticationMechanism extends ServletKeycloakAuthMech { + + public WildflyAuthenticationMechanism(KeycloakDeployment deployment, + UndertowUserSessionManagement userSessionManagement, + ConfidentialPortManager portManager) { + super(deployment, userSessionManagement, portManager); + } + + @Override + protected ServletRequestAuthenticator createRequestAuthenticator(HttpServerExchange exchange, SecurityContext securityContext, UndertowHttpFacade facade) { + return new WildflyRequestAuthenticator(facade, deployment, + portManager.getConfidentialPort(exchange), securityContext, exchange, userSessionManagement); + } +} diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java new file mode 100755 index 0000000000..e0623add2c --- /dev/null +++ b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyKeycloakServletExtension.java @@ -0,0 +1,24 @@ +package org.keycloak.adapters.wildfly; + +import io.undertow.servlet.api.DeploymentInfo; +import org.jboss.logging.Logger; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.undertow.KeycloakServletExtension; +import org.keycloak.adapters.undertow.ServletKeycloakAuthMech; +import org.keycloak.adapters.undertow.UndertowUserSessionManagement; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class WildflyKeycloakServletExtension extends KeycloakServletExtension { + protected static Logger log = Logger.getLogger(WildflyKeycloakServletExtension.class); + + @Override + protected ServletKeycloakAuthMech createAuthenticationMechanism(DeploymentInfo deploymentInfo, KeycloakDeployment deployment, + UndertowUserSessionManagement userSessionManagement) { + log.info("creating WildflyAuthenticationMechanism"); + return new WildflyAuthenticationMechanism(deployment, userSessionManagement, deploymentInfo.getConfidentialPortManager()); + + } +} diff --git a/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java new file mode 100755 index 0000000000..0b3563a596 --- /dev/null +++ b/integration/wildfly-adapter/src/main/java/org/keycloak/adapters/wildfly/WildflyRequestAuthenticator.java @@ -0,0 +1,136 @@ +package org.keycloak.adapters.wildfly; + +import io.undertow.security.api.SecurityContext; +import io.undertow.server.HttpServerExchange; +import org.jboss.logging.Logger; +import org.jboss.security.NestableGroup; +import org.jboss.security.SecurityConstants; +import org.jboss.security.SecurityContextAssociation; +import org.jboss.security.SimpleGroup; +import org.jboss.security.SimplePrincipal; +import org.keycloak.adapters.HttpFacade; +import org.keycloak.adapters.KeycloakDeployment; +import org.keycloak.adapters.undertow.KeycloakUndertowAccount; +import org.keycloak.adapters.undertow.ServletRequestAuthenticator; +import org.keycloak.adapters.undertow.UndertowUserSessionManagement; + +import javax.security.auth.Subject; +import java.security.Principal; +import java.security.acl.Group; +import java.util.Collection; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Set; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class WildflyRequestAuthenticator extends ServletRequestAuthenticator { + protected static Logger log = Logger.getLogger(WildflyRequestAuthenticator.class); + + public WildflyRequestAuthenticator(HttpFacade facade, KeycloakDeployment deployment, int sslRedirectPort, + SecurityContext securityContext, HttpServerExchange exchange, + UndertowUserSessionManagement userSessionManagement) { + super(facade, deployment, sslRedirectPort, securityContext, exchange, userSessionManagement); + } + + @Override + protected void propagateKeycloakContext(KeycloakUndertowAccount account) { + super.propagateKeycloakContext(account); + SecurityInfoHelper.propagateSessionInfo(account); + log.info("propagate security context to wildfly"); + Subject subject = new Subject(); + Set principals = subject.getPrincipals(); + principals.add(account.getPrincipal()); + Group[] roleSets = getRoleSets(account.getRoles()); + for (int g = 0; g < roleSets.length; g++) { + Group group = roleSets[g]; + String name = group.getName(); + Group subjectGroup = createGroup(name, principals); + if (subjectGroup instanceof NestableGroup) { + /* A NestableGroup only allows Groups to be added to it so we + need to add a SimpleGroup to subjectRoles to contain the roles + */ + SimpleGroup tmp = new SimpleGroup("Roles"); + subjectGroup.addMember(tmp); + subjectGroup = tmp; + } + // Copy the group members to the Subject group + Enumeration members = group.members(); + while (members.hasMoreElements()) { + Principal role = (Principal) members.nextElement(); + subjectGroup.addMember(role); + } + } + // add the CallerPrincipal group if none has been added in getRoleSets + Group callerGroup = new SimpleGroup(SecurityConstants.CALLER_PRINCIPAL_GROUP); + callerGroup.addMember(account.getPrincipal()); + principals.add(callerGroup); + org.jboss.security.SecurityContext sc = SecurityContextAssociation.getSecurityContext(); + Principal userPrincipal = getPrincipal(subject); + sc.getUtil().createSubjectInfo(userPrincipal, account, subject); + } + + /** + * Get the Principal given the authenticated Subject. Currently the first subject that is not of type {@code Group} is + * considered or the single subject inside the CallerPrincipal group. + * + * @param subject + * @return the authenticated subject + */ + protected Principal getPrincipal(Subject subject) { + Principal principal = null; + Principal callerPrincipal = null; + if (subject != null) { + Set principals = subject.getPrincipals(); + if (principals != null && !principals.isEmpty()) { + for (Principal p : principals) { + if (!(p instanceof Group) && principal == null) { + principal = p; + } + if (p instanceof Group) { + Group g = Group.class.cast(p); + if (g.getName().equals(SecurityConstants.CALLER_PRINCIPAL_GROUP) && callerPrincipal == null) { + Enumeration e = g.members(); + if (e.hasMoreElements()) + callerPrincipal = e.nextElement(); + } + } + } + } + } + return callerPrincipal == null ? principal : callerPrincipal; + } + + protected Group createGroup(String name, Set principals) { + Group roles = null; + Iterator iter = principals.iterator(); + while (iter.hasNext()) { + Object next = iter.next(); + if ((next instanceof Group) == false) + continue; + Group grp = (Group) next; + if (grp.getName().equals(name)) { + roles = grp; + break; + } + } + // If we did not find a group create one + if (roles == null) { + roles = new SimpleGroup(name); + principals.add(roles); + } + return roles; + } + + protected Group[] getRoleSets(Collection roleSet) { + SimpleGroup roles = new SimpleGroup("Roles"); + Group[] roleSets = {roles}; + for (String role : roleSet) { + roles.addMember(new SimplePrincipal(role)); + } + return roleSets; + } + +} diff --git a/integration/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension b/integration/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension new file mode 100755 index 0000000000..a46a78ec82 --- /dev/null +++ b/integration/wildfly-adapter/src/main/resources/META-INF/services/io.undertow.servlet.ServletExtension @@ -0,0 +1 @@ +org.keycloak.adapters.wildfly.WildflyKeycloakServletExtension diff --git a/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java b/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java index 59fd9aa445..16872c86ff 100755 --- a/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java +++ b/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakAdapterConfigDeploymentProcessor.java @@ -48,11 +48,30 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP // Seems wise to have this run after INSTALL_WAR_DEPLOYMENT public static final int PRIORITY = Phase.INSTALL_WAR_DEPLOYMENT - 1; + // not sure if we need this yet, keeping here just in case + protected void addSecurityDomain(DeploymentUnit deploymentUnit, KeycloakAdapterConfigService service) { + String deploymentName = deploymentUnit.getName(); + if (!service.isKeycloakDeployment(deploymentName)) { + return; + } + WarMetaData warMetaData = deploymentUnit.getAttachment(WarMetaData.ATTACHMENT_KEY); + if (warMetaData == null) return; + JBossWebMetaData webMetaData = warMetaData.getMergedJBossWebMetaData(); + if (webMetaData == null) return; + + LoginConfigMetaData loginConfig = webMetaData.getLoginConfig(); + if (loginConfig == null || !loginConfig.getAuthMethod().equalsIgnoreCase("KEYCLOAK")) { + return; + } + + webMetaData.setSecurityDomain("keycloak"); + } + @Override public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException { DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit(); - String deploymentName = deploymentUnit.getName(); + String deploymentName = deploymentUnit.getName(); KeycloakAdapterConfigService service = KeycloakAdapterConfigService.find(phaseContext.getServiceRegistry()); //log.info("********* CHECK KEYCLOAK DEPLOYMENT: " + deploymentName); if (service.isKeycloakDeployment(deploymentName)) { @@ -61,6 +80,9 @@ public class KeycloakAdapterConfigDeploymentProcessor implements DeploymentUnitP } // FYI, Undertow Extension will find deployments that have auth-method set to KEYCLOAK + + // todo notsure if we need this + // addSecurityDomain(deploymentUnit, service); } private void addKeycloakAuthData(DeploymentPhaseContext phaseContext, String deploymentName, KeycloakAdapterConfigService service) { diff --git a/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java b/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java index d16645d738..5dd1e526d6 100755 --- a/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java +++ b/integration/wildfly-subsystem/src/main/java/org/keycloak/subsystem/extension/KeycloakDependencyProcessor.java @@ -36,7 +36,9 @@ import org.keycloak.subsystem.logging.KeycloakLogger; */ public class KeycloakDependencyProcessor implements DeploymentUnitProcessor { + private static final ModuleIdentifier KEYCLOAK_WILDFLY_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-wildfly-adapter"); private static final ModuleIdentifier KEYCLOAK_UNDERTOW_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-undertow-adapter"); + private static final ModuleIdentifier KEYCLOAK_JBOSS_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-jboss-adapter-core"); private static final ModuleIdentifier KEYCLOAK_CORE_ADAPTER = ModuleIdentifier.create("org.keycloak.keycloak-adapter-core"); private static final ModuleIdentifier KEYCLOAK_CORE = ModuleIdentifier.create("org.keycloak.keycloak-core"); //private static final ModuleIdentifier APACHE_HTTPCOMPONENTS = ModuleIdentifier.create("org.apache.httpcomponents"); @@ -51,7 +53,9 @@ public class KeycloakDependencyProcessor implements DeploymentUnitProcessor { final ModuleSpecification moduleSpecification = deploymentUnit.getAttachment(Attachments.MODULE_SPECIFICATION); final ModuleLoader moduleLoader = Module.getBootModuleLoader(); - moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_UNDERTOW_ADAPTER, false, false, true, false)); + moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_WILDFLY_ADAPTER, false, false, true, false)); + moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_UNDERTOW_ADAPTER, false, false, false, false)); + moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_JBOSS_CORE_ADAPTER, false, false, false, false)); moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE_ADAPTER, false, false, false, false)); moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, KEYCLOAK_CORE, false, false, false, false)); //moduleSpecification.addSystemDependency(new ModuleDependency(moduleLoader, APACHE_HTTPCOMPONENTS, false, false, true, false)); diff --git a/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java b/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java index c5cc177d49..50ed5ea3b5 100755 --- a/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/AdminService.java @@ -218,7 +218,7 @@ public class AdminService { } } - @Path("isLoggedIn.js") + @Path("isLoggedIn.js") @GET @Produces("application/javascript") @NoCache