From 51b5f4ce004c55ea223e68a98bd38093dcc88e1d Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Thu, 20 Apr 2017 18:07:45 -0500 Subject: [PATCH] [WFLY-8603] [WFLY-8604] [WFLY-8605] [WFLY-8606] Upgrade components for fixed Remoting/Elytron authentication methodology --- .../as/ejb3/remote/LocalEjbReceiver.java | 6 +- pom.xml | 10 +-- .../RemotingConnectionCredential.java | 30 ++++---- .../remoting/RemotingLoginModule.java | 68 ++++++++----------- .../service/SimpleSecurityManager.java | 5 +- .../security/SwitchIdentityTestCase.java | 11 +++ .../security/api/SwitchIdentityTestCase.java | 11 +++ ...pBasedInitialContextEjbClientTestCase.java | 2 - .../integration/ejb/security/AnnSBTest.java | 3 +- 9 files changed, 84 insertions(+), 62 deletions(-) diff --git a/ejb3/src/main/java/org/jboss/as/ejb3/remote/LocalEjbReceiver.java b/ejb3/src/main/java/org/jboss/as/ejb3/remote/LocalEjbReceiver.java index 41e28e9c3c3f..b15ef915d28d 100644 --- a/ejb3/src/main/java/org/jboss/as/ejb3/remote/LocalEjbReceiver.java +++ b/ejb3/src/main/java/org/jboss/as/ejb3/remote/LocalEjbReceiver.java @@ -53,7 +53,7 @@ import org.jboss.marshalling.cloner.ObjectCloners; import org.jboss.security.SecurityContext; import org.jboss.security.SecurityContextAssociation; -import org.wildfly.naming.client.NamingProvider; +import org.wildfly.security.auth.client.AuthenticationConfiguration; import org.wildfly.security.manager.WildFlySecurityManager; import java.lang.reflect.Method; @@ -65,6 +65,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import javax.net.ssl.SSLContext; + /** * {@link EJBReceiver} for local same-VM invocations. This handles all invocations on remote interfaces * within the server JVM. @@ -330,7 +332,7 @@ private ObjectCloner createCloner(final ClonerConfiguration paramConfig) { } @Override - protected StatefulEJBLocator createSession(StatelessEJBLocator statelessLocator, NamingProvider namingProvider) throws Exception { + protected StatefulEJBLocator createSession(final StatelessEJBLocator statelessLocator, final AuthenticationConfiguration authenticationConfiguration, final SSLContext sslContext) throws Exception { final EjbDeploymentInformation ejbInfo = findBean(statelessLocator); final EJBComponent component = ejbInfo.getEjbComponent(); if (!(component instanceof StatefulSessionComponent)) { diff --git a/pom.xml b/pom.xml index ec40f270762d..e51d5e9f3ec3 100644 --- a/pom.xml +++ b/pom.xml @@ -157,7 +157,7 @@ 1.0.2 2.0.0.Final 2.9.6.Final - 4.0.0.Beta24 + 4.0.0.Beta25 2.2.0.Final 2.0.0.Alpha2 1.0.0.Final @@ -215,12 +215,12 @@ 0.9.30 1.1.8.Final 1.0.5.Final - 3.0.0.Beta15 + 3.0.0.Beta16 1.2.0.Alpha4 2.1.0.Alpha1 - 1.0.0.Alpha4 - 1.0.0.Beta13 - 1.0.0.Beta19 + 1.0.0.CR2-SNAPSHOT + 1.0.0.Beta14 + 1.0.0.Beta21 1.17 2.2.11.jbossorg-1 1.3.16-jbossorg-1 diff --git a/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingConnectionCredential.java b/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingConnectionCredential.java index 4bd1e589e1b9..39504f4ca5ba 100644 --- a/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingConnectionCredential.java +++ b/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingConnectionCredential.java @@ -34,6 +34,7 @@ import org.jboss.as.core.security.RealmRole; import org.jboss.as.core.security.RealmUser; import org.jboss.remoting3.Connection; +import org.wildfly.common.Assert; import org.wildfly.security.auth.server.SecurityIdentity; /** @@ -44,20 +45,21 @@ public final class RemotingConnectionCredential { private final Connection connection; + private final SecurityIdentity securityIdentity; private final Subject subject; - public RemotingConnectionCredential(final Connection connection) { + public RemotingConnectionCredential(final Connection connection, final SecurityIdentity securityIdentity) { + Assert.checkNotNullParam("connection", connection); + Assert.checkNotNullParam("securityIdentity", securityIdentity); this.connection = connection; + this.securityIdentity = securityIdentity; Subject subject = new Subject(); - SecurityIdentity localIdentity = connection.getLocalIdentity(); - if (localIdentity != null) { - Set principals = subject.getPrincipals(); - principals.add(new RealmUser(localIdentity.getPrincipal().getName())); - StreamSupport.stream(localIdentity.getRoles().spliterator(), true).forEach((String role) -> { - principals.add(new RealmGroup(role)); - principals.add(new RealmRole(role)); - }); - } + Set principals = subject.getPrincipals(); + principals.add(new RealmUser(securityIdentity.getPrincipal().getName())); + StreamSupport.stream(securityIdentity.getRoles().spliterator(), true).forEach((String role) -> { + principals.add(new RealmGroup(role)); + principals.add(new RealmRole(role)); + }); this.subject = subject; } @@ -65,6 +67,10 @@ Connection getConnection() { return connection; } + SecurityIdentity getSecurityIdentity() { + return securityIdentity; + } + public Subject getSubject() { return subject; } @@ -76,10 +82,10 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof RemotingConnectionCredential ? equals((RemotingConnectionCredential) obj) : false; + return obj instanceof RemotingConnectionCredential && equals((RemotingConnectionCredential) obj); } public boolean equals(RemotingConnectionCredential obj) { - return connection.equals(obj.connection); + return connection.equals(obj.connection) && securityIdentity.equals(obj.securityIdentity); } } diff --git a/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingLoginModule.java b/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingLoginModule.java index 5c798c81d74e..540acf163814 100644 --- a/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingLoginModule.java +++ b/security/subsystem/src/main/java/org/jboss/as/security/remoting/RemotingLoginModule.java @@ -98,49 +98,41 @@ public boolean login() throws LoginException { Object credential = getCredential(); if (credential instanceof RemotingConnectionCredential) { - Connection con = ((RemotingConnectionCredential) credential).getConnection(); - Principal up = null; - - SecurityIdentity localIdentity = con.getLocalIdentity(); - if (localIdentity != null) { - up = new RealmUser(localIdentity.getPrincipal().getName()); - } - - // If we found a principal from the connection then authentication succeeded. - if (up != null) { - identity = up; - if (getUseFirstPass()) { - String userName = identity.getName(); - log.debugf("Storing username '%s'", userName); - // Add the username to the shared state map - sharedState.put("javax.security.auth.login.name", identity); - - if (useNewClientCert) { - SSLSession session = con.getSslSession(); - if (session != null) { - try { - credential = session.getPeerCertificates()[0]; - log.debug("Using new certificate as credential."); - } catch (SSLPeerUnverifiedException e) { - log.debugf("No peer certificate available for '%s'", userName); - } + final RemotingConnectionCredential remotingConnectionCredential = (RemotingConnectionCredential) credential; + Connection con = remotingConnectionCredential.getConnection(); + SecurityIdentity localIdentity = remotingConnectionCredential.getSecurityIdentity(); + identity = new RealmUser(localIdentity.getPrincipal().getName()); + if (getUseFirstPass()) { + String userName = identity.getName(); + log.debugf("Storing username '%s'", userName); + // Add the username to the shared state map + sharedState.put("javax.security.auth.login.name", identity); + + if (useNewClientCert) { + SSLSession session = con.getSslSession(); + if (session != null) { + try { + credential = session.getPeerCertificates()[0]; + log.debug("Using new certificate as credential."); + } catch (SSLPeerUnverifiedException e) { + log.debugf("No peer certificate available for '%s'", userName); } - } else if (useClientCert) { - SSLSession session = con.getSslSession(); - if (session != null) { - try { - credential = session.getPeerCertificateChain()[0]; - log.debug("Using certificate as credential."); - } catch (SSLPeerUnverifiedException e) { - log.debugf("No peer certificate available for '%s'", userName); - } + } + } else if (useClientCert) { + SSLSession session = con.getSslSession(); + if (session != null) { + try { + credential = session.getPeerCertificateChain()[0]; + log.debug("Using certificate as credential."); + } catch (SSLPeerUnverifiedException e) { + log.debugf("No peer certificate available for '%s'", userName); } } - sharedState.put("javax.security.auth.login.password", credential); } - loginOk = true; - return true; + 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 diff --git a/security/subsystem/src/main/java/org/jboss/as/security/service/SimpleSecurityManager.java b/security/subsystem/src/main/java/org/jboss/as/security/service/SimpleSecurityManager.java index 37258e930728..37e02e680ff2 100644 --- a/security/subsystem/src/main/java/org/jboss/as/security/service/SimpleSecurityManager.java +++ b/security/subsystem/src/main/java/org/jboss/as/security/service/SimpleSecurityManager.java @@ -66,6 +66,7 @@ import org.jboss.security.javaee.SecurityHelperFactory; import org.jboss.security.javaee.SecurityRoleRef; import org.wildfly.security.auth.server.IdentityCredentials; +import org.wildfly.security.auth.server.SecurityDomain; import org.wildfly.security.auth.server.SecurityIdentity; import org.wildfly.security.credential.PasswordCredential; import org.wildfly.security.password.interfaces.ClearPassword; @@ -301,7 +302,7 @@ public void push(final String securityDomain) { Principal p = null; Object credential = null; - SecurityIdentity localIdentity = connection.getLocalIdentity(); + SecurityIdentity localIdentity = SecurityDomain.forIdentity(connection.getLocalIdentity()).getCurrentSecurityIdentity(); if (localIdentity != null) { p = new SimplePrincipal(localIdentity.getPrincipal().getName()); IdentityCredentials privateCredentials = localIdentity.getPrivateCredentials(); @@ -309,7 +310,7 @@ public void push(final String securityDomain) { if (passwordCredential != null) { credential = new String(passwordCredential.getPassword(ClearPassword.class).getPassword()); } else { - credential = new RemotingConnectionCredential(connection); + credential = new RemotingConnectionCredential(connection, localIdentity); } } else { throw SecurityLogger.ROOT_LOGGER.noUserPrincipalFound(); diff --git a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/SwitchIdentityTestCase.java b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/SwitchIdentityTestCase.java index 02a4d2fce5b0..6ae076bebfef 100644 --- a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/SwitchIdentityTestCase.java +++ b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/SwitchIdentityTestCase.java @@ -81,6 +81,16 @@ public class SwitchIdentityTestCase { @ArquillianResource private ManagementClient mgmtClient; + private final Map passwordsToUse; + + public SwitchIdentityTestCase() { + passwordsToUse = new HashMap<>(); + passwordsToUse.put("guest", "b5d048a237bfd2874b6928e1f37ee15e"); + passwordsToUse.put("user1", "23624d2f74dfcb9688651a066d90b97e"); + passwordsToUse.put("user2", "ab3f9e12039435236d89de9023a304b7"); + passwordsToUse.put("remoteejbuser", "d37cd830cc282510807b82c4b861256d"); + } + // Public methods -------------------------------------------------------- @BeforeClass @@ -174,6 +184,7 @@ private AuthenticationContext setupAuthenticationContext(final String username) AuthenticationConfiguration.EMPTY .useName(username == null ? "$local" : username) .useRealm(null) + .usePassword(passwordsToUse.getOrDefault(username, "")) .allowSaslMechanisms("DIGEST-MD5") .useMechanismProperties(getSaslProperties(builder.getMap())) .useProvidersFromClassLoader(SwitchIdentityTestCase.class.getClassLoader())); diff --git a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/api/SwitchIdentityTestCase.java b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/api/SwitchIdentityTestCase.java index 121bb8d901fe..4ba46bd0912a 100644 --- a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/api/SwitchIdentityTestCase.java +++ b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/container/interceptor/security/api/SwitchIdentityTestCase.java @@ -83,6 +83,16 @@ public class SwitchIdentityTestCase { private static final String EJB_OUTBOUND_REALM = "ejb-outbound-realm"; private static final String SECURITY_DOMAIN_NAME = "switch-identity-test"; + private final Map passwordsToUse; + + public SwitchIdentityTestCase() { + passwordsToUse = new HashMap<>(); + passwordsToUse.put("guest", "b5d048a237bfd2874b6928e1f37ee15e"); + passwordsToUse.put("user1", "23624d2f74dfcb9688651a066d90b97e"); + passwordsToUse.put("user2", "ab3f9e12039435236d89de9023a304b7"); + passwordsToUse.put("remoteejbuser", "d37cd830cc282510807b82c4b861256d"); + } + @ArquillianResource private ManagementClient mgmtClient; @@ -196,6 +206,7 @@ private AuthenticationContext setupAuthenticationContext(final String username) AuthenticationConfiguration.EMPTY .useName(username == null ? "$local" : username) .useRealm(null) + .usePassword(passwordsToUse.getOrDefault(username, "")) .allowSaslMechanisms("DIGEST-MD5") .useMechanismProperties(getSaslProperties(builder.getMap())) .useProvidersFromClassLoader(org.jboss.as.test.integration.ejb.container.interceptor.security.SwitchIdentityTestCase.class.getClassLoader())); diff --git a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/mapbased/MapBasedInitialContextEjbClientTestCase.java b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/mapbased/MapBasedInitialContextEjbClientTestCase.java index 894c3a5154a8..0a38c5bf93e2 100644 --- a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/mapbased/MapBasedInitialContextEjbClientTestCase.java +++ b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/mapbased/MapBasedInitialContextEjbClientTestCase.java @@ -30,7 +30,6 @@ import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.arquillian.container.test.api.RunAsClient; import org.jboss.arquillian.junit.Arquillian; -import org.jboss.as.test.shared.util.AssumeTestGroupUtil; import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.JavaArchive; @@ -64,7 +63,6 @@ public static Archive getDeployment() { */ @Test public void testScopedEJBClientContexts() throws Exception { - AssumeTestGroupUtil.assumeElytronProfileTestsEnabled(); InitialContext ctx = new InitialContext(getEjbClientProperties(System.getProperty("node0", "127.0.0.1"), 8080)); try { String lookupName = "ejb:/" + ARCHIVE_NAME + "/" + StatelessBean.class.getSimpleName() + "!" + StatelessIface.class.getCanonicalName(); diff --git a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/security/AnnSBTest.java b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/security/AnnSBTest.java index 7dc094a447e3..3f4cf98ae543 100644 --- a/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/security/AnnSBTest.java +++ b/testsuite/integration/basic/src/test/java/org/jboss/as/test/integration/ejb/security/AnnSBTest.java @@ -47,6 +47,7 @@ import org.wildfly.security.auth.client.AuthenticationConfiguration; import org.wildfly.security.auth.client.AuthenticationContext; import org.wildfly.security.auth.client.MatchRule; +import org.wildfly.security.auth.principal.AnonymousPrincipal; import org.xnio.OptionMap; import org.xnio.Options; import org.xnio.Property; @@ -106,7 +107,7 @@ private SimpleAuthorizationRemote getBean(final String MODULE, final Logger log, */ public void testSingleMethodAnnotationsNoUserTemplate(final String MODULE, final Logger log, final Class SB_CLASS) throws Exception { final Context ctx = Util.createNamingContext(); - final AuthenticationContext authenticationContext = setupAuthenticationContext("$local", null); + final AuthenticationContext authenticationContext = AuthenticationContext.empty().with(MatchRule.ALL, AuthenticationConfiguration.EMPTY.useAuthorizationPrincipal(AnonymousPrincipal.getInstance())); authenticationContext.runCallable(() -> { String echoValue = getBean(MODULE, log, SB_CLASS, ctx).defaultAccess("alohomora"); Assert.assertEquals(echoValue, "alohomora");