You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2021/07/15 07:47:36 UTC

[servicecomb-java-chassis] branch master updated: [SCB-2288]add a configuration for ssl client auth type (#2469)

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new 1c4efc5  [SCB-2288]add a configuration for ssl client auth type (#2469)
1c4efc5 is described below

commit 1c4efc5c1e0bf096c28c6cd2b1f6b4c53ef4bafa
Author: liubao68 <bi...@qq.com>
AuthorDate: Thu Jul 15 15:47:25 2021 +0800

    [SCB-2288]add a configuration for ssl client auth type (#2469)
---
 .../apache/servicecomb/config/TransportUtils.java  |  5 ++
 .../servicecomb/config/kie/TransportUtils.java     |  5 ++
 .../servicecomb/foundation/ssl/ClientAuth.java     | 26 ++++++++++
 .../servicecomb/foundation/ssl/SSLManager.java     | 59 +++++++++++++++-------
 .../servicecomb/foundation/ssl/SSLOption.java      | 24 ++++++++-
 .../servicecomb/foundation/ssl/SSLManagerTest.java | 27 +++++++++-
 .../foundation/vertx/VertxTLSBuilder.java          | 22 ++++++--
 .../serviceregistry/auth/RBACBootStrapService.java |  5 ++
 8 files changed, 148 insertions(+), 25 deletions(-)

diff --git a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/TransportUtils.java b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/TransportUtils.java
index bbfdb72..21a510a 100644
--- a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/TransportUtils.java
+++ b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/TransportUtils.java
@@ -70,6 +70,11 @@ public class TransportUtils {
             DEFAULT_OPTION.getStorePath(),
             "ssl." + tag + ".storePath",
             "ssl.storePath"));
+    option.setClientAuth(
+        getStringProperty(configuration,
+            DEFAULT_OPTION.getClientAuth(),
+            "ssl." + tag + ".clientAuth",
+            "ssl.clientAuth"));
     option.setTrustStore(
         getStringProperty(configuration,
             DEFAULT_OPTION.getTrustStore(),
diff --git a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java
index 42959b7..56afa18 100644
--- a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java
+++ b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/TransportUtils.java
@@ -70,6 +70,11 @@ public class TransportUtils {
             DEFAULT_OPTION.getStorePath(),
             "ssl." + tag + ".storePath",
             "ssl.storePath"));
+    option.setClientAuth(
+        getStringProperty(configuration,
+            DEFAULT_OPTION.getClientAuth(),
+            "ssl." + tag + ".clientAuth",
+            "ssl.clientAuth"));
     option.setTrustStore(
         getStringProperty(configuration,
             DEFAULT_OPTION.getTrustStore(),
diff --git a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/ClientAuth.java b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/ClientAuth.java
new file mode 100644
index 0000000..b80d003
--- /dev/null
+++ b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/ClientAuth.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.foundation.ssl;
+
+public final class ClientAuth {
+  public static final String REQUIRED = "REQUIRED";
+
+  public static final String REQUEST = "REQUEST";
+
+  public static final String NONE = "NONE";
+}
diff --git a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java
index 916d4b0..82c28f7 100644
--- a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java
+++ b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLManager.java
@@ -17,7 +17,6 @@
 
 package org.apache.servicecomb.foundation.ssl;
 
-import java.io.File;
 import java.io.IOException;
 import java.net.UnknownHostException;
 import java.security.KeyManagementException;
@@ -100,8 +99,8 @@ public final class SSLManager {
     SSLContext context = createSSLContext(option, custom);
     SSLSocketFactory factory = context.getSocketFactory();
     String[] supported = factory.getSupportedCipherSuites();
-    String[] eanbled = option.getCiphers().split(",");
-    return new SSLSocketFactoryExt(factory, getEnabledCiphers(supported, eanbled),
+    String[] enabled = option.getCiphers().split(",");
+    return new SSLSocketFactoryExt(factory, getEnabledCiphers(supported, enabled),
         option.getProtocols().split(","));
   }
 
@@ -111,9 +110,9 @@ public final class SSLManager {
         context.createSSLEngine();
     engine.setEnabledProtocols(option.getProtocols().split(","));
     String[] supported = engine.getSupportedCipherSuites();
-    String[] eanbled = option.getCiphers().split(",");
-    engine.setEnabledCipherSuites(getEnabledCiphers(supported, eanbled));
-    engine.setNeedClientAuth(option.isAuthPeer());
+    String[] enabled = option.getCiphers().split(",");
+    engine.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));
+    setClientAuth(option, engine);
     return engine;
   }
 
@@ -123,12 +122,38 @@ public final class SSLManager {
         context.createSSLEngine(peerHost, peerPort);
     engine.setEnabledProtocols(option.getProtocols().split(","));
     String[] supported = engine.getSupportedCipherSuites();
-    String[] eanbled = option.getCiphers().split(",");
-    engine.setEnabledCipherSuites(getEnabledCiphers(supported, eanbled));
-    engine.setNeedClientAuth(option.isAuthPeer());
+    String[] enabled = option.getCiphers().split(",");
+    engine.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));
+    setClientAuth(option, engine);
     return engine;
   }
 
+  private static void setClientAuth(SSLOption option, SSLEngine engine) {
+    if (option.isAuthPeer() || ClientAuth.REQUIRED.equals(option.getClientAuth())) {
+      engine.setNeedClientAuth(true);
+      return;
+    }
+    if (ClientAuth.NONE.equals(option.getClientAuth())) {
+      engine.setNeedClientAuth(false);
+      engine.setWantClientAuth(false);
+      return;
+    }
+    engine.setWantClientAuth(true);
+  }
+
+  private static void setClientAuth(SSLOption option, SSLServerSocket serverSocket) {
+    if (option.isAuthPeer() || ClientAuth.REQUIRED.equals(option.getClientAuth())) {
+      serverSocket.setNeedClientAuth(true);
+      return;
+    }
+    if (ClientAuth.NONE.equals(option.getClientAuth())) {
+      serverSocket.setNeedClientAuth(false);
+      serverSocket.setWantClientAuth(false);
+      return;
+    }
+    serverSocket.setWantClientAuth(true);
+  }
+
   public static SSLServerSocket createSSLServerSocket(SSLOption option,
       SSLCustom custom) {
     try {
@@ -138,9 +163,9 @@ public final class SSLManager {
           (SSLServerSocket) factory.createServerSocket();
       socket.setEnabledProtocols(option.getProtocols().split(","));
       String[] supported = socket.getSupportedCipherSuites();
-      String[] eanbled = option.getCiphers().split(",");
-      socket.setEnabledCipherSuites(getEnabledCiphers(supported, eanbled));
-      socket.setNeedClientAuth(option.isAuthPeer());
+      String[] enabled = option.getCiphers().split(",");
+      socket.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));
+      setClientAuth(option, socket);
       return socket;
     } catch (UnknownHostException e) {
       throw new IllegalArgumentException("unkown host");
@@ -152,16 +177,16 @@ public final class SSLManager {
   public static SSLSocket createSSLSocket(SSLOption option, SSLCustom custom) {
     try {
       SSLContext context = createSSLContext(option, custom);
-      SSLSocketFactory facroty = context.getSocketFactory();
+      SSLSocketFactory factory = context.getSocketFactory();
       SSLSocket socket =
-          (SSLSocket) facroty.createSocket();
+          (SSLSocket) factory.createSocket();
       socket.setEnabledProtocols(option.getProtocols().split(","));
       String[] supported = socket.getSupportedCipherSuites();
-      String[] eanbled = option.getCiphers().split(",");
-      socket.setEnabledCipherSuites(getEnabledCiphers(supported, eanbled));
+      String[] enabled = option.getCiphers().split(",");
+      socket.setEnabledCipherSuites(getEnabledCiphers(supported, enabled));
       return socket;
     } catch (UnknownHostException e) {
-      throw new IllegalArgumentException("unkown host");
+      throw new IllegalArgumentException("unknown host");
     } catch (IOException e) {
       throw new IllegalArgumentException("unable create socket");
     }
diff --git a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java
index 2ac537e..6482466 100644
--- a/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java
+++ b/foundations/foundation-ssl/src/main/java/org/apache/servicecomb/foundation/ssl/SSLOption.java
@@ -76,6 +76,8 @@ public final class SSLOption {
 
   private boolean allowRenegociate;
 
+  private String clientAuth;
+
   private String storePath;
 
   private String trustStore;
@@ -194,6 +196,14 @@ public final class SSLOption {
     return storePath;
   }
 
+  public String getClientAuth() {
+    return this.clientAuth;
+  }
+
+  public void setClientAuth(String clientAuth) {
+    this.clientAuth = clientAuth;
+  }
+
   public String getTrustStore() {
     return trustStore;
   }
@@ -259,7 +269,7 @@ public final class SSLOption {
     for (String key : keys) {
       if (configSource != null) {
         Object v = configSource.getProperty(key);
-        if (List.class.isInstance(v)) {
+        if (v instanceof List) {
           property = listToString(((List<?>) v).toArray());
         } else {
           property = (String) configSource.getProperty(key);
@@ -340,6 +350,11 @@ public final class SSLOption {
             DEFAULT_OPTION.getStorePath(),
             "ssl." + tag + ".storePath",
             "ssl.storePath");
+    option.clientAuth =
+        getStringProperty(configSource,
+            DEFAULT_OPTION.getClientAuth(),
+            "ssl." + tag + ".storePath",
+            "ssl.clientAuth");
     option.trustStore =
         getStringProperty(configSource,
             DEFAULT_OPTION.getTrustStore(),
@@ -383,6 +398,7 @@ public final class SSLOption {
     this.checkCNWhiteFile = propString(props, "ssl.checkCN.white.file");
     this.allowRenegociate = propBoolean(props, "ssl.allowRenegociate");
     this.storePath = propString(props, "ssl.storePath");
+    this.clientAuth = propString(props, "ssl.clientAuth", false);
     this.trustStore = propString(props, "ssl.trustStore");
     this.trustStoreType = propString(props, "ssl.trustStoreType");
     this.trustStoreValue = propString(props, "ssl.trustStoreValue");
@@ -394,8 +410,12 @@ public final class SSLOption {
   }
 
   private String propString(Properties props, String key) {
+    return propString(props, key, true);
+  }
+
+  private String propString(Properties props, String key, boolean required) {
     String s = props.getProperty(key);
-    if (s == null) {
+    if (s == null && required) {
       throw new IllegalArgumentException("No key :" + key);
     }
     return s;
diff --git a/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/SSLManagerTest.java b/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/SSLManagerTest.java
index ac609e1..fb2d3d4 100644
--- a/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/SSLManagerTest.java
+++ b/foundations/foundation-ssl/src/test/java/org/apache/servicecomb/foundation/ssl/SSLManagerTest.java
@@ -120,6 +120,7 @@ public class SSLManagerTest {
       }
     };
     final SSLServerSocket serverSocket = SSLManager.createSSLServerSocket(option, custom);
+    Assert.assertTrue(serverSocket.getNeedClientAuth());
     serverSocket.bind(new InetSocketAddress("127.0.0.1", 8886));
     String[] protos = serverSocket.getEnabledCipherSuites();
     String[] protosExpected =
@@ -201,7 +202,31 @@ public class SSLManagerTest {
     SSLEngine aSSLEngine = SSLManager.createSSLEngine(option, custom);
     // if client mode may not decided at initialization. Different JDK is different, do not check it.
     // Assert.assertEquals(false, aSSLEngine.getUseClientMode());
-    Assert.assertNotNull(aSSLEngine);
+    Assert.assertTrue(aSSLEngine.getNeedClientAuth());
+  }
+
+  @Test
+  public void testCreateSSLEngineClientAuthNone() {
+    SSLOption option = SSLOption.build(DIR + "/server.ssl.properties");
+    option.setClientAuth("NONE");
+    option.setAuthPeer(false);
+    SSLCustom custom = new SSLCustom() {
+      @Override
+      public String getFullPath(String filename) {
+        return DIR + "/ssl/" + filename;
+      }
+
+      @Override
+      public char[] decode(char[] encrypted) {
+        return encrypted;
+      }
+    };
+
+    SSLEngine aSSLEngine = SSLManager.createSSLEngine(option, custom);
+    // if client mode may not decided at initialization. Different JDK is different, do not check it.
+    // Assert.assertEquals(false, aSSLEngine.getUseClientMode());
+    Assert.assertFalse(aSSLEngine.getNeedClientAuth());
+    Assert.assertFalse(aSSLEngine.getWantClientAuth());
   }
 
   @Test
diff --git a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxTLSBuilder.java b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxTLSBuilder.java
index 74d0498..3090572 100644
--- a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxTLSBuilder.java
+++ b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/VertxTLSBuilder.java
@@ -23,7 +23,6 @@ import java.util.Arrays;
 import java.util.HashSet;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.servicecomb.foundation.ssl.KeyStoreUtil;
 import org.apache.servicecomb.foundation.ssl.SSLCustom;
 import org.apache.servicecomb.foundation.ssl.SSLManager;
 import org.apache.servicecomb.foundation.ssl.SSLOption;
@@ -54,12 +53,25 @@ public final class VertxTLSBuilder {
   public static NetServerOptions buildNetServerOptions(SSLOption sslOption, SSLCustom sslCustom,
       NetServerOptions netServerOptions) {
     buildTCPSSLOptions(sslOption, sslCustom, netServerOptions);
-    if (sslOption.isAuthPeer()) {
+    setClientAuth(sslOption, netServerOptions);
+    return netServerOptions;
+  }
+
+  private static void setClientAuth(SSLOption sslOption, NetServerOptions netServerOptions) {
+    if (sslOption.isAuthPeer() || org.apache.servicecomb.foundation.ssl.ClientAuth.REQUIRED
+        .equals(sslOption.getClientAuth())) {
       netServerOptions.setClientAuth(ClientAuth.REQUIRED);
-    } else {
-      netServerOptions.setClientAuth(ClientAuth.REQUEST);
+      return;
     }
-    return netServerOptions;
+
+    if (org.apache.servicecomb.foundation.ssl.ClientAuth.NONE
+        .equals(sslOption.getClientAuth())) {
+      netServerOptions.setClientAuth(ClientAuth.NONE);
+      return;
+    }
+
+    netServerOptions.setClientAuth(ClientAuth.REQUEST);
+    return;
   }
 
   public static void buildHttpClientOptions(String sslKey, HttpClientOptions httpClientOptions) {
diff --git a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
index fcc1f42..4aa696a 100644
--- a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
+++ b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
@@ -131,6 +131,11 @@ public class RBACBootStrapService implements BootStrapService {
             DEFAULT_OPTION.getStorePath(),
             "ssl." + tag + ".storePath",
             "ssl.storePath"));
+    option.setClientAuth(
+        getStringProperty(environment,
+            DEFAULT_OPTION.getClientAuth(),
+            "ssl." + tag + ".clientAuth",
+            "ssl.clientAuth"));
     option.setTrustStore(
         getStringProperty(environment,
             DEFAULT_OPTION.getTrustStore(),