From abc22393ba8730b686faec5c20a357714f1c0b2f Mon Sep 17 00:00:00 2001
From: Haotian Zhang <928016560@qq.com>
Date: Thu, 14 Nov 2024 21:16:05 +0800
Subject: [PATCH] feat:support auth.
---
polaris-auth/polaris-auth-api/pom.xml | 29 ++
.../polaris/auth/api/core/AuthAPI.java | 46 +++
.../polaris/auth/api/flow/AuthFlow.java | 37 ++
.../polaris/auth/api/rpc/AuthRequest.java | 86 +++++
.../polaris/auth/api/rpc/AuthResponse.java | 45 +++
polaris-auth/polaris-auth-client/pom.xml | 31 ++
.../auth/client/api/DefaultAuthAPI.java | 53 +++
.../auth/client/flow/DefaultAuthFlow.java | 81 +++++
.../auth/client/utils/AuthValidator.java | 39 +++
...com.tencent.polaris.auth.api.flow.AuthFlow | 1 +
polaris-auth/polaris-auth-factory/pom.xml | 35 ++
.../polaris/auth/factory/AuthAPIFactory.java | 69 ++++
polaris-auth/pom.xml | 23 ++
.../main/resources/conf/default-config.yml | 8 +
.../api/config/plugin/DefaultPlugins.java | 5 +
.../api/config/provider/AuthConfig.java | 41 +++
.../api/config/provider/ProviderConfig.java | 9 +
.../config/provider/AuthConfigImpl.java | 81 +++++
.../config/provider/ProviderConfigImpl.java | 15 +
.../polaris/api/pojo/ServiceEventKey.java | 1 +
.../tencent/polaris/api/utils/RuleUtils.java | 22 +-
polaris-dependencies/pom.xml | 24 +-
.../polaris/api/plugin/auth/AuthInfo.java | 97 ++++++
.../polaris/api/plugin/auth/AuthResult.java | 57 ++++
.../api/plugin/auth/Authenticator.java | 36 ++
.../api/plugin/common/PluginTypes.java | 8 +-
.../api/plugin/compose/Extensions.java | 29 ++
.../auth-block-allow-list/pom.xml | 30 ++
.../BlockAllowListAuthenticator.java | 232 +++++++++++++
...cent.polaris.api.plugin.auth.Authenticator | 1 +
.../BlockAllowListAuthenticatorTest.java | 213 ++++++++++++
polaris-plugins/polaris-plugins-auth/pom.xml | 29 ++
.../common/DestroyableServerConnector.java | 5 +-
.../connector/common/ServiceUpdateTask.java | 6 +-
.../composite/CompositeServiceUpdateTask.java | 13 +-
.../connector/consul/ConsulAPIConnector.java | 2 +
.../service/authority/AuthorityService.java | 321 ++++++++++++++++++
.../service/authority/entity/AuthRule.java | 153 +++++++++
.../authority/entity/AuthRuleGroup.java | 59 ++++
.../service/authority/entity/AuthTag.java | 14 +
.../authority/entity/TsfAuthConstant.java | 24 ++
.../plugins/connector/grpc/GrpcUtil.java | 6 +
.../codec/BlockAllowListRuleCacheHandler.java | 92 +++++
...t.polaris.api.plugin.registry.CacheHandler | 3 +-
polaris-plugins/pom.xml | 1 +
.../ratelimit/client/flow/QuotaFlow.java | 7 +-
pom.xml | 1 +
47 files changed, 2203 insertions(+), 17 deletions(-)
create mode 100644 polaris-auth/polaris-auth-api/pom.xml
create mode 100644 polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/core/AuthAPI.java
create mode 100644 polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/flow/AuthFlow.java
create mode 100644 polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthRequest.java
create mode 100644 polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthResponse.java
create mode 100644 polaris-auth/polaris-auth-client/pom.xml
create mode 100644 polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/api/DefaultAuthAPI.java
create mode 100644 polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/flow/DefaultAuthFlow.java
create mode 100644 polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/utils/AuthValidator.java
create mode 100644 polaris-auth/polaris-auth-client/src/main/resources/META-INF/services/com.tencent.polaris.auth.api.flow.AuthFlow
create mode 100644 polaris-auth/polaris-auth-factory/pom.xml
create mode 100644 polaris-auth/polaris-auth-factory/src/main/java/com/tencent/polaris/auth/factory/AuthAPIFactory.java
create mode 100644 polaris-auth/pom.xml
create mode 100644 polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/AuthConfig.java
create mode 100644 polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/AuthConfigImpl.java
create mode 100644 polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthInfo.java
create mode 100644 polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthResult.java
create mode 100644 polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/Authenticator.java
create mode 100644 polaris-plugins/polaris-plugins-auth/auth-block-allow-list/pom.xml
create mode 100644 polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticator.java
create mode 100644 polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.auth.Authenticator
create mode 100644 polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/test/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticatorTest.java
create mode 100644 polaris-plugins/polaris-plugins-auth/pom.xml
create mode 100644 polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/AuthorityService.java
create mode 100644 polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRule.java
create mode 100644 polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRuleGroup.java
create mode 100644 polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthTag.java
create mode 100644 polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/TsfAuthConstant.java
create mode 100644 polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/codec/BlockAllowListRuleCacheHandler.java
diff --git a/polaris-auth/polaris-auth-api/pom.xml b/polaris-auth/polaris-auth-api/pom.xml
new file mode 100644
index 000000000..cb44f790a
--- /dev/null
+++ b/polaris-auth/polaris-auth-api/pom.xml
@@ -0,0 +1,29 @@
+
+
+
+ polaris-auth
+ com.tencent.polaris
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ polaris-auth-api
+ Polaris Auth API
+ Polaris Auth API JAR
+
+
+
+ com.tencent.polaris
+ polaris-plugin-api
+ ${project.version}
+
+
+ com.tencent.polaris
+ polaris-client
+ ${project.version}
+
+
+
\ No newline at end of file
diff --git a/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/core/AuthAPI.java b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/core/AuthAPI.java
new file mode 100644
index 000000000..dc1cf43e8
--- /dev/null
+++ b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/core/AuthAPI.java
@@ -0,0 +1,46 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.api.core;
+
+import com.tencent.polaris.api.exception.PolarisException;
+import com.tencent.polaris.auth.api.rpc.AuthRequest;
+import com.tencent.polaris.auth.api.rpc.AuthResponse;
+
+import java.io.Closeable;
+
+public interface AuthAPI extends AutoCloseable, Closeable {
+
+ /**
+ * 鉴权
+ *
+ * @param authRequest 鉴权请求(服务及标签信息)
+ * @return 鉴权通过情况
+ * @throws PolarisException 异常信息
+ */
+ AuthResponse authenticate(AuthRequest authRequest) throws PolarisException;
+
+ /**
+ * 清理并释放资源
+ */
+ void destroy();
+
+ @Override
+ default void close() {
+ destroy();
+ }
+}
diff --git a/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/flow/AuthFlow.java b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/flow/AuthFlow.java
new file mode 100644
index 000000000..a7c7c9b56
--- /dev/null
+++ b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/flow/AuthFlow.java
@@ -0,0 +1,37 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.api.flow;
+
+import com.tencent.polaris.api.exception.PolarisException;
+import com.tencent.polaris.auth.api.rpc.AuthRequest;
+import com.tencent.polaris.auth.api.rpc.AuthResponse;
+import com.tencent.polaris.client.flow.AbstractFlow;
+
+public interface AuthFlow extends AbstractFlow {
+
+ /**
+ * 鉴权
+ *
+ * @param authRequest 鉴权请求(服务及标签信息)
+ * @return 鉴权通过情况
+ * @throws PolarisException 异常信息
+ */
+ default AuthResponse authenticate(AuthRequest authRequest) {
+ return null;
+ }
+}
diff --git a/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthRequest.java b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthRequest.java
new file mode 100644
index 000000000..9babda03b
--- /dev/null
+++ b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthRequest.java
@@ -0,0 +1,86 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.api.rpc;
+
+import com.tencent.polaris.api.rpc.RequestBaseEntity;
+import com.tencent.polaris.metadata.core.manager.MetadataContext;
+
+/**
+ * 鉴权请求
+ *
+ * @author Haotian Zhang
+ */
+public class AuthRequest extends RequestBaseEntity {
+
+ private final String namespace;
+
+ private final String service;
+
+ private final String path;
+
+ private final String protocol;
+
+ private final String method;
+
+ private final MetadataContext metadataContext;
+
+ public AuthRequest(String namespace, String service, String path, String protocol, String method, MetadataContext metadataContext) {
+ this.namespace = namespace;
+ this.service = service;
+ this.path = path;
+ this.protocol = protocol;
+ this.method = method;
+ this.metadataContext = metadataContext;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getService() {
+ return service;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public MetadataContext getMetadataContext() {
+ return metadataContext;
+ }
+
+ @Override
+ public String toString() {
+ return "AuthRequest{" +
+ "namespace='" + namespace + '\'' +
+ ", service='" + service + '\'' +
+ ", path='" + path + '\'' +
+ ", protocol='" + protocol + '\'' +
+ ", method='" + method + '\'' +
+ ", metadataContext=" + metadataContext +
+ '}';
+ }
+}
diff --git a/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthResponse.java b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthResponse.java
new file mode 100644
index 000000000..90be24022
--- /dev/null
+++ b/polaris-auth/polaris-auth-api/src/main/java/com/tencent/polaris/auth/api/rpc/AuthResponse.java
@@ -0,0 +1,45 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.api.rpc;
+
+import com.tencent.polaris.api.plugin.auth.AuthResult;
+
+/**
+ * 鉴权响应
+ *
+ * @author Haotian Zhang
+ */
+public class AuthResponse {
+
+ private final AuthResult authResult;
+
+ public AuthResponse(AuthResult authResult) {
+ this.authResult = authResult;
+ }
+
+ public AuthResult getAuthResult() {
+ return authResult;
+ }
+
+ @Override
+ public String toString() {
+ return "AuthResponse{" +
+ "authResult=" + authResult +
+ '}';
+ }
+}
diff --git a/polaris-auth/polaris-auth-client/pom.xml b/polaris-auth/polaris-auth-client/pom.xml
new file mode 100644
index 000000000..2edbf9729
--- /dev/null
+++ b/polaris-auth/polaris-auth-client/pom.xml
@@ -0,0 +1,31 @@
+
+
+
+ polaris-auth
+ com.tencent.polaris
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ polaris-auth-client
+ Polaris Auth Client
+ Polaris Auth Client JAR
+
+
+
+ com.tencent.polaris
+ polaris-auth-api
+ ${project.version}
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ provided
+
+
+
\ No newline at end of file
diff --git a/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/api/DefaultAuthAPI.java b/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/api/DefaultAuthAPI.java
new file mode 100644
index 000000000..cbff1ff1d
--- /dev/null
+++ b/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/api/DefaultAuthAPI.java
@@ -0,0 +1,53 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.client.api;
+
+import com.tencent.polaris.api.exception.PolarisException;
+import com.tencent.polaris.auth.api.core.AuthAPI;
+import com.tencent.polaris.auth.api.flow.AuthFlow;
+import com.tencent.polaris.auth.api.rpc.AuthRequest;
+import com.tencent.polaris.auth.api.rpc.AuthResponse;
+import com.tencent.polaris.auth.client.utils.AuthValidator;
+import com.tencent.polaris.client.api.BaseEngine;
+import com.tencent.polaris.client.api.SDKContext;
+
+/**
+ * 默认的鉴权API实现
+ *
+ * @author Haotian Zhang
+ */
+public class DefaultAuthAPI extends BaseEngine implements AuthAPI {
+
+ private AuthFlow authFlow;
+
+ public DefaultAuthAPI(SDKContext sdkContext) {
+ super(sdkContext);
+ }
+
+ @Override
+ protected void subInit() {
+ authFlow = sdkContext.getOrInitFlow(AuthFlow.class);
+ }
+
+ @Override
+ public AuthResponse authenticate(AuthRequest authRequest) throws PolarisException {
+ checkAvailable("AuthFlow");
+ AuthValidator.validateAuthRequest(authRequest);
+ return authFlow.authenticate(authRequest);
+ }
+}
diff --git a/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/flow/DefaultAuthFlow.java b/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/flow/DefaultAuthFlow.java
new file mode 100644
index 000000000..421ec010d
--- /dev/null
+++ b/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/flow/DefaultAuthFlow.java
@@ -0,0 +1,81 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.client.flow;
+
+import com.tencent.polaris.api.config.global.FlowConfig;
+import com.tencent.polaris.api.config.provider.AuthConfig;
+import com.tencent.polaris.api.plugin.auth.AuthInfo;
+import com.tencent.polaris.api.plugin.auth.AuthResult;
+import com.tencent.polaris.api.plugin.auth.Authenticator;
+import com.tencent.polaris.api.plugin.compose.Extensions;
+import com.tencent.polaris.auth.api.flow.AuthFlow;
+import com.tencent.polaris.auth.api.rpc.AuthRequest;
+import com.tencent.polaris.auth.api.rpc.AuthResponse;
+import com.tencent.polaris.client.api.SDKContext;
+import com.tencent.polaris.logging.LoggerFactory;
+import org.slf4j.Logger;
+
+import java.util.List;
+
+/**
+ * 默认的鉴权Flow实现
+ *
+ * @author Haotian Zhang
+ */
+public class DefaultAuthFlow implements AuthFlow {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DefaultAuthFlow.class);
+
+ private SDKContext sdkContext;
+
+ private AuthConfig authConfig;
+
+ private Extensions extensions;
+
+ private List authenticatorList;
+
+ @Override
+ public String getName() {
+ return FlowConfig.DEFAULT_FLOW_NAME;
+ }
+
+ @Override
+ public void setSDKContext(SDKContext sdkContext) {
+ this.sdkContext = sdkContext;
+ this.authConfig = sdkContext.getConfig().getProvider().getAuth();
+ this.extensions = sdkContext.getExtensions();
+ this.authenticatorList = extensions.getAuthenticatorList();
+ }
+
+ @Override
+ public AuthResponse authenticate(AuthRequest authRequest) {
+ if (authConfig == null || !authConfig.isEnable()) {
+ return new AuthResponse(new AuthResult(AuthResult.Code.AuthResultOk));
+ }
+ AuthInfo authInfo = new AuthInfo(authRequest.getNamespace(), authRequest.getService(), authRequest.getPath(),
+ authRequest.getProtocol(), authRequest.getMethod(), authRequest.getMetadataContext());
+ AuthResponse authResponse = new AuthResponse(new AuthResult(AuthResult.Code.AuthResultOk));
+ for (Authenticator authenticator : authenticatorList) {
+ AuthResult authResult = authenticator.authenticate(authInfo);
+ if (authResult.getCode().equals(AuthResult.Code.AuthResultForbidden)) {
+ return new AuthResponse(authResult);
+ }
+ }
+ return authResponse;
+ }
+}
diff --git a/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/utils/AuthValidator.java b/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/utils/AuthValidator.java
new file mode 100644
index 000000000..8ffcab53d
--- /dev/null
+++ b/polaris-auth/polaris-auth-client/src/main/java/com/tencent/polaris/auth/client/utils/AuthValidator.java
@@ -0,0 +1,39 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.client.utils;
+
+import com.tencent.polaris.api.exception.ErrorCode;
+import com.tencent.polaris.api.exception.PolarisException;
+import com.tencent.polaris.auth.api.rpc.AuthRequest;
+import com.tencent.polaris.client.util.CommonValidator;
+
+public class AuthValidator {
+
+ /**
+ * 校验鉴权请求
+ *
+ * @param authRequest 鉴权请求参数
+ * @throws PolarisException 校验失败
+ */
+ public static void validateAuthRequest(AuthRequest authRequest) throws PolarisException {
+ if (null == authRequest) {
+ throw new PolarisException(ErrorCode.API_INVALID_ARGUMENT, "AuthRequest can not be null");
+ }
+ CommonValidator.validateNamespaceService(authRequest.getNamespace(), authRequest.getService());
+ }
+}
diff --git a/polaris-auth/polaris-auth-client/src/main/resources/META-INF/services/com.tencent.polaris.auth.api.flow.AuthFlow b/polaris-auth/polaris-auth-client/src/main/resources/META-INF/services/com.tencent.polaris.auth.api.flow.AuthFlow
new file mode 100644
index 000000000..889ce40b4
--- /dev/null
+++ b/polaris-auth/polaris-auth-client/src/main/resources/META-INF/services/com.tencent.polaris.auth.api.flow.AuthFlow
@@ -0,0 +1 @@
+com.tencent.polaris.auth.client.flow.DefaultAuthFlow
\ No newline at end of file
diff --git a/polaris-auth/polaris-auth-factory/pom.xml b/polaris-auth/polaris-auth-factory/pom.xml
new file mode 100644
index 000000000..22bbf7fe0
--- /dev/null
+++ b/polaris-auth/polaris-auth-factory/pom.xml
@@ -0,0 +1,35 @@
+
+
+
+ polaris-auth
+ com.tencent.polaris
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ polaris-auth-factory
+ Polaris Auth Factory
+ Polaris Auth Factory JAR
+
+
+
+ com.tencent.polaris
+ polaris-auth-client
+ ${project.version}
+
+
+ com.tencent.polaris
+ polaris-client
+ ${project.version}
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ provided
+
+
+
\ No newline at end of file
diff --git a/polaris-auth/polaris-auth-factory/src/main/java/com/tencent/polaris/auth/factory/AuthAPIFactory.java b/polaris-auth/polaris-auth-factory/src/main/java/com/tencent/polaris/auth/factory/AuthAPIFactory.java
new file mode 100644
index 000000000..fd60ae5e5
--- /dev/null
+++ b/polaris-auth/polaris-auth-factory/src/main/java/com/tencent/polaris/auth/factory/AuthAPIFactory.java
@@ -0,0 +1,69 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.auth.factory;
+
+import com.tencent.polaris.api.config.Configuration;
+import com.tencent.polaris.api.exception.PolarisException;
+import com.tencent.polaris.auth.api.core.AuthAPI;
+import com.tencent.polaris.auth.client.api.DefaultAuthAPI;
+import com.tencent.polaris.client.api.SDKContext;
+import com.tencent.polaris.factory.ConfigAPIFactory;
+
+/**
+ * Factory to create AuthAPI.
+ *
+ * @author Haotian Zhang
+ */
+public class AuthAPIFactory {
+
+ /**
+ * 通过默认配置创建 AuthAPI
+ *
+ * @return AuthAPI 对象
+ * @throws PolarisException 初始化过程异常
+ */
+ public static AuthAPI createAuthAPI() throws PolarisException {
+ Configuration configuration = ConfigAPIFactory.defaultConfig();
+ return createAuthAPIByConfig(configuration);
+ }
+
+ /**
+ * 通过 SDKContext 创建 AuthAPI
+ *
+ * @param sdkContext 上下文信息
+ * @return AuthAPI 对象
+ * @throws PolarisException 创建过程的初始化异常
+ */
+ public static AuthAPI createAuthAPIByContext(SDKContext sdkContext) throws PolarisException {
+ DefaultAuthAPI defaultAuthAPI = new DefaultAuthAPI(sdkContext);
+ defaultAuthAPI.init();
+ return defaultAuthAPI;
+ }
+
+ /**
+ * 通过配置对象创建 AuthAPI
+ *
+ * @param config 配置对象
+ * @return AuthAPI 对象
+ * @throws PolarisException 初始化过程的异常
+ */
+ public static AuthAPI createAuthAPIByConfig(Configuration config) throws PolarisException {
+ SDKContext context = SDKContext.initContextByConfig(config);
+ return createAuthAPIByContext(context);
+ }
+}
diff --git a/polaris-auth/pom.xml b/polaris-auth/pom.xml
new file mode 100644
index 000000000..a872fe10a
--- /dev/null
+++ b/polaris-auth/pom.xml
@@ -0,0 +1,23 @@
+
+
+
+ polaris-parent
+ com.tencent.polaris
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ polaris-auth
+ pom
+ Polaris Auth
+ Polaris Auth POM
+
+
+ polaris-auth-api
+ polaris-auth-client
+ polaris-auth-factory
+
+
\ No newline at end of file
diff --git a/polaris-common/polaris-config-default/src/main/resources/conf/default-config.yml b/polaris-common/polaris-config-default/src/main/resources/conf/default-config.yml
index 87e13b1de..c52f22391 100644
--- a/polaris-common/polaris-config-default/src/main/resources/conf/default-config.yml
+++ b/polaris-common/polaris-config-default/src/main/resources/conf/default-config.yml
@@ -303,6 +303,14 @@ provider:
delayRegisterInterval: 30s
# 优雅上线的探测周期
healthCheckInterval: 5s
+ # 服务鉴权
+ auth:
+ # 是否启用服务鉴权
+ enable: false
+ #描述: 服务鉴权插件链
+ chain:
+ # 黑白名单鉴权插件
+ - blockAllowList
# 限流配置
rateLimit:
# 是否开启限流功能
diff --git a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/plugin/DefaultPlugins.java b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/plugin/DefaultPlugins.java
index f0f101122..1b83d2cb8 100644
--- a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/plugin/DefaultPlugins.java
+++ b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/plugin/DefaultPlugins.java
@@ -89,4 +89,9 @@ public interface DefaultPlugins {
* TSF 事件上报插件名
*/
String TSF_EVENT_REPORTER_TYPE = "tsf";
+
+ /**
+ * 黑白名单鉴权插件名
+ */
+ String BLOCK_ALLOW_LIST_AUTHENTICATOR_TYPE = "blockAllowList";
}
diff --git a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/AuthConfig.java b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/AuthConfig.java
new file mode 100644
index 000000000..582fe7143
--- /dev/null
+++ b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/AuthConfig.java
@@ -0,0 +1,41 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.api.config.provider;
+
+import com.tencent.polaris.api.config.verify.Verifier;
+
+import java.util.List;
+
+public interface AuthConfig extends Verifier {
+
+ /**
+ * 是否启用服务鉴权
+ * provider.auth.enable
+ *
+ * @return 启用鉴权
+ */
+ boolean isEnable();
+
+ /**
+ * 服务鉴权插件链配置
+ * provider.auth.chain
+ *
+ * @return 鉴权插件链列表
+ */
+ List getChain();
+}
diff --git a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/ProviderConfig.java b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/ProviderConfig.java
index 55c0f5dff..9db70e48f 100644
--- a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/ProviderConfig.java
+++ b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/api/config/provider/ProviderConfig.java
@@ -18,6 +18,7 @@
package com.tencent.polaris.api.config.provider;
import com.tencent.polaris.api.config.verify.Verifier;
+
import java.util.List;
import java.util.Map;
@@ -72,7 +73,15 @@ public interface ProviderConfig extends Verifier {
/**
* get the lossless configuration
+ *
* @return configuration
*/
LosslessConfig getLossless();
+
+ /**
+ * get the auth configuration
+ *
+ * @return AuthConfig
+ */
+ AuthConfig getAuth();
}
diff --git a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/AuthConfigImpl.java b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/AuthConfigImpl.java
new file mode 100644
index 000000000..ae6904b6a
--- /dev/null
+++ b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/AuthConfigImpl.java
@@ -0,0 +1,81 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.factory.config.provider;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.tencent.polaris.api.config.provider.AuthConfig;
+import com.tencent.polaris.api.utils.CollectionUtils;
+import com.tencent.polaris.factory.util.ConfigUtils;
+
+import java.util.List;
+
+public class AuthConfigImpl implements AuthConfig {
+
+ @JsonProperty
+ private Boolean enable;
+
+ @JsonProperty
+ private List chain;
+
+ @Override
+ public boolean isEnable() {
+ return enable;
+ }
+
+ public void setEnable(Boolean enable) {
+ this.enable = enable;
+ }
+
+ @Override
+ public List getChain() {
+ return chain;
+ }
+
+ public void setChain(List chain) {
+ this.chain = chain;
+ }
+
+ @Override
+ public void verify() {
+ ConfigUtils.validateNull(enable, "provider.auth.enable");
+ if (CollectionUtils.isEmpty(chain)) {
+ throw new IllegalArgumentException("provider.auth.chain must not be empty");
+ }
+ }
+
+ @Override
+ public void setDefault(Object defaultObject) {
+ if (null != defaultObject) {
+ AuthConfig authConfig = (AuthConfig) defaultObject;
+ if (null == enable) {
+ setEnable(authConfig.isEnable());
+ }
+ if (CollectionUtils.isEmpty(chain)) {
+ setChain(authConfig.getChain());
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "AuthConfigImpl{" +
+ "enable=" + enable +
+ ", chain=" + chain +
+ '}';
+ }
+}
diff --git a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/ProviderConfigImpl.java b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/ProviderConfigImpl.java
index 55b5df368..3d51fa315 100644
--- a/polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/ProviderConfigImpl.java
+++ b/polaris-common/polaris-config/src/main/java/com/tencent/polaris/factory/config/provider/ProviderConfigImpl.java
@@ -23,6 +23,7 @@
import com.tencent.polaris.api.config.provider.ProviderConfig;
import com.tencent.polaris.api.utils.CollectionUtils;
import com.tencent.polaris.factory.util.ConfigUtils;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -63,6 +64,9 @@ public class ProviderConfigImpl implements ProviderConfig {
@JsonProperty
private LosslessConfigImpl lossless;
+ @JsonProperty
+ private AuthConfigImpl auth;
+
@Override
public RateLimitConfigImpl getRateLimit() {
return rateLimit;
@@ -83,6 +87,11 @@ public LosslessConfig getLossless() {
return lossless;
}
+ @Override
+ public AuthConfigImpl getAuth() {
+ return auth;
+ }
+
@Override
public List getRegisters() {
if (CollectionUtils.isEmpty(registers)) {
@@ -113,6 +122,7 @@ public Map getRegisterConfigMap() {
public void verify() {
ConfigUtils.validateNull(rateLimit, "rateLimitConfig");
ConfigUtils.validateNull(lossless, "losslessConfig");
+ ConfigUtils.validateNull(auth, "authConfig");
rateLimit.verify();
if (CollectionUtils.isNotEmpty(registers)) {
@@ -131,6 +141,9 @@ public void setDefault(Object defaultObject) {
if (null == lossless) {
lossless = new LosslessConfigImpl();
}
+ if (null == auth) {
+ auth = new AuthConfigImpl();
+ }
if (null == service) {
service = new ServiceConfigImpl();
}
@@ -144,6 +157,7 @@ public void setDefault(Object defaultObject) {
ProviderConfig providerConfig = (ProviderConfig) defaultObject;
rateLimit.setDefault(providerConfig.getRateLimit());
lossless.setDefault(providerConfig.getLossless());
+ auth.setDefault(providerConfig.getAuth());
if (CollectionUtils.isNotEmpty(registers)) {
for (RegisterConfigImpl registerConfig : registers) {
registerConfig.setDefault(providerConfig.getRegisters().get(0));
@@ -175,6 +189,7 @@ public String toString() {
", minRegisterInterval=" + minRegisterInterval +
", heartbeatWorkerSize=" + heartbeatWorkerSize +
", lossless=" + lossless +
+ ", auth=" + auth +
'}';
}
}
diff --git a/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/pojo/ServiceEventKey.java b/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/pojo/ServiceEventKey.java
index 5168805b4..6cd7464a9 100644
--- a/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/pojo/ServiceEventKey.java
+++ b/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/pojo/ServiceEventKey.java
@@ -34,6 +34,7 @@ public enum EventType {
LANE_RULE,
NEARBY_ROUTE_RULE,
LOSSLESS,
+ BLOCK_ALLOW_RULE,
}
private final ServiceKey serviceKey;
diff --git a/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/utils/RuleUtils.java b/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/utils/RuleUtils.java
index 68ac7ee9a..a880d791b 100644
--- a/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/utils/RuleUtils.java
+++ b/polaris-common/polaris-model/src/main/java/com/tencent/polaris/api/utils/RuleUtils.java
@@ -22,6 +22,7 @@
import com.tencent.polaris.api.pojo.TrieNode;
import com.tencent.polaris.logging.LoggerFactory;
import com.tencent.polaris.metadata.core.manager.MetadataContainerGroup;
+import com.tencent.polaris.specification.api.v1.model.ModelProto;
import com.tencent.polaris.specification.api.v1.model.ModelProto.MatchString;
import com.tencent.polaris.specification.api.v1.model.ModelProto.MatchString.MatchStringType;
import org.slf4j.Logger;
@@ -94,7 +95,7 @@ public static boolean matchStringValue(MatchStringType matchType, String actualV
if (useTrieNode && trieNodeFunction != null) {
return ApiTrieUtil.checkSimple(trieNodeFunction.apply(matchValue), actualValue);
}
- return StringUtils.equals(actualValue, matchValue);
+ return StringUtils.equalsIgnoreCase(actualValue, matchValue);
}
case REGEX: {
//正则表达式匹配
@@ -105,7 +106,7 @@ public static boolean matchStringValue(MatchStringType matchType, String actualV
if (useTrieNode && trieNodeFunction != null) {
return !ApiTrieUtil.checkSimple(trieNodeFunction.apply(matchValue), actualValue);
}
- return !StringUtils.equals(actualValue, matchValue);
+ return !StringUtils.equalsIgnoreCase(actualValue, matchValue);
}
case IN: {
String[] tokens = matchValue.split(",");
@@ -115,7 +116,7 @@ public static boolean matchStringValue(MatchStringType matchType, String actualV
return true;
}
} else {
- if (StringUtils.equals(token, actualValue)) {
+ if (StringUtils.equalsIgnoreCase(token, actualValue)) {
return true;
}
}
@@ -130,7 +131,7 @@ public static boolean matchStringValue(MatchStringType matchType, String actualV
return false;
}
} else {
- if (StringUtils.equals(token, actualValue)) {
+ if (StringUtils.equalsIgnoreCase(token, actualValue)) {
return false;
}
}
@@ -342,4 +343,17 @@ public static boolean matchService(ServiceKey serviceKey, String namespace, Stri
}
return true;
}
+
+ public static boolean matchMethod(String path, String protocol, String method, ModelProto.API api,
+ Function regexToPattern, Function> trieNodeFunction) {
+ if (trieNodeFunction != null) {
+ return RuleUtils.matchStringValue(MatchString.MatchStringType.EXACT, protocol, api.getProtocol())
+ && RuleUtils.matchStringValue(MatchString.MatchStringType.EXACT, method, api.getMethod())
+ && RuleUtils.matchStringValue(api.getPath().getType(), path, api.getPath().getValue().getValue(), regexToPattern, true, trieNodeFunction);
+ } else {
+ return RuleUtils.matchStringValue(MatchString.MatchStringType.EXACT, protocol, api.getProtocol())
+ && RuleUtils.matchStringValue(MatchString.MatchStringType.EXACT, method, api.getMethod())
+ && RuleUtils.matchStringValue(api.getPath(), path, regexToPattern);
+ }
+ }
}
diff --git a/polaris-dependencies/pom.xml b/polaris-dependencies/pom.xml
index a399d0210..b24b6434a 100644
--- a/polaris-dependencies/pom.xml
+++ b/polaris-dependencies/pom.xml
@@ -145,7 +145,29 @@
${project.version}
-
+
+
+ com.tencent.polaris
+ polaris-auth-api
+ ${project.version}
+
+
+ com.tencent.polaris
+ polaris-auth-client
+ ${project.version}
+
+
+ com.tencent.polaris
+ polaris-auth-factory
+ ${project.version}
+
+
+ com.tencent.polaris
+ auth-block-allow-list
+ ${project.version}
+
+
+
com.tencent.polaris
polaris-assembly-api
diff --git a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthInfo.java b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthInfo.java
new file mode 100644
index 000000000..eca475fe4
--- /dev/null
+++ b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthInfo.java
@@ -0,0 +1,97 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.api.plugin.auth;
+
+import com.tencent.polaris.metadata.core.manager.MetadataContext;
+
+/**
+ * 鉴权信息
+ *
+ * @author Haotian Zhang
+ */
+public class AuthInfo {
+
+ private String namespace;
+
+ private String service;
+
+ private String path;
+
+ private String protocol;
+
+ private String method;
+
+ private MetadataContext metadataContext;
+
+ public AuthInfo(String namespace, String service, String path, String protocol, String method, MetadataContext metadataContext) {
+ this.namespace = namespace;
+ this.service = service;
+ this.path = path;
+ this.protocol = protocol;
+ this.method = method;
+ this.metadataContext = metadataContext;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String getService() {
+ return service;
+ }
+
+ public void setService(String service) {
+ this.service = service;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ public MetadataContext getMetadataContext() {
+ return metadataContext;
+ }
+
+ public void setMetadataContext(MetadataContext metadataContext) {
+ this.metadataContext = metadataContext;
+ }
+}
diff --git a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthResult.java b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthResult.java
new file mode 100644
index 000000000..31dabc86f
--- /dev/null
+++ b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/AuthResult.java
@@ -0,0 +1,57 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.api.plugin.auth;
+
+/**
+ * 鉴权结果
+ *
+ * @author Haotian Zhang
+ */
+public class AuthResult {
+
+ /**
+ * 限流返回码
+ */
+ public enum Code {
+ /**
+ * OK,代表请求可以通过
+ */
+ AuthResultOk,
+ /**
+ * FORBIDDEN,代表本次请求被禁止
+ */
+ AuthResultForbidden,
+ }
+
+ private final Code code;
+
+ public AuthResult(Code code) {
+ this.code = code;
+ }
+
+ public Code getCode() {
+ return code;
+ }
+
+ @Override
+ public String toString() {
+ return "AuthResult{" +
+ "code=" + code +
+ '}';
+ }
+}
diff --git a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/Authenticator.java b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/Authenticator.java
new file mode 100644
index 000000000..6413dd46a
--- /dev/null
+++ b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/auth/Authenticator.java
@@ -0,0 +1,36 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.api.plugin.auth;
+
+import com.tencent.polaris.api.plugin.Plugin;
+
+/**
+ * 【扩展点接口】服务鉴权
+ *
+ * @author Haotian Zhang
+ */
+public interface Authenticator extends Plugin {
+
+ /**
+ * 鉴权
+ *
+ * @param authInfo
+ * @return AuthResult
+ */
+ AuthResult authenticate(AuthInfo authInfo);
+}
diff --git a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/common/PluginTypes.java b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/common/PluginTypes.java
index 514548327..dfd83fa1e 100644
--- a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/common/PluginTypes.java
+++ b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/common/PluginTypes.java
@@ -18,6 +18,7 @@
package com.tencent.polaris.api.plugin.common;
import com.tencent.polaris.api.plugin.PluginType;
+import com.tencent.polaris.api.plugin.auth.Authenticator;
import com.tencent.polaris.api.plugin.cache.FlowCache;
import com.tencent.polaris.api.plugin.circuitbreaker.CircuitBreaker;
import com.tencent.polaris.api.plugin.circuitbreaker.InstanceCircuitBreaker;
@@ -135,7 +136,12 @@ public enum PluginTypes {
/**
* 无损上下线策略扩展点
*/
- LOSSLESS_POLICY(new PluginType(LosslessPolicy.class, 2));
+ LOSSLESS_POLICY(new PluginType(LosslessPolicy.class, 2)),
+
+ /**
+ * 服务鉴权扩展点
+ */
+ AUTHENTICATOR(new PluginType(Authenticator.class, 2));
private PluginType baseType;
diff --git a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java
index b6ffe8cfa..3deae0d8b 100644
--- a/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java
+++ b/polaris-plugins/polaris-plugin-api/src/main/java/com/tencent/polaris/api/plugin/compose/Extensions.java
@@ -31,6 +31,7 @@
import com.tencent.polaris.api.plugin.HttpServerAware;
import com.tencent.polaris.api.plugin.Plugin;
import com.tencent.polaris.api.plugin.Supplier;
+import com.tencent.polaris.api.plugin.auth.Authenticator;
import com.tencent.polaris.api.plugin.cache.FlowCache;
import com.tencent.polaris.api.plugin.circuitbreaker.CircuitBreaker;
import com.tencent.polaris.api.plugin.circuitbreaker.InstanceCircuitBreaker;
@@ -117,6 +118,9 @@ public class Extensions extends Destroyable {
private List weightAdjusters;
+ // 服务鉴权插件列表
+ private List authenticatorList;
+
public static List loadServiceRouters(List routerChain, Supplier plugins, boolean force) {
List routers = new ArrayList<>();
if (CollectionUtils.isNotEmpty(routerChain)) {
@@ -213,6 +217,9 @@ public void init(Configuration config, Supplier plugins, ValueContext valueConte
// 加载预热插件
loadWeightAdjusters(plugins);
+ // 加载服务鉴权插件
+ loadAuthenticatorList(config, plugins);
+
initLocation(config, valueContext);
}
@@ -353,6 +360,24 @@ private void loadWeightAdjusters(Supplier plugins) throws PolarisException {
}
}
+ private void loadAuthenticatorList(Configuration config, Supplier plugins) throws PolarisException {
+ if (!config.getProvider().getAuth().isEnable()) {
+ return;
+ }
+ List authenticators = config.getProvider().getAuth().getChain();
+ authenticatorList = new ArrayList<>();
+ if (CollectionUtils.isNotEmpty(authenticators)) {
+ for (String pluginName : authenticators) {
+ Plugin authenticator = plugins.getPlugin(PluginTypes.AUTHENTICATOR.getBaseType(), pluginName);
+ if (!(authenticator instanceof Authenticator)) {
+ LOG.warn("authenticator {} not found", pluginName);
+ continue;
+ }
+ authenticatorList.add((Authenticator) authenticator);
+ }
+ }
+ }
+
public void initHttpServer(Configuration configuration, Supplier plugins) {
// 遍历插件并获取监听器
Map allHandlers = buildHttpHandlers(plugins);
@@ -513,6 +538,10 @@ public List getWeightAdjusters() {
return weightAdjusters;
}
+ public List getAuthenticatorList() {
+ return authenticatorList;
+ }
+
@Override
protected void doDestroy() {
if (MapUtils.isNotEmpty(httpServers)) {
diff --git a/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/pom.xml b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/pom.xml
new file mode 100644
index 000000000..189ee1606
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/pom.xml
@@ -0,0 +1,30 @@
+
+
+
+ com.tencent.polaris
+ polaris-plugins-auth
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ auth-block-allow-list
+ Polaris Plugins Auth Block Allow List
+ Polaris Plugins Auth Block Allow List JAR
+
+
+
+ com.tencent.polaris
+ polaris-client
+ ${project.version}
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j.version}
+ provided
+
+
+
\ No newline at end of file
diff --git a/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticator.java b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticator.java
new file mode 100644
index 000000000..05fea3f2f
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticator.java
@@ -0,0 +1,232 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.plugins.auth.blockallowlist;
+
+import com.tencent.polaris.api.config.plugin.DefaultPlugins;
+import com.tencent.polaris.api.exception.PolarisException;
+import com.tencent.polaris.api.plugin.PluginType;
+import com.tencent.polaris.api.plugin.auth.AuthInfo;
+import com.tencent.polaris.api.plugin.auth.AuthResult;
+import com.tencent.polaris.api.plugin.auth.Authenticator;
+import com.tencent.polaris.api.plugin.cache.FlowCache;
+import com.tencent.polaris.api.plugin.common.InitContext;
+import com.tencent.polaris.api.plugin.common.PluginTypes;
+import com.tencent.polaris.api.plugin.compose.Extensions;
+import com.tencent.polaris.api.pojo.*;
+import com.tencent.polaris.api.rpc.RequestBaseEntity;
+import com.tencent.polaris.api.utils.ApiTrieUtil;
+import com.tencent.polaris.api.utils.CollectionUtils;
+import com.tencent.polaris.api.utils.RuleUtils;
+import com.tencent.polaris.api.utils.StringUtils;
+import com.tencent.polaris.client.flow.BaseFlow;
+import com.tencent.polaris.client.flow.DefaultFlowControlParam;
+import com.tencent.polaris.client.flow.ResourcesResponse;
+import com.tencent.polaris.logging.LoggerFactory;
+import com.tencent.polaris.metadata.core.MessageMetadataContainer;
+import com.tencent.polaris.metadata.core.MetadataType;
+import com.tencent.polaris.metadata.core.manager.MetadataContext;
+import com.tencent.polaris.specification.api.v1.security.BlockAllowListProto;
+import com.tencent.polaris.specification.api.v1.service.manage.ResponseProto;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+
+import static com.tencent.polaris.api.plugin.cache.CacheConstants.API_ID;
+import static com.tencent.polaris.api.utils.RuleUtils.matchMethod;
+import static com.tencent.polaris.metadata.core.constant.MetadataConstants.LOCAL_NAMESPACE;
+import static com.tencent.polaris.metadata.core.constant.MetadataConstants.LOCAL_SERVICE;
+
+/**
+ * 黑白名单服务鉴权插件.
+ *
+ * @author Haotian Zhang
+ */
+public class BlockAllowListAuthenticator implements Authenticator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BlockAllowListAuthenticator.class);
+
+ protected Extensions extensions;
+
+ private Function regexFunction;
+
+ private Function> trieNodeFunction;
+
+ @Override
+ public AuthResult authenticate(AuthInfo authInfo) {
+ List blockAllowListRuleList = getBlockAllowListRule(authInfo);
+ if (CollectionUtils.isNotEmpty(blockAllowListRuleList)) {
+ if (!checkAllow(authInfo, blockAllowListRuleList)) {
+ return new AuthResult(AuthResult.Code.AuthResultForbidden);
+ }
+ }
+ return new AuthResult(AuthResult.Code.AuthResultOk);
+ }
+
+ /**
+ * 获取黑白名单鉴权规则
+ *
+ * @param authInfo 鉴权信息
+ * @return 目标服务黑白名单鉴权规则
+ */
+ private List getBlockAllowListRule(AuthInfo authInfo) {
+ // 获取服务鉴权规则
+ DefaultFlowControlParam engineFlowControlParam = new DefaultFlowControlParam();
+ BaseFlow.buildFlowControlParam(new RequestBaseEntity(), extensions.getConfiguration(), engineFlowControlParam);
+ Set serviceEventKeys = new HashSet<>();
+ ServiceEventKey dstSvcEventKey = new ServiceEventKey(new ServiceKey(authInfo.getNamespace(), authInfo.getService()),
+ ServiceEventKey.EventType.BLOCK_ALLOW_RULE);
+ serviceEventKeys.add(dstSvcEventKey);
+ DefaultServiceEventKeysProvider svcKeysProvider = new DefaultServiceEventKeysProvider();
+ svcKeysProvider.setSvcEventKeys(serviceEventKeys);
+ ResourcesResponse resourcesResponse = BaseFlow
+ .syncGetResources(extensions, false, svcKeysProvider, engineFlowControlParam);
+ ServiceRule serviceRule = resourcesResponse.getServiceRule(dstSvcEventKey);
+
+ List blockAllowListRuleList = new ArrayList<>();
+ if (serviceRule != null && serviceRule.getRule() != null) {
+ ResponseProto.DiscoverResponse discoverResponse = (ResponseProto.DiscoverResponse) serviceRule.getRule();
+ blockAllowListRuleList = discoverResponse.getBlockAllowListRuleList();
+ }
+
+ return blockAllowListRuleList;
+ }
+
+ /**
+ * 1、如果全是白名单策略,那么只要有一个匹配,才算通过。
+ * 2、如果全是黑名单策略,那么只要有一个匹配,才算不通过。
+ * 3、如果又有白名单策略,又有黑名单策略,只要有一个白名单策略匹配,才算通过。
+ *
+ * @param authInfo
+ * @param blockAllowListRuleList
+ * @return
+ */
+ protected boolean checkAllow(AuthInfo authInfo, List blockAllowListRuleList) {
+ boolean containsAllowList = false;
+ if (CollectionUtils.isNotEmpty(blockAllowListRuleList)) {
+ for (BlockAllowListProto.BlockAllowListRule balr : blockAllowListRuleList) {
+ if (balr.getEnable()) {
+ for (BlockAllowListProto.BlockAllowConfig config : balr.getBlockAllowConfigList()) {
+ if (config.getBlockAllowPolicy().equals(BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST)) {
+ containsAllowList = true;
+ }
+ boolean methodMatched = matchMethod(authInfo.getPath(), authInfo.getProtocol(),
+ authInfo.getMethod(), config.getApi(), regexFunction, trieNodeFunction);
+ if (methodMatched) {
+ boolean matched = true;
+ MetadataContext metadataContext = authInfo.getMetadataContext();
+ List argumentsList = config.getArgumentsList();
+ if (CollectionUtils.isNotEmpty(argumentsList)) {
+ for (BlockAllowListProto.BlockAllowConfig.MatchArgument matchArgument : argumentsList) {
+ String labelValue = null;
+ if (metadataContext != null) {
+ labelValue = getLabelValue(matchArgument, metadataContext);
+ }
+ matched = RuleUtils.matchStringValue(matchArgument.getValue(), labelValue, regexFunction);
+ if (!matched) {
+ LOG.debug("match fail because label value [{}] is null or not match [{}]", labelValue, matchArgument.getValue());
+ break;
+ }
+ }
+ }
+ if (matched) {
+ return config.getBlockAllowPolicy().equals(BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (containsAllowList) {
+ LOG.debug("check allow fail because no matched allow list.");
+ }
+ return !containsAllowList;
+ }
+
+ private static String getLabelValue(BlockAllowListProto.BlockAllowConfig.MatchArgument matchArgument,
+ MetadataContext metadataContext) {
+ MessageMetadataContainer messageMetadataContainer = metadataContext.getMetadataContainer(MetadataType.MESSAGE, true);
+ if (messageMetadataContainer == null) {
+ return null;
+ }
+ switch (matchArgument.getType()) {
+ case HEADER:
+ return messageMetadataContainer.getHeader(matchArgument.getKey());
+ case QUERY:
+ return messageMetadataContainer.getQuery(matchArgument.getKey());
+ case CALLER_SERVICE: {
+ String namespace = metadataContext.getMetadataContainer(MetadataType.APPLICATION, true).getRawMetadataStringValue(LOCAL_NAMESPACE);
+ if (StringUtils.equals(matchArgument.getKey(), namespace) || StringUtils.equals("*", matchArgument.getKey())) {
+ return metadataContext.getMetadataContainer(MetadataType.APPLICATION, true).getRawMetadataStringValue(LOCAL_SERVICE);
+ } else {
+ return null;
+ }
+ }
+ case CALLER_IP:
+ return messageMetadataContainer.getCallerIP();
+ case CALLER_METADATA:
+ return metadataContext.getMetadataContainer(MetadataType.APPLICATION, true).getRawMetadataStringValue(matchArgument.getKey());
+ case CUSTOM:
+ default:
+ return metadataContext.getMetadataContainer(MetadataType.CUSTOM, false).getRawMetadataStringValue(matchArgument.getKey());
+ }
+ }
+
+ @Override
+ public String getName() {
+ return DefaultPlugins.BLOCK_ALLOW_LIST_AUTHENTICATOR_TYPE;
+ }
+
+ @Override
+ public PluginType getType() {
+ return PluginTypes.AUTHENTICATOR.getBaseType();
+ }
+
+ @Override
+ public void init(InitContext ctx) throws PolarisException {
+
+ }
+
+ @Override
+ public void postContextInit(Extensions ctx) throws PolarisException {
+ this.extensions = ctx;
+ this.regexFunction = regex -> {
+ if (null == extensions) {
+ return Pattern.compile(regex);
+ }
+ FlowCache flowCache = extensions.getFlowCache();
+ return flowCache.loadOrStoreCompiledRegex(regex);
+ };
+ this.trieNodeFunction = key -> {
+ if (null == extensions) {
+ return null;
+ }
+ FlowCache flowCache = extensions.getFlowCache();
+ return flowCache.loadPluginCacheObject(API_ID, key, path -> ApiTrieUtil.buildSimpleTrieNode((String) path));
+ };
+ }
+
+ @Override
+ public void destroy() {
+
+ }
+}
diff --git a/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.auth.Authenticator b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.auth.Authenticator
new file mode 100644
index 000000000..5492206d0
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.auth.Authenticator
@@ -0,0 +1 @@
+com.tencent.polaris.plugins.auth.blockallowlist.BlockAllowListAuthenticator
diff --git a/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/test/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticatorTest.java b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/test/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticatorTest.java
new file mode 100644
index 000000000..93fd46ef0
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-auth/auth-block-allow-list/src/test/java/com/tencent/polaris/plugins/auth/blockallowlist/BlockAllowListAuthenticatorTest.java
@@ -0,0 +1,213 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.plugins.auth.blockallowlist;
+
+import com.google.protobuf.StringValue;
+import com.tencent.polaris.api.plugin.auth.AuthInfo;
+import com.tencent.polaris.metadata.core.manager.MetadataContext;
+import com.tencent.polaris.specification.api.v1.model.ModelProto;
+import com.tencent.polaris.specification.api.v1.security.BlockAllowListProto;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Test for {@link BlockAllowListAuthenticator}.
+ *
+ * @author Haotian Zhang
+ */
+public class BlockAllowListAuthenticatorTest {
+
+ private final String testNamespace = "testNamespace";
+ private final String testService = "testService";
+ private final String testPath = "/path";
+ private final String testProtocol = "HTTP";
+ private final String testMethod = "GET";
+ private final MetadataContext testMetadataContext = new MetadataContext();
+
+ /**
+ * 测试空的黑白名单规则列表,预期返回true
+ */
+ @Test
+ public void testCheckAllow_WithEmptyBlockAllowListRuleList_ShouldReturnTrue() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, testPath, testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Collections.emptyList();
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isTrue();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,且禁用了允许列表,预期返回true
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndDisableAllowList_ShouldReturnTrue() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, testPath, testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Collections.singletonList(
+ createBlockAllowListRule(false, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isTrue();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,且只有允许列表,预期返回true
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndOnlyAllowList_ShouldReturnTrue() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, testPath, testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Collections.singletonList(
+ createBlockAllowListRule(true, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isTrue();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,且只有阻止列表,预期返回false
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndOnlyBlockList_ShouldReturnFalse() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, testPath, testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Collections.singletonList(
+ createBlockAllowListRule(true, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.BLOCK_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isFalse();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,且只有允许列表,但请求路径不匹配,预期返回false
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndOnlyAllowListButNotMatch_ShouldReturnFalse() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, "/no-test", testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Collections.singletonList(
+ createBlockAllowListRule(true, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isFalse();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,且只有阻止列表,但请求路径不匹配,预期返回true
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndOnlyBlockListButNotMatch_ShouldReturnTrue() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, "/no-test", testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Collections.singletonList(
+ createBlockAllowListRule(true, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.BLOCK_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isTrue();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,允许列表匹配且阻止列表不匹配,预期返回true
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndAllowListMatchAndBlockListNotMatch_ShouldReturnTrue() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, testPath, testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Arrays.asList(
+ createBlockAllowListRule(true, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST),
+ createBlockAllowListRule(true, "/no-test", BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.BLOCK_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isTrue();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,允许列表不匹配且阻止列表匹配,预期返回false
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndAllowListNotMatchAndBlockListMatch_ShouldReturnFalse() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, "/no-test", testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Arrays.asList(
+ createBlockAllowListRule(true, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST),
+ createBlockAllowListRule(true, "/no-test", BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.BLOCK_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isFalse();
+ }
+
+ /**
+ * 测试非空的黑白名单规则列表,允许列表和阻止列表都不匹配,预期返回false
+ */
+ @Test
+ public void testCheckAllow_WithNonEmptyBlockAllowListRuleListAndAllowListNotMatchAndBlockListNotMatch_ShouldReturnFalse() {
+ BlockAllowListAuthenticator authenticator = new BlockAllowListAuthenticator();
+ AuthInfo authInfo = new AuthInfo(testNamespace, testService, "/no-no-test", testProtocol, testMethod, testMetadataContext);
+ List blockAllowListRuleList = Arrays.asList(
+ createBlockAllowListRule(true, testPath, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST),
+ createBlockAllowListRule(true, "/no-test", BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.BLOCK_LIST)
+ );
+
+ boolean result = authenticator.checkAllow(authInfo, blockAllowListRuleList);
+
+ assertThat(result).isFalse();
+ }
+
+ /**
+ * 创建一个BlockAllowListProto.BlockAllowListRule实例
+ *
+ * @param enable 是否启用规则
+ * @param path 请求路径
+ * @param policy 黑白名单策略
+ * @return BlockAllowListProto.BlockAllowListRule实例
+ */
+ private BlockAllowListProto.BlockAllowListRule createBlockAllowListRule(boolean enable, String path, BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy policy) {
+ return BlockAllowListProto.BlockAllowListRule.newBuilder()
+ .setEnable(enable)
+ .addBlockAllowConfig(BlockAllowListProto.BlockAllowConfig.newBuilder()
+ .setApi(ModelProto.API.newBuilder()
+ .setPath(ModelProto.MatchString.newBuilder().setValue(StringValue.of(path)).build())
+ .setProtocol(testProtocol)
+ .setMethod(testMethod)
+ .build())
+ .setBlockAllowPolicy(policy)
+ .build())
+ .build();
+ }
+}
diff --git a/polaris-plugins/polaris-plugins-auth/pom.xml b/polaris-plugins/polaris-plugins-auth/pom.xml
new file mode 100644
index 000000000..e3ffa3043
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-auth/pom.xml
@@ -0,0 +1,29 @@
+
+
+
+ polaris-plugins
+ com.tencent.polaris
+ ${revision}
+ ../pom.xml
+
+ 4.0.0
+
+ polaris-plugins-auth
+ pom
+ Polaris Plugins Auth
+ Polaris Plugins Auth POM
+
+
+ auth-block-allow-list
+
+
+
+
+ com.tencent.polaris
+ polaris-plugin-api
+ ${project.version}
+
+
+
\ No newline at end of file
diff --git a/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/DestroyableServerConnector.java b/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/DestroyableServerConnector.java
index 17efe7ea5..4865058ca 100644
--- a/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/DestroyableServerConnector.java
+++ b/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/DestroyableServerConnector.java
@@ -23,9 +23,10 @@
import com.tencent.polaris.api.pojo.Services;
import com.tencent.polaris.logging.LoggerFactory;
import com.tencent.polaris.plugins.connector.common.constant.ServiceUpdateTaskConstant.Status;
+import org.slf4j.Logger;
+
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import org.slf4j.Logger;
/**
* Destroyable server connector.
@@ -52,7 +53,7 @@ public abstract class DestroyableServerConnector extends Destroyable implements
*/
public void retryServiceUpdateTask(ServiceUpdateTask updateTask) {
LOG.info("[ServerConnector]retry schedule task for {}, retry delay {}", updateTask, TASK_RETRY_INTERVAL_MS);
- updateTask.setStatus(Status.RUNNING, Status.READY);
+ updateTask.setStatus(Status.RUNNING, Status.READY, true);
if (isDestroyed()) {
return;
}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/ServiceUpdateTask.java b/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/ServiceUpdateTask.java
index 0d6dd63aa..5d0d5f5c6 100644
--- a/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/ServiceUpdateTask.java
+++ b/polaris-plugins/polaris-plugins-connector/connector-common/src/main/java/com/tencent/polaris/plugins/connector/common/ServiceUpdateTask.java
@@ -83,10 +83,14 @@ public boolean setType(Type last, Type current) {
return taskType.compareAndSet(last, current);
}
- public boolean setStatus(Status last, Status current) {
+ public boolean setStatus(Status last, Status current, boolean isSpread) {
return taskStatus.compareAndSet(last, current);
}
+ public boolean setStatus(Status last, Status current) {
+ return setStatus(last, current, false);
+ }
+
public void setLastUpdateTime(long currentTime) {
lastUpdateTime.set(currentTime);
}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-composite/src/main/java/com/tencent/polaris/plugins/connector/composite/CompositeServiceUpdateTask.java b/polaris-plugins/polaris-plugins-connector/connector-composite/src/main/java/com/tencent/polaris/plugins/connector/composite/CompositeServiceUpdateTask.java
index 7c90874a8..c67aed03b 100644
--- a/polaris-plugins/polaris-plugins-connector/connector-composite/src/main/java/com/tencent/polaris/plugins/connector/composite/CompositeServiceUpdateTask.java
+++ b/polaris-plugins/polaris-plugins-connector/connector-composite/src/main/java/com/tencent/polaris/plugins/connector/composite/CompositeServiceUpdateTask.java
@@ -113,7 +113,6 @@ public void execute() {
entry.getValue().execute(this);
}
}
- // TODO 全部规则实现完后改成StringUtils.equals(mainConnectorType, SERVER_CONNECTOR_CONSUL)
if (ifMainConnectorTypeSet && isServiceUpdateTaskExecuted
&& (StringUtils.equals(mainConnectorType, SERVER_CONNECTOR_GRPC)
|| (serviceEventKey.getEventType().equals(EventType.INSTANCE)
@@ -123,7 +122,8 @@ public void execute() {
|| serviceEventKey.getEventType().equals(EventType.LOSSLESS)
|| serviceEventKey.getEventType().equals(EventType.CIRCUIT_BREAKING)
|| serviceEventKey.getEventType().equals(EventType.RATE_LIMITING)
- || serviceEventKey.getEventType().equals(EventType.LANE_RULE)))) {
+ || serviceEventKey.getEventType().equals(EventType.LANE_RULE)
+ || serviceEventKey.getEventType().equals(EventType.BLOCK_ALLOW_RULE)))) {
return;
}
boolean svcDeleted = this.notifyServerEvent(
@@ -407,6 +407,15 @@ public boolean notifyServerEvent(ServerEvent serverEvent) {
return svcDeleted;
}
+ public boolean setStatus(Status last, Status current, boolean isSpread) {
+ if (isSpread) {
+ for (Map.Entry entry : subServiceUpdateTaskMap.entrySet()) {
+ entry.getValue().setStatus(last, current);
+ }
+ }
+ return taskStatus.compareAndSet(last, current);
+ }
+
private boolean canExecute(String connectorType, ServiceUpdateTask serviceUpdateTask) {
boolean canConnectorExecute = StringUtils.equalsIgnoreCase(mainConnectorType, connectorType)
|| serviceEventKey.getEventType().equals(EventType.INSTANCE)
diff --git a/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/ConsulAPIConnector.java b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/ConsulAPIConnector.java
index 6f713731d..828e3229e 100644
--- a/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/ConsulAPIConnector.java
+++ b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/ConsulAPIConnector.java
@@ -49,6 +49,7 @@
import com.tencent.polaris.plugins.connector.consul.service.ConsulService;
import com.tencent.polaris.plugins.connector.consul.service.InstanceService;
import com.tencent.polaris.plugins.connector.consul.service.ServiceService;
+import com.tencent.polaris.plugins.connector.consul.service.authority.AuthorityService;
import com.tencent.polaris.plugins.connector.consul.service.circuitbreaker.CircuitBreakingService;
import com.tencent.polaris.plugins.connector.consul.service.lossless.LosslessService;
import com.tencent.polaris.plugins.connector.consul.service.lane.LaneService;
@@ -236,6 +237,7 @@ private void initActually(InitContext ctx, ServerConnectorConfig connectorConfig
consulServiceMap.put(ServiceEventKey.EventType.CIRCUIT_BREAKING, new CircuitBreakingService(consulClient, consulRawClient, consulContext, "consul-circuit-breaking", mapper));
consulServiceMap.put(ServiceEventKey.EventType.RATE_LIMITING, new RateLimitingService(consulClient, consulRawClient, consulContext, "consul-rate-limiting", mapper));
consulServiceMap.put(ServiceEventKey.EventType.LANE_RULE, new LaneService(consulClient, consulRawClient, consulContext, "consul-lane", mapper));
+ consulServiceMap.put(ServiceEventKey.EventType.BLOCK_ALLOW_RULE, new AuthorityService(consulClient, consulRawClient, consulContext, "consul-auth", mapper));
initialized = true;
}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/AuthorityService.java b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/AuthorityService.java
new file mode 100644
index 000000000..2adad08d1
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/AuthorityService.java
@@ -0,0 +1,321 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.plugins.connector.consul.service.authority;
+
+import com.ecwid.consul.v1.ConsulClient;
+import com.ecwid.consul.v1.ConsulRawClient;
+import com.ecwid.consul.v1.QueryParams;
+import com.ecwid.consul.v1.Response;
+import com.ecwid.consul.v1.kv.model.GetValue;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.protobuf.StringValue;
+import com.google.protobuf.UInt32Value;
+import com.tencent.polaris.api.exception.ErrorCode;
+import com.tencent.polaris.api.exception.PolarisException;
+import com.tencent.polaris.api.exception.ServerCodes;
+import com.tencent.polaris.api.exception.ServerErrorResponseException;
+import com.tencent.polaris.api.plugin.server.ServerEvent;
+import com.tencent.polaris.api.utils.CollectionUtils;
+import com.tencent.polaris.api.utils.StringUtils;
+import com.tencent.polaris.logging.LoggerFactory;
+import com.tencent.polaris.metadata.core.MessageMetadataContainer;
+import com.tencent.polaris.metadata.core.constant.TsfMetadataConstants;
+import com.tencent.polaris.plugins.connector.common.ServiceUpdateTask;
+import com.tencent.polaris.plugins.connector.consul.ConsulContext;
+import com.tencent.polaris.plugins.connector.consul.service.ConsulService;
+import com.tencent.polaris.plugins.connector.consul.service.authority.entity.AuthRule;
+import com.tencent.polaris.plugins.connector.consul.service.authority.entity.AuthRuleGroup;
+import com.tencent.polaris.plugins.connector.consul.service.authority.entity.AuthTag;
+import com.tencent.polaris.plugins.connector.consul.service.authority.entity.TsfAuthConstant;
+import com.tencent.polaris.plugins.connector.consul.service.common.TagConstant;
+import com.tencent.polaris.specification.api.v1.model.ModelProto;
+import com.tencent.polaris.specification.api.v1.security.BlockAllowListProto;
+import com.tencent.polaris.specification.api.v1.service.manage.ResponseProto;
+import com.tencent.polaris.specification.api.v1.service.manage.ServiceProto;
+import org.slf4j.Logger;
+import org.yaml.snakeyaml.Yaml;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static com.tencent.polaris.api.config.plugin.DefaultPlugins.SERVER_CONNECTOR_CONSUL;
+import static com.tencent.polaris.plugins.connector.consul.service.common.TagConditionUtil.parseMatchStringType;
+
+/**
+ * @author Haotian Zhang
+ */
+public class AuthorityService extends ConsulService {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AuthorityService.class);
+
+ private final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+
+ private final Map authorityConsulIndexMap = new ConcurrentHashMap<>();
+
+ public AuthorityService(ConsulClient consulClient, ConsulRawClient consulRawClient, ConsulContext consulContext,
+ String threadName, ObjectMapper mapper) {
+ super(consulClient, consulRawClient, consulContext, threadName, mapper);
+ }
+
+ @Override
+ public void sendRequest(ServiceUpdateTask serviceUpdateTask) {
+ String authorityRuleKey = String.format("authority/%s/%s/data", consulContext.getNamespace(), consulContext.getServiceName());
+ AuthorityKey authorityKey = new AuthorityKey();
+ authorityKey.setNamespace(consulContext.getNamespace());
+ authorityKey.setService(consulContext.getServiceName());
+ Long currentIndex = getAuthorityConsulIndex(authorityKey);
+ QueryParams queryParams = new QueryParams(consulContext.getWaitTime(), currentIndex);
+ int code = ServerCodes.DATA_NO_CHANGE;
+ try {
+ LOG.debug("Begin get authority rules of {} sync", authorityRuleKey);
+ Response response = consulClient.getKVValue(authorityRuleKey, consulContext.getAclToken(), queryParams);
+ if (response != null) {
+ if (LOG.isDebugEnabled()) {
+ String responseStr = "Response{" +
+ "value='" + response.getValue() + '\'' +
+ ", consulIndex=" + response.getConsulIndex() + '\'' +
+ ", consulKnownLeader=" + response.isConsulKnownLeader() + '\'' +
+ ", consulLastContact=" + response.getConsulLastContact() +
+ '}';
+ LOG.debug("tsf authority rule, consul kv namespace, response: {}", responseStr);
+ }
+
+ Long newIndex = response.getConsulIndex();
+ // create service.
+ ServiceProto.Service.Builder newServiceBuilder = ServiceProto.Service.newBuilder();
+ newServiceBuilder.setNamespace(StringValue.of(consulContext.getNamespace()));
+ newServiceBuilder.setName(StringValue.of(consulContext.getServiceName()));
+ newServiceBuilder.setRevision(StringValue.of(String.valueOf(newIndex)));
+ // create discover response.
+ ResponseProto.DiscoverResponse.Builder newDiscoverResponseBuilder = ResponseProto.DiscoverResponse.newBuilder();
+ newDiscoverResponseBuilder.setService(newServiceBuilder);
+ // 重写index
+ List ruleList = new ArrayList<>();
+ if (Objects.nonNull(newIndex)) {
+ if (!Objects.equals(currentIndex, newIndex)) {
+ code = ServerCodes.EXECUTE_SUCCESS;
+ GetValue getValue = response.getValue();
+ if (Objects.nonNull(getValue)) {
+ String decodedValue = getValue.getDecodedValue();
+ LOG.info("[TSF Auth] New consul config: {}", decodedValue);
+ if (!StringUtils.isEmpty(decodedValue)) {
+ ruleList = parseResponse(decodedValue, consulContext.getNamespace(), consulContext.getServiceName(), newIndex);
+ }
+ } else {
+ LOG.info("empty authority rule: {}", response);
+ }
+ } else {
+ LOG.debug("[TSF Auth] Consul data is not changed");
+ }
+ } else {
+ LOG.warn("[TSF Auth] Consul data is abnormal. {}", response);
+ }
+ if (CollectionUtils.isNotEmpty(ruleList)) {
+ newDiscoverResponseBuilder.addAllBlockAllowListRule(ruleList);
+ }
+ newDiscoverResponseBuilder.setCode(UInt32Value.of(code));
+ ServerEvent serverEvent = new ServerEvent(serviceUpdateTask.getServiceEventKey(), newDiscoverResponseBuilder.build(), null, SERVER_CONNECTOR_CONSUL);
+ boolean svcDeleted = serviceUpdateTask.notifyServerEvent(serverEvent);
+ if (newIndex != null) {
+ setAuthorityConsulIndex(authorityKey, currentIndex, newIndex);
+ }
+ if (!svcDeleted) {
+ serviceUpdateTask.addUpdateTaskSet();
+ }
+ }
+ } catch (Throwable e) {
+ LOG.error("[TSF Auth] tsf authority rule load error. Will sleep for {} ms. Key path:{}",
+ consulContext.getConsulErrorSleep(), authorityRuleKey, e);
+ try {
+ Thread.sleep(consulContext.getConsulErrorSleep());
+ } catch (Exception e1) {
+ LOG.error("error in sleep, msg: {}", e1.getMessage());
+ }
+ PolarisException error = ServerErrorResponseException.build(ErrorCode.NETWORK_ERROR.getCode(),
+ "Get authority sync failed.");
+ ServerEvent serverEvent = new ServerEvent(serviceUpdateTask.getServiceEventKey(), null, error, SERVER_CONNECTOR_CONSUL);
+ serviceUpdateTask.notifyServerEvent(serverEvent);
+ }
+ }
+
+ private List parseResponse(String decodedValue, String namespace, String service, Long index) {
+ List ruleList = Lists.newArrayList();
+
+ // yaml -> List
+ Yaml yaml = new Yaml();
+ List authRuleGroupList;
+ try {
+ String authJsonString = mapper.writeValueAsString(yaml.load(decodedValue));
+ authRuleGroupList = mapper.readValue(authJsonString, new TypeReference>() {
+ });
+ } catch (Exception ex) {
+ LOG.error("tsf authority rule load error.", ex);
+ throw new PolarisException(ErrorCode.INVALID_RESPONSE, "tsf authority rule load error.", ex);
+ }
+
+ // List -> List
+ if (CollectionUtils.isNotEmpty(authRuleGroupList)) {
+ for (AuthRuleGroup authRuleGroup : authRuleGroupList) {
+ for (AuthRule authRule : authRuleGroup.getRules()) {
+ BlockAllowListProto.BlockAllowListRule.Builder ruleBuilder = BlockAllowListProto.BlockAllowListRule.newBuilder();
+ ruleBuilder.setId(authRule.getRuleId());
+ ruleBuilder.setNamespace(namespace);
+ ruleBuilder.setService(service);
+ ruleBuilder.setEnable(true);
+ ruleBuilder.setName(authRule.getRuleName());
+ BlockAllowListProto.BlockAllowConfig.Builder blockAllowConfigBuilder = BlockAllowListProto.BlockAllowConfig.newBuilder();
+ blockAllowConfigBuilder.setBlockAllowPolicy(parseBlockAllowPolicy(authRuleGroup.getType()));
+ if (CollectionUtils.isNotEmpty(authRule.getTags())) {
+ List list = new ArrayList<>();
+ for (AuthTag authTag : authRule.getTags()) {
+ // build MatchArgument
+ BlockAllowListProto.BlockAllowConfig.MatchArgument.Builder matchArgumentBuilder = BlockAllowListProto.BlockAllowConfig.MatchArgument.newBuilder();
+ if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_SERVICE_NAME)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CALLER_SERVICE);
+ matchArgumentBuilder.setKey("*");
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_NAMESPACE_SERVICE_NAME)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CALLER_SERVICE);
+ matchArgumentBuilder.setKey("*");
+ String[] split = authTag.getTagValue().split("/");
+ if (split.length == 2) {
+ matchArgumentBuilder.setKey(split[0]);
+ authTag.setTagValue(split[1]);
+ }
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_APPLICATION_ID)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CALLER_METADATA);
+ matchArgumentBuilder.setKey(TsfMetadataConstants.TSF_APPLICATION_ID);
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_APPLICATION_VERSION)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CALLER_METADATA);
+ matchArgumentBuilder.setKey(TsfMetadataConstants.TSF_PROG_VERSION);
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_GROUP_ID)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CALLER_METADATA);
+ matchArgumentBuilder.setKey(TsfMetadataConstants.TSF_GROUP_ID);
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.SOURCE_CONNECTION_IP)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CALLER_IP);
+ matchArgumentBuilder.setKey(MessageMetadataContainer.LABEL_KEY_CALLER_IP);
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.DESTINATION_APPLICATION_VERSION)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CUSTOM);
+ matchArgumentBuilder.setKey(TsfMetadataConstants.TSF_PROG_VERSION);
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.DESTINATION_GROUP_ID)) {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CUSTOM);
+ matchArgumentBuilder.setKey(TsfMetadataConstants.TSF_GROUP_ID);
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.DESTINATION_INTERFACE)) {
+ ModelProto.MatchString.Builder matchStringBuilder = ModelProto.MatchString.newBuilder();
+ matchStringBuilder.setType(parseMatchStringType(authTag.getTagOperator()));
+ matchStringBuilder.setValue(StringValue.of(authTag.getTagValue()));
+ ModelProto.API.Builder apiBuilder = ModelProto.API.newBuilder();
+ apiBuilder.setPath(matchStringBuilder);
+ apiBuilder.setProtocol("*");
+ apiBuilder.setMethod("*");
+ blockAllowConfigBuilder.setApi(apiBuilder.build());
+ continue;
+ } else if (StringUtils.equals(authTag.getTagField(), TagConstant.SYSTEM_FIELD.REQUEST_HTTP_METHOD)) {
+ ModelProto.MatchString.Builder matchStringBuilder = ModelProto.MatchString.newBuilder();
+ matchStringBuilder.setType(ModelProto.MatchString.MatchStringType.EXACT);
+ matchStringBuilder.setValue(StringValue.of("*"));
+ ModelProto.API.Builder apiBuilder = ModelProto.API.newBuilder();
+ apiBuilder.setPath(matchStringBuilder);
+ apiBuilder.setProtocol("*");
+ apiBuilder.setMethod(authTag.getTagValue());
+ blockAllowConfigBuilder.setApi(apiBuilder.build());
+ continue;
+ } else {
+ matchArgumentBuilder.setType(BlockAllowListProto.BlockAllowConfig.MatchArgument.Type.CUSTOM);
+ matchArgumentBuilder.setKey(authTag.getTagField());
+ }
+ ModelProto.MatchString.Builder matchStringBuilder = ModelProto.MatchString.newBuilder();
+ matchStringBuilder.setType(parseMatchStringType(authTag.getTagOperator()));
+ matchStringBuilder.setValue(StringValue.of(authTag.getTagValue()));
+ matchArgumentBuilder.setValue(matchStringBuilder);
+ list.add(matchArgumentBuilder.build());
+ }
+ blockAllowConfigBuilder.addAllArguments(list);
+ }
+ ruleBuilder.addBlockAllowConfig(blockAllowConfigBuilder);
+ ruleList.add(ruleBuilder.build());
+ }
+ }
+ }
+ return ruleList;
+ }
+
+ private BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy parseBlockAllowPolicy(String type) {
+ switch (type) {
+ case TsfAuthConstant.TYPE.BLACK_LIST:
+ return BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.BLOCK_LIST;
+ case TsfAuthConstant.TYPE.WHITE_LIST:
+ default:
+ return BlockAllowListProto.BlockAllowConfig.BlockAllowPolicy.ALLOW_LIST;
+ }
+ }
+
+ private Long getAuthorityConsulIndex(AuthorityKey authorityKey) {
+ Long index = authorityConsulIndexMap.get(authorityKey);
+ if (index != null) {
+ return index;
+ }
+ setAuthorityConsulIndex(authorityKey, null, -1L);
+ return -1L;
+ }
+
+ private void setAuthorityConsulIndex(AuthorityKey authorityKey, Long lastIndex, Long newIndex) {
+ LOG.debug("AuthorityKey: {}; lastIndex: {}; newIndex: {}", authorityKey, lastIndex, newIndex);
+ authorityConsulIndexMap.put(authorityKey, newIndex);
+ }
+
+ static class AuthorityKey {
+ private String namespace = "";
+ private String service = "";
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String getService() {
+ return service;
+ }
+
+ public void setService(String service) {
+ this.service = service;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ AuthorityKey that = (AuthorityKey) o;
+ return Objects.equals(getNamespace(), that.getNamespace()) && Objects.equals(getService(), that.getService());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getNamespace(), getService());
+ }
+ }
+}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRule.java b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRule.java
new file mode 100644
index 000000000..951543de9
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRule.java
@@ -0,0 +1,153 @@
+package com.tencent.polaris.plugins.connector.consul.service.authority.entity;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * TSF微服务鉴权规则
+ *
+ * @author hongweizhu
+ */
+public class AuthRule implements Serializable {
+
+ /**
+ * serialVersionUID
+ */
+ private static final long serialVersionUID = -4319194985653367847L;
+ /**
+ * 规则ID
+ */
+ private String ruleId;
+ /**
+ * 规则名称
+ */
+ private String ruleName;
+ /**
+ * 是否启用:0:不启用;1:启用
+ */
+ private String isEnabled;
+ /**
+ * 创建时间
+ */
+ private String createTime;
+ /**
+ * 更新时间
+ */
+ private String updateTime;
+ /**
+ * 微服务于ID
+ */
+ private String microserviceId;
+ /**
+ * 命名空间ID
+ */
+ private String namespaceId;
+ /**
+ * 标签(Tag)列表
+ */
+ private List tags;
+
+ /**
+ * 标签(Tag)计算规则
+ */
+ private String tagProgram;
+
+ public String getRuleId() {
+ return ruleId;
+ }
+
+ public void setRuleId(String ruleId) {
+ this.ruleId = ruleId;
+ }
+
+ public String getRuleName() {
+ return ruleName;
+ }
+
+ public void setRuleName(String ruleName) {
+ this.ruleName = ruleName;
+ }
+
+ public String getIsEnabled() {
+ return isEnabled;
+ }
+
+ public void setIsEnabled(String isEnabled) {
+ this.isEnabled = isEnabled;
+ }
+
+ public String getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
+
+ public String getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(String updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ public String getMicroserviceId() {
+ return microserviceId;
+ }
+
+ public void setMicroserviceId(String microserviceId) {
+ this.microserviceId = microserviceId;
+ }
+
+ public String getNamespaceId() {
+ return namespaceId;
+ }
+
+ public void setNamespaceId(String namespaceId) {
+ this.namespaceId = namespaceId;
+ }
+
+ public List getTags() {
+ return tags;
+ }
+
+ public void setTags(List tags) {
+ this.tags = tags;
+ }
+
+ public String getTagProgram() {
+ return tagProgram;
+ }
+
+ public void setTagProgram(String tagProgram) {
+ this.tagProgram = tagProgram;
+ }
+
+ /**
+ * 推送Consul前清理rule
+ */
+ public void clearAuthRule() {
+ this.microserviceId = null;
+ this.namespaceId = null;
+ this.createTime = null;
+ this.updateTime = null;
+ this.isEnabled = null;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("AuthRule{");
+ sb.append("ruleId='").append(ruleId).append('\'');
+ sb.append(", ruleName='").append(ruleName).append('\'');
+ sb.append(", isEnabled='").append(isEnabled).append('\'');
+ sb.append(", createTime='").append(createTime).append('\'');
+ sb.append(", updateTime='").append(updateTime).append('\'');
+ sb.append(", microserviceId='").append(microserviceId).append('\'');
+ sb.append(", namespaceId='").append(namespaceId).append('\'');
+ sb.append(", tags=").append(tags);
+ sb.append(", tagProgram='").append(tagProgram).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRuleGroup.java b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRuleGroup.java
new file mode 100644
index 000000000..9fa0f0cf0
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthRuleGroup.java
@@ -0,0 +1,59 @@
+package com.tencent.polaris.plugins.connector.consul.service.authority.entity;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class AuthRuleGroup implements Serializable {
+
+ /**
+ * serialVersionUID
+ */
+ private static final long serialVersionUID = 1643183648126834802L;
+ /**
+ * 规则列表
+ */
+ private List rules;
+ /**
+ * 规则计算规则
+ */
+ private String ruleProgram;
+
+ /**
+ * 鉴权类型
+ */
+ private String type;
+
+ public List getRules() {
+ return rules;
+ }
+
+ public void setRules(List rules) {
+ this.rules = rules;
+ }
+
+ public String getRuleProgram() {
+ return ruleProgram;
+ }
+
+ public void setRuleProgram(String ruleProgram) {
+ this.ruleProgram = ruleProgram;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer sb = new StringBuffer("AuthRuleGroup{");
+ sb.append("rules=").append(rules);
+ sb.append(", ruleProgram='").append(ruleProgram).append('\'');
+ sb.append(", type='").append(type).append('\'');
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthTag.java b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthTag.java
new file mode 100644
index 000000000..ba0410919
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/AuthTag.java
@@ -0,0 +1,14 @@
+package com.tencent.polaris.plugins.connector.consul.service.authority.entity;
+
+
+import com.tencent.polaris.plugins.connector.consul.service.common.TagCondition;
+
+/**
+ * TSF微服务于权限标签实体
+ *
+ * @author hongweizhu
+ */
+public class AuthTag extends TagCondition {
+
+ private static final long serialVersionUID = 5850710577425618376L;
+}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/TsfAuthConstant.java b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/TsfAuthConstant.java
new file mode 100644
index 000000000..dff9251d6
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-connector/connector-consul/src/main/java/com/tencent/polaris/plugins/connector/consul/service/authority/entity/TsfAuthConstant.java
@@ -0,0 +1,24 @@
+package com.tencent.polaris.plugins.connector.consul.service.authority.entity;
+
+public class TsfAuthConstant {
+
+ /**
+ * 鉴权类型(微服务级别)
+ *
+ * @author hongweizhu
+ */
+ public static class TYPE {
+ /**
+ * 黑名单模式
+ */
+ public static final String BLACK_LIST = "B";
+ /**
+ * 白名单模式
+ */
+ public static final String WHITE_LIST = "W";
+ /**
+ * 不启用
+ */
+ public static final String DISABLED = "D";
+ }
+}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/GrpcUtil.java b/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/GrpcUtil.java
index 4f793152a..e55320204 100644
--- a/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/GrpcUtil.java
+++ b/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/GrpcUtil.java
@@ -239,6 +239,8 @@ public static DiscoverRequestType buildDiscoverRequestType(
return DiscoverRequestType.NEARBY_ROUTE_RULE;
case LOSSLESS:
return DiscoverRequestType.LOSSLESS;
+ case BLOCK_ALLOW_RULE:
+ return DiscoverRequestType.BLOCK_ALLOW_RULE;
default:
return DiscoverRequestType.UNKNOWN;
}
@@ -265,6 +267,8 @@ public static DiscoverResponseType buildDiscoverResponseType(
return DiscoverResponseType.NEARBY_ROUTE_RULE;
case LOSSLESS:
return DiscoverResponseType.LOSSLESS;
+ case BLOCK_ALLOW_RULE:
+ return DiscoverResponseType.BLOCK_ALLOW_RULE;
default:
return DiscoverResponseType.UNKNOWN;
}
@@ -290,6 +294,8 @@ public static EventType buildEventType(DiscoverResponseType responseType) {
return EventType.NEARBY_ROUTE_RULE;
case LOSSLESS:
return EventType.LOSSLESS;
+ case BLOCK_ALLOW_RULE:
+ return EventType.BLOCK_ALLOW_RULE;
default:
return EventType.UNKNOWN;
}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/codec/BlockAllowListRuleCacheHandler.java b/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/codec/BlockAllowListRuleCacheHandler.java
new file mode 100644
index 000000000..26c3e6ff9
--- /dev/null
+++ b/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/java/com/tencent/polaris/plugins/connector/grpc/codec/BlockAllowListRuleCacheHandler.java
@@ -0,0 +1,92 @@
+/*
+ * Tencent is pleased to support the open source community by making Polaris available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * Licensed under the BSD 3-Clause License (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://opensource.org/licenses/BSD-3-Clause
+ *
+ * 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 com.tencent.polaris.plugins.connector.grpc.codec;
+
+import com.tencent.polaris.api.plugin.cache.FlowCache;
+import com.tencent.polaris.api.plugin.registry.AbstractCacheHandler;
+import com.tencent.polaris.api.pojo.RegistryCacheValue;
+import com.tencent.polaris.api.pojo.ServiceEventKey;
+import com.tencent.polaris.api.utils.CompareUtils;
+import com.tencent.polaris.client.pojo.ServiceRuleByProto;
+import com.tencent.polaris.logging.LoggerFactory;
+import com.tencent.polaris.specification.api.v1.security.BlockAllowListProto;
+import com.tencent.polaris.specification.api.v1.service.manage.ResponseProto;
+import com.tencent.polaris.specification.api.v1.service.manage.ServiceProto;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BlockAllowListRuleCacheHandler extends AbstractCacheHandler {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BlockAllowListRuleCacheHandler.class);
+
+ @Override
+ protected String getRevision(ResponseProto.DiscoverResponse discoverResponse) {
+ ServiceProto.Service service = discoverResponse.getService();
+ return service.getRevision().getValue();
+ }
+
+ @Override
+ public ServiceEventKey.EventType getTargetEventType() {
+ return ServiceEventKey.EventType.BLOCK_ALLOW_RULE;
+ }
+
+ @Override
+ public RegistryCacheValue messageToCacheValue(RegistryCacheValue oldValue, Object newValue, boolean isCacheLoaded, FlowCache flowCache) {
+ ResponseProto.DiscoverResponse discoverResponse = (ResponseProto.DiscoverResponse) newValue;
+ String revision = discoverResponse.getService().getRevision().getValue();
+
+ // 排序规则
+ ResponseProto.DiscoverResponse.Builder newDiscoverResponseBuilder = ResponseProto.DiscoverResponse.newBuilder()
+ .mergeFrom(discoverResponse);
+ List unmodifiableList = discoverResponse.getBlockAllowListRuleList();
+ List blockAllowListRuleList = sortNearbyRouteRules(unmodifiableList);
+ newDiscoverResponseBuilder.clearBlockAllowListRule();
+ newDiscoverResponseBuilder.addAllBlockAllowListRule(blockAllowListRuleList);
+
+ return new ServiceRuleByProto(newDiscoverResponseBuilder.build(), revision, isCacheLoaded, getTargetEventType());
+ }
+
+ private List sortNearbyRouteRules(List rules) {
+ List sorted = new ArrayList<>(rules);
+ sorted.sort((o1, o2) -> {
+ // 比较优先级,数字越小,规则优先级越大
+ int priorityResult = o1.getPriority() - o2.getPriority();
+ if (priorityResult != 0) {
+ return priorityResult;
+ }
+
+ // 比较目标服务
+ String destNamespace1 = o1.getNamespace();
+ String destService1 = o1.getService();
+ String destNamespace2 = o2.getNamespace();
+ String destService2 = o2.getService();
+ int serviceKeyResult = CompareUtils.compareService(destNamespace1, destService1, destNamespace2, destService2);
+ if (serviceKeyResult != 0) {
+ return serviceKeyResult;
+ }
+
+ // 比较规则ID
+ String ruleId1 = o1.getId();
+ String ruleId2 = o1.getId();
+ return CompareUtils.compareSingleValue(ruleId1, ruleId2);
+ });
+ return sorted;
+ }
+}
diff --git a/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.registry.CacheHandler b/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.registry.CacheHandler
index c4bef124d..a394ebc0d 100644
--- a/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.registry.CacheHandler
+++ b/polaris-plugins/polaris-plugins-connector/connector-polaris-grpc/src/main/resources/META-INF/services/com.tencent.polaris.api.plugin.registry.CacheHandler
@@ -5,4 +5,5 @@ com.tencent.polaris.plugins.connector.grpc.codec.ServicesCacheHandler
com.tencent.polaris.plugins.connector.grpc.codec.FaultDetectCacheHandler
com.tencent.polaris.plugins.connector.grpc.codec.LaneRuleCacheHandler
com.tencent.polaris.plugins.connector.grpc.codec.NearByRouteRuleCacheHandler
-com.tencent.polaris.plugins.connector.grpc.codec.LosslessCacheHandler
\ No newline at end of file
+com.tencent.polaris.plugins.connector.grpc.codec.LosslessCacheHandler
+com.tencent.polaris.plugins.connector.grpc.codec.BlockAllowListRuleCacheHandler
diff --git a/polaris-plugins/pom.xml b/polaris-plugins/pom.xml
index 2d127bfdd..e67a8a523 100644
--- a/polaris-plugins/pom.xml
+++ b/polaris-plugins/pom.xml
@@ -30,5 +30,6 @@
polaris-plugins-location
polaris-plugins-configfilefilter
polaris-plugins-lossless
+ polaris-plugins-auth
diff --git a/polaris-ratelimit/polaris-ratelimit-client/src/main/java/com/tencent/polaris/ratelimit/client/flow/QuotaFlow.java b/polaris-ratelimit/polaris-ratelimit-client/src/main/java/com/tencent/polaris/ratelimit/client/flow/QuotaFlow.java
index 605a3a394..fdce3e2a0 100644
--- a/polaris-ratelimit/polaris-ratelimit-client/src/main/java/com/tencent/polaris/ratelimit/client/flow/QuotaFlow.java
+++ b/polaris-ratelimit/polaris-ratelimit-client/src/main/java/com/tencent/polaris/ratelimit/client/flow/QuotaFlow.java
@@ -383,11 +383,8 @@ private List lookupRules(ServiceRule serviceRule, String method, MetadataC
labelValue = getLabelValue(matchArgument, stringStringMap);
}
- if (null == labelValue) {
- matched = false;
- } else {
- matched = RuleUtils.matchStringValue(matchArgument.getValue(), labelValue, function);
- }
+ matched = RuleUtils.matchStringValue(matchArgument.getValue(), labelValue, function);
+
if (!matched) {
break;
}
diff --git a/pom.xml b/pom.xml
index e380e22d8..ed83d299d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,6 +60,7 @@
polaris-distribution
polaris-examples
polaris-configuration
+ polaris-auth
4.0.0