diff --git a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java index d8a88545d3..9ba2c8bf84 100644 --- a/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java +++ b/artemis-core-client/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/TransportConstants.java @@ -103,6 +103,8 @@ public class TransportConstants { public static final String NEED_CLIENT_AUTH_PROP_NAME = "needClientAuth"; + public static final String WANT_CLIENT_AUTH_PROP_NAME = "wantClientAuth"; + public static final String VERIFY_HOST_PROP_NAME = "verifyHost"; public static final String TRUST_ALL_PROP_NAME = "trustAll"; @@ -201,6 +203,8 @@ public class TransportConstants { public static final boolean DEFAULT_NEED_CLIENT_AUTH = false; + public static final boolean DEFAULT_WANT_CLIENT_AUTH = false; + public static final boolean DEFAULT_VERIFY_HOST = false; public static final String DEFAULT_SSL_PROVIDER = "JDK"; @@ -297,6 +301,7 @@ public class TransportConstants { allowableAcceptorKeys.add(TransportConstants.ENABLED_CIPHER_SUITES_PROP_NAME); allowableAcceptorKeys.add(TransportConstants.ENABLED_PROTOCOLS_PROP_NAME); allowableAcceptorKeys.add(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME); + allowableAcceptorKeys.add(TransportConstants.WANT_CLIENT_AUTH_PROP_NAME); allowableAcceptorKeys.add(TransportConstants.VERIFY_HOST_PROP_NAME); allowableAcceptorKeys.add(TransportConstants.TCP_NODELAY_PROPNAME); allowableAcceptorKeys.add(TransportConstants.TCP_SENDBUFFER_SIZE_PROPNAME); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java index f6424e3c08..5af3db76b5 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/remoting/impl/netty/NettyAcceptor.java @@ -166,6 +166,8 @@ public class NettyAcceptor extends AbstractAcceptor { private final boolean needClientAuth; + private final boolean wantClientAuth; + private final String sslProvider; private final boolean verifyHost; @@ -273,6 +275,8 @@ public class NettyAcceptor extends AbstractAcceptor { needClientAuth = ConfigurationHelper.getBooleanProperty(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, TransportConstants.DEFAULT_NEED_CLIENT_AUTH, configuration); + wantClientAuth = ConfigurationHelper.getBooleanProperty(TransportConstants.WANT_CLIENT_AUTH_PROP_NAME, TransportConstants.DEFAULT_WANT_CLIENT_AUTH, configuration); + verifyHost = ConfigurationHelper.getBooleanProperty(TransportConstants.VERIFY_HOST_PROP_NAME, TransportConstants.DEFAULT_VERIFY_HOST, configuration); sslProvider = ConfigurationHelper.getStringProperty(TransportConstants.SSL_PROVIDER, TransportConstants.DEFAULT_SSL_PROVIDER, configuration); @@ -287,6 +291,7 @@ public class NettyAcceptor extends AbstractAcceptor { enabledCipherSuites = TransportConstants.DEFAULT_ENABLED_CIPHER_SUITES; enabledProtocols = TransportConstants.DEFAULT_ENABLED_PROTOCOLS; needClientAuth = TransportConstants.DEFAULT_NEED_CLIENT_AUTH; + wantClientAuth = TransportConstants.DEFAULT_WANT_CLIENT_AUTH; verifyHost = TransportConstants.DEFAULT_VERIFY_HOST; sslProvider = TransportConstants.DEFAULT_SSL_PROVIDER; } @@ -468,8 +473,11 @@ public class NettyAcceptor extends AbstractAcceptor { engine.setUseClientMode(false); - if (needClientAuth) + if (needClientAuth) { engine.setNeedClientAuth(true); + } else if (wantClientAuth) { + engine.setWantClientAuth(true); + } // setting the enabled cipher suites resets the enabled protocols so we need // to save the enabled protocols so that after the customer cipher suite is enabled diff --git a/docs/user-manual/en/configuring-transports.md b/docs/user-manual/en/configuring-transports.md index 5f83627633..df985b6371 100644 --- a/docs/user-manual/en/configuring-transports.md +++ b/docs/user-manual/en/configuring-transports.md @@ -403,6 +403,18 @@ following additional properties: This property is only for an `acceptor`. It tells a client connecting to this acceptor that 2-way SSL is required. Valid values are `true` or `false`. Default is `false`. + + Note that this property takes precedence over `wantClientAuth` and if + its value is set to true then `wantClientAuth` will be ignored. + +- `wantClientAuth` + + This property is only for an `acceptor`. It tells a client + connecting to this acceptor that 2-way SSL is requested but not required. + Valid values are `true` or `false`. Default is `false`. + + Note that if the property `needClientAuth` is set to true then that + property will take precedence and this property will be ignored. - `verifyHost` diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java index 6d5b77d226..cb59471799 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java @@ -146,6 +146,15 @@ public class SecurityTest extends ActiveMQTestBase { @Test public void testJAASSecurityManagerAuthenticationWithCerts() throws Exception { + testJAASSecurityManagerAuthenticationWithCerts(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME); + } + + @Test + public void testJAASSecurityManagerAuthenticationWithCertsWantClientAuth() throws Exception { + testJAASSecurityManagerAuthenticationWithCerts(TransportConstants.WANT_CLIENT_AUTH_PROP_NAME); + } + + protected void testJAASSecurityManagerAuthenticationWithCerts(String clientAuthPropName) throws Exception { ActiveMQJAASSecurityManager securityManager = new ActiveMQJAASSecurityManager("CertLogin"); ActiveMQServer server = addServer(ActiveMQServers.newActiveMQServer(createDefaultInVMConfig().setSecurityEnabled(true), ManagementFactory.getPlatformMBeanServer(), securityManager, false)); @@ -155,7 +164,7 @@ public class SecurityTest extends ActiveMQTestBase { params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "secureexample"); params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "server-side-truststore.jks"); params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample"); - params.put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true); + params.put(clientAuthPropName, true); server.getConfiguration().addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params)); @@ -612,6 +621,15 @@ public class SecurityTest extends ActiveMQTestBase { @Test public void testJAASSecurityManagerAuthorizationPositiveWithCerts() throws Exception { + testJAASSecurityManagerAuthorizationPositiveWithCerts(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME); + } + + @Test + public void testJAASSecurityManagerAuthorizationPositiveWithCertsWantClientAuth() throws Exception { + testJAASSecurityManagerAuthorizationPositiveWithCerts(TransportConstants.WANT_CLIENT_AUTH_PROP_NAME); + } + + protected void testJAASSecurityManagerAuthorizationPositiveWithCerts(String clientAuthPropName) throws Exception { final SimpleString ADDRESS = new SimpleString("address"); final SimpleString DURABLE_QUEUE = new SimpleString("durableQueue"); final SimpleString NON_DURABLE_QUEUE = new SimpleString("nonDurableQueue"); @@ -625,7 +643,7 @@ public class SecurityTest extends ActiveMQTestBase { params.put(TransportConstants.KEYSTORE_PASSWORD_PROP_NAME, "secureexample"); params.put(TransportConstants.TRUSTSTORE_PATH_PROP_NAME, "server-side-truststore.jks"); params.put(TransportConstants.TRUSTSTORE_PASSWORD_PROP_NAME, "secureexample"); - params.put(TransportConstants.NEED_CLIENT_AUTH_PROP_NAME, true); + params.put(clientAuthPropName, true); server.getConfiguration().addAcceptorConfiguration(new TransportConfiguration(NETTY_ACCEPTOR_FACTORY, params));