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 0c7f5e1bb [#4300] black/white microservice authentication add
apiWhiteList (#4301)
0c7f5e1bb is described below
commit 0c7f5e1bb13e1f029f2fd861c5ff52b6fc8f5dfa
Author: Cheng YouLing <[email protected]>
AuthorDate: Mon May 6 10:15:26 2024 +0800
[#4300] black/white microservice authentication add apiWhiteList (#4301)
---
.../servicecomb/samples/ConsumerController.java | 5 ++
.../servicecomb/samples/ProviderService.java | 2 +
.../consumer/src/main/resources/application.yml | 5 +-
.../servicecomb/samples/ProviderController.java | 5 ++
.../provider/src/main/resources/application.yml | 9 +++
.../apache/servicecomb/samples/HelloWorldIT.java | 11 +++
.../authentication/provider/PathCheckUtils.java | 92 ++++++++++++++++++++++
.../provider/ProviderAuthFilter.java | 9 ++-
8 files changed, 136 insertions(+), 2 deletions(-)
diff --git
a/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
b/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
index 4ed0ecd85..437f88bfa 100644
---
a/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
+++
b/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ConsumerController.java
@@ -34,4 +34,9 @@ public class ConsumerController {
public String sayHello(@RequestParam("name") String name) {
return providerService.sayHello(name);
}
+
+ @GetMapping("/authIncludePath")
+ public String authIncludePath() {
+ return providerService.authIncludePath();
+ }
}
diff --git
a/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
b/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
index f327412b7..ee62a1106 100644
---
a/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
+++
b/demo/demo-nacos/consumer/src/main/java/org/apache/servicecomb/samples/ProviderService.java
@@ -19,4 +19,6 @@ package org.apache.servicecomb.samples;
public interface ProviderService {
String sayHello(String name);
+
+ String authIncludePath();
}
diff --git a/demo/demo-nacos/consumer/src/main/resources/application.yml
b/demo/demo-nacos/consumer/src/main/resources/application.yml
index 0110e6e27..d2317215e 100644
--- a/demo/demo-nacos/consumer/src/main/resources/application.yml
+++ b/demo/demo-nacos/consumer/src/main/resources/application.yml
@@ -29,5 +29,8 @@ servicecomb:
rest:
address: 0.0.0.0:9092
-
+ publicKey:
+ accessControl:
+ enabled: true
+ excludePathPatterns: '/*'
diff --git
a/demo/demo-nacos/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
b/demo/demo-nacos/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
index 6eea7776a..0076440d2 100644
---
a/demo/demo-nacos/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
+++
b/demo/demo-nacos/provider/src/main/java/org/apache/servicecomb/samples/ProviderController.java
@@ -30,4 +30,9 @@ public class ProviderController {
public String sayHello(@RequestParam("name") String name) {
return "Hello " + name;
}
+
+ @GetMapping("/authIncludePath")
+ public String authIncludePath() {
+ return "success.";
+ }
}
diff --git a/demo/demo-nacos/provider/src/main/resources/application.yml
b/demo/demo-nacos/provider/src/main/resources/application.yml
index b24d281cd..ae6e029b7 100644
--- a/demo/demo-nacos/provider/src/main/resources/application.yml
+++ b/demo/demo-nacos/provider/src/main/resources/application.yml
@@ -31,3 +31,12 @@ servicecomb:
rest:
address: 0.0.0.0:9094
+ publicKey:
+ accessControl:
+ enabled: true
+ includePathPatterns: '/authIncludePath'
+ black:
+ authPath:
+ category: property
+ propertyName: serviceName
+ rule: consumer*
diff --git
a/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
b/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
index 59d06bb1e..ad9460753 100644
---
a/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
+++
b/demo/demo-nacos/test-client/src/main/java/org/apache/servicecomb/samples/HelloWorldIT.java
@@ -30,6 +30,7 @@ public class HelloWorldIT implements CategorizedTestCase {
@Override
public void testRestTransport() throws Exception {
testHelloWorld();
+ testAuthIncludePath();
}
private void testHelloWorld() {
@@ -37,4 +38,14 @@ public class HelloWorldIT implements CategorizedTestCase {
.getForObject(Config.GATEWAY_URL + "/sayHello?name=World",
String.class);
TestMgr.check("Hello World", result);
}
+
+ private void testAuthIncludePath() {
+ String result = "";
+ try {
+ result = template.getForObject(Config.GATEWAY_URL + "/authIncludePath",
String.class);
+ } catch (Exception e) {
+ result = "failed";
+ }
+ TestMgr.check("failed", result);
+ }
}
diff --git
a/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/PathCheckUtils.java
b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/PathCheckUtils.java
new file mode 100644
index 000000000..c587195d2
--- /dev/null
+++
b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/PathCheckUtils.java
@@ -0,0 +1,92 @@
+/*
+ * 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.authentication.provider;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.env.Environment;
+
+public class PathCheckUtils {
+ private static final String KEY_INCLUDE_PATH =
"servicecomb.publicKey.accessControl.includePathPatterns";
+
+ private static final String KEY_EXCLUDE_PATH =
"servicecomb.publicKey.accessControl.excludePathPatterns";
+
+ /**
+ * first determine configured non-authentication path is matched
requestPath, if match not needed auth.
+ * second determine whether of configured authentication path, if not
configured, default all path need auth;
+ * if configured, then check whether of matched requestPath, if match needed
auth, otherwise not needed auth.
+ *
+ * @param requestPath path
+ * @param env environment
+ * @return notRequiredAuth
+ */
+ public static boolean isNotRequiredAuth(String requestPath, Environment env)
{
+ if (excludePathMatchPath(requestPath, env)) {
+ return true;
+ }
+ return includePathMatchPath(requestPath, env);
+ }
+
+ private static boolean excludePathMatchPath(String requestPath, Environment
env) {
+ String excludePathPattern = env.getProperty(KEY_EXCLUDE_PATH, "");
+ if (StringUtils.isEmpty(excludePathPattern)) {
+ return false;
+ }
+ return isPathMather(requestPath, excludePathPattern);
+ }
+
+ private static boolean includePathMatchPath(String requestPath, Environment
env) {
+ String includePathPattern = env.getProperty(KEY_INCLUDE_PATH, "");
+ if (StringUtils.isEmpty(includePathPattern)) {
+ return false;
+ }
+ return !isPathMather(requestPath, includePathPattern);
+ }
+
+ private static boolean isPathMather(String requestPath, String pathPattern) {
+ for (String pattern : pathPattern.split(",")) {
+ if (!pattern.isEmpty() && isPatternMatch(requestPath, pattern)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isPatternMatch(String value, String pattern) {
+ if (pattern.startsWith("*") || pattern.startsWith("/*")) {
+ int index = 0;
+ for (int i = 0; i < pattern.length(); i++) {
+ if (pattern.charAt(i) != '*' && pattern.charAt(i) != '/') {
+ break;
+ }
+ index++;
+ }
+ return value.endsWith(pattern.substring(index));
+ }
+ if (pattern.endsWith("*")) {
+ int index = pattern.length() - 1;
+ for (int i = pattern.length() - 1; i >= 0; i--) {
+ if (pattern.charAt(i) != '*' && pattern.charAt(i) != '/') {
+ break;
+ }
+ index--;
+ }
+ return value.startsWith(pattern.substring(0, index + 1));
+ }
+ return value.equals(pattern);
+ }
+}
diff --git
a/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java
b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java
index 93563f403..02b1108a5 100644
---
a/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java
+++
b/handlers/handler-publickey-auth/src/main/java/org/apache/servicecomb/authentication/provider/ProviderAuthFilter.java
@@ -27,15 +27,19 @@ import org.apache.servicecomb.core.filter.ProviderFilter;
import org.apache.servicecomb.swagger.invocation.Response;
import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
import jakarta.ws.rs.core.Response.Status;
public class ProviderAuthFilter extends AbstractFilter implements
ProviderFilter {
private ProviderTokenManager authenticationTokenManager;
+ private Environment env;
+
@Autowired
- public void setProviderTokenManager(ProviderTokenManager
providerTokenManager) {
+ public void setProviderTokenManager(ProviderTokenManager
providerTokenManager, Environment env) {
this.authenticationTokenManager = providerTokenManager;
+ this.env = env;
}
@Override
@@ -50,6 +54,9 @@ public class ProviderAuthFilter extends AbstractFilter
implements ProviderFilter
@Override
public CompletableFuture<Response> onFilter(Invocation invocation,
FilterNode nextNode) {
+ if
(PathCheckUtils.isNotRequiredAuth(invocation.getOperationMeta().getOperationPath(),
env)) {
+ return nextNode.onFilter(invocation);
+ }
String token = invocation.getContext(CoreConst.AUTH_TOKEN);
if (null != token && authenticationTokenManager.valid(token)) {
return nextNode.onFilter(invocation);