diff --git a/auth/src/main/java/com/alibaba/nacos/auth/AbstractProtocolAuthService.java b/auth/src/main/java/com/alibaba/nacos/auth/AbstractProtocolAuthService.java
new file mode 100644
index 000000000..0731fe630
--- /dev/null
+++ b/auth/src/main/java/com/alibaba/nacos/auth/AbstractProtocolAuthService.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1999-2021 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.auth;
+
+import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.IdentityContext;
+import com.alibaba.nacos.auth.api.Permission;
+import com.alibaba.nacos.auth.api.Resource;
+import com.alibaba.nacos.auth.config.AuthConfigs;
+import com.alibaba.nacos.auth.constant.Constants;
+import com.alibaba.nacos.auth.exception.AccessException;
+import com.alibaba.nacos.auth.util.Loggers;
+
+import java.util.Optional;
+
+/**
+ * Abstract protocol auth service.
+ *
+ *
Implement #validateIdentity and #validateAuthority method template.
+ *
+ * @author xiweng.yy
+ */
+public abstract class AbstractProtocolAuthService implements ProtocolAuthService {
+
+ protected final AuthConfigs authConfigs;
+
+ protected AbstractProtocolAuthService(AuthConfigs authConfigs) {
+ this.authConfigs = authConfigs;
+ }
+
+ @Override
+ public boolean validateIdentity(IdentityContext identityContext) throws AccessException {
+ if (!authConfigs.isAuthEnabled()) {
+ return true;
+ }
+ Optional authPluginService = AuthPluginManager.getInstance()
+ .findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType());
+ if (authPluginService.isPresent()) {
+ return authPluginService.get().validateIdentity(identityContext);
+ }
+ Loggers.AUTH.warn("Can't find auth plugin for type {}, please add plugin to classpath or set {} as false",
+ authConfigs.getNacosAuthSystemType(), Constants.Auth.NACOS_CORE_AUTH_ENABLED);
+ return true;
+ }
+
+ @Override
+ public boolean validateAuthority(IdentityContext identityContext, Permission permission) {
+ if (!authConfigs.isAuthEnabled()) {
+ return true;
+ }
+ Optional authPluginService = AuthPluginManager.getInstance()
+ .findAuthServiceSpiImpl(authConfigs.getNacosAuthSystemType());
+ if (authPluginService.isPresent()) {
+ return authPluginService.get().validateAuthority(identityContext, permission);
+ }
+ Loggers.AUTH.warn("Can't find auth plugin for type {}, please add plugin to classpath or set {} as false",
+ authConfigs.getNacosAuthSystemType(), Constants.Auth.NACOS_CORE_AUTH_ENABLED);
+ return true;
+ }
+
+ /**
+ * Get resource from secured annotation specified resource.
+ *
+ * @param secured secured annotation
+ * @return resource
+ */
+ protected Resource parseSpecifiedResource(Secured secured) {
+ return new Resource(null, null, secured.resource(), secured.signType(), null);
+ }
+}
diff --git a/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginService.java b/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginService.java
index 328d9d8db..dde7cae8a 100644
--- a/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginService.java
+++ b/auth/src/main/java/com/alibaba/nacos/auth/AuthPluginService.java
@@ -40,10 +40,10 @@ public interface AuthPluginService {
* To validate whether the identity context from request is legal or illegal.
*
* @param identityContext where we can find the user information
- * @return IdentityContext user auth result
+ * @return {@code true} if legal, otherwise {@code false}
* @throws AccessException if authentication is failed
*/
- IdentityContext validateIdentity(IdentityContext identityContext) throws AccessException;
+ boolean validateIdentity(IdentityContext identityContext) throws AccessException;
/**
* Validate the identity whether has the resource authority.
diff --git a/auth/src/main/java/com/alibaba/nacos/auth/GrpcProtocolAuthService.java b/auth/src/main/java/com/alibaba/nacos/auth/GrpcProtocolAuthService.java
new file mode 100644
index 000000000..9c7ea5601
--- /dev/null
+++ b/auth/src/main/java/com/alibaba/nacos/auth/GrpcProtocolAuthService.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1999-2021 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.auth;
+
+import com.alibaba.nacos.api.remote.request.Request;
+import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.IdentityContext;
+import com.alibaba.nacos.auth.api.Resource;
+import com.alibaba.nacos.auth.config.AuthConfigs;
+import com.alibaba.nacos.auth.constant.SignType;
+import com.alibaba.nacos.auth.context.GrpcIdentityContextBuilder;
+import com.alibaba.nacos.auth.parser.grpc.AbstractGrpcResourceParser;
+import com.alibaba.nacos.auth.parser.grpc.ConfigGrpcResourceParser;
+import com.alibaba.nacos.auth.parser.grpc.NamingGrpcResourceParser;
+import com.alibaba.nacos.auth.util.Loggers;
+import com.alibaba.nacos.common.utils.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Auth Service for Http protocol.
+ *
+ * @author xiweng.yy
+ */
+public class GrpcProtocolAuthService extends AbstractProtocolAuthService {
+
+ private final Map resourceParserMap;
+
+ private final GrpcIdentityContextBuilder identityContextBuilder;
+
+ protected GrpcProtocolAuthService(AuthConfigs authConfigs) {
+ super(authConfigs);
+ resourceParserMap = new HashMap<>(2);
+ identityContextBuilder = new GrpcIdentityContextBuilder(authConfigs);
+ }
+
+ @Override
+ public void initialize() {
+ resourceParserMap.put(SignType.NAMING, new NamingGrpcResourceParser());
+ resourceParserMap.put(SignType.CONFIG, new ConfigGrpcResourceParser());
+ }
+
+ @Override
+ public Resource parseResource(Request request, Secured secured) {
+ if (StringUtils.isNotBlank(secured.resource())) {
+ return parseSpecifiedResource(secured);
+ }
+ String type = secured.signType();
+ if (!resourceParserMap.containsKey(type)) {
+ Loggers.AUTH.warn("Can't find Grpc request resourceParser for type {}", type);
+ return Resource.EMPTY_RESOURCE;
+ }
+ return resourceParserMap.get(type).parse(request, type);
+ }
+
+ @Override
+ public IdentityContext parseIdentity(Request request) {
+ return identityContextBuilder.build(request);
+ }
+}
diff --git a/auth/src/main/java/com/alibaba/nacos/auth/HttpProtocolAuthService.java b/auth/src/main/java/com/alibaba/nacos/auth/HttpProtocolAuthService.java
new file mode 100644
index 000000000..3088c38e1
--- /dev/null
+++ b/auth/src/main/java/com/alibaba/nacos/auth/HttpProtocolAuthService.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 1999-2021 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.auth;
+
+import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.IdentityContext;
+import com.alibaba.nacos.auth.api.Resource;
+import com.alibaba.nacos.auth.config.AuthConfigs;
+import com.alibaba.nacos.auth.constant.SignType;
+import com.alibaba.nacos.auth.context.HttpIdentityContextBuilder;
+import com.alibaba.nacos.auth.parser.http.AbstractHttpResourceParser;
+import com.alibaba.nacos.auth.parser.http.ConfigHttpResourceParser;
+import com.alibaba.nacos.auth.parser.http.NamingHttpResourceParser;
+import com.alibaba.nacos.auth.util.Loggers;
+import com.alibaba.nacos.common.utils.StringUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Auth Service for Http protocol.
+ *
+ * @author xiweng.yy
+ */
+public class HttpProtocolAuthService extends AbstractProtocolAuthService {
+
+ private final Map resourceParserMap;
+
+ private final HttpIdentityContextBuilder identityContextBuilder;
+
+ protected HttpProtocolAuthService(AuthConfigs authConfigs) {
+ super(authConfigs);
+ resourceParserMap = new HashMap<>(2);
+ identityContextBuilder = new HttpIdentityContextBuilder(authConfigs);
+ }
+
+ @Override
+ public void initialize() {
+ resourceParserMap.put(SignType.NAMING, new NamingHttpResourceParser());
+ resourceParserMap.put(SignType.CONFIG, new ConfigHttpResourceParser());
+ }
+
+ @Override
+ public Resource parseResource(HttpServletRequest request, Secured secured) {
+ if (StringUtils.isNotBlank(secured.resource())) {
+ return parseSpecifiedResource(secured);
+ }
+ String type = secured.signType();
+ if (!resourceParserMap.containsKey(type)) {
+ Loggers.AUTH.warn("Can't find Http request resourceParser for type {}", type);
+ return Resource.EMPTY_RESOURCE;
+ }
+ return resourceParserMap.get(type).parse(request, type);
+ }
+
+ @Override
+ public IdentityContext parseIdentity(HttpServletRequest request) {
+ return identityContextBuilder.build(request);
+ }
+}
diff --git a/auth/src/main/java/com/alibaba/nacos/auth/ProtocolAuthService.java b/auth/src/main/java/com/alibaba/nacos/auth/ProtocolAuthService.java
new file mode 100644
index 000000000..95565fd21
--- /dev/null
+++ b/auth/src/main/java/com/alibaba/nacos/auth/ProtocolAuthService.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 1999-2021 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.auth;
+
+import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.IdentityContext;
+import com.alibaba.nacos.auth.api.Permission;
+import com.alibaba.nacos.auth.api.Resource;
+import com.alibaba.nacos.auth.exception.AccessException;
+
+/**
+ * Protocol auth service.
+ *
+ * @author xiweng.yy
+ */
+public interface ProtocolAuthService {
+
+ /**
+ * Init protocol auth service.
+ */
+ void initialize();
+
+ /**
+ * Parse resource from protocol request and secured annotation.
+ *
+ * @param request protocol request
+ * @param secured api secured annotation
+ * @return resource
+ */
+ Resource parseResource(R request, Secured secured);
+
+ /**
+ * Parse identity context from protocol request.
+ *
+ * @param request protocol request
+ * @return identity context
+ */
+ IdentityContext parseIdentity(R request);
+
+ /**
+ * Validate identity whether is legal.
+ *
+ * @param identityContext identity context
+ * @return {@code true} if legal, otherwise {@code false}
+ * @throws AccessException exception during validating
+ */
+ boolean validateIdentity(IdentityContext identityContext) throws AccessException;
+
+ /**
+ * Validate identity whether had permission for the resource and action.
+ *
+ * @param identityContext identity context
+ * @param permission permssion include resource and action
+ * @return {@code true} if legal, otherwise {@code false}
+ * @throws AccessException exception during validating
+ */
+ boolean validateAuthority(IdentityContext identityContext, Permission permission) throws AccessException;
+}
diff --git a/auth/src/main/java/com/alibaba/nacos/auth/api/Permission.java b/auth/src/main/java/com/alibaba/nacos/auth/api/Permission.java
index e0c6a77c8..c62537f2d 100644
--- a/auth/src/main/java/com/alibaba/nacos/auth/api/Permission.java
+++ b/auth/src/main/java/com/alibaba/nacos/auth/api/Permission.java
@@ -23,6 +23,7 @@ import java.io.Serializable;
*
* @author nkorange
* @author mai.jh
+ * @author xiweng.yy
* @since 1.2.0
*/
public class Permission implements Serializable {
@@ -32,7 +33,7 @@ public class Permission implements Serializable {
/**
* An unique key of resource.
*/
- private String resource;
+ private Resource resource;
/**
* Action on resource, refer to class ActionTypes.
@@ -43,16 +44,16 @@ public class Permission implements Serializable {
}
- public Permission(String resource, String action) {
+ public Permission(Resource resource, String action) {
this.resource = resource;
this.action = action;
}
- public String getResource() {
+ public Resource getResource() {
return resource;
}
- public void setResource(String resource) {
+ public void setResource(Resource resource) {
this.resource = resource;
}
diff --git a/auth/src/main/java/com/alibaba/nacos/auth/api/Resource.java b/auth/src/main/java/com/alibaba/nacos/auth/api/Resource.java
index f38de4d74..cbf43dddf 100644
--- a/auth/src/main/java/com/alibaba/nacos/auth/api/Resource.java
+++ b/auth/src/main/java/com/alibaba/nacos/auth/api/Resource.java
@@ -16,6 +16,8 @@
package com.alibaba.nacos.auth.api;
+import com.alibaba.nacos.common.utils.StringUtils;
+
import java.io.Serializable;
import java.util.Properties;
@@ -30,6 +32,9 @@ public class Resource implements Serializable {
private static final long serialVersionUID = 925971662931204553L;
+ public static final Resource EMPTY_RESOURCE = new Resource(StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY,
+ StringUtils.EMPTY, null);
+
private final String namespaceId;
private final String group;
diff --git a/auth/src/main/java/com/alibaba/nacos/auth/util/Loggers.java b/auth/src/main/java/com/alibaba/nacos/auth/util/Loggers.java
new file mode 100644
index 000000000..bb6cbe651
--- /dev/null
+++ b/auth/src/main/java/com/alibaba/nacos/auth/util/Loggers.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.auth.util;
+
+import ch.qos.logback.classic.Level;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Loggers for core.
+ *
+ * @author nkorange
+ * @since 1.2.0
+ */
+public class Loggers {
+
+ private static final String AUTH_LOG_NAME = "auth";
+
+ public static final Logger AUTH = LoggerFactory.getLogger("com.alibaba.nacos.auth");
+
+ public static void setLogLevel(String logName, String level) {
+
+ if (AUTH_LOG_NAME.equals(logName)) {
+ ((ch.qos.logback.classic.Logger) AUTH).setLevel(Level.valueOf(level));
+ }
+ }
+}
diff --git a/auth/src/test/java/com/alibaba/nacos/auth/GrpcProtocolAuthServiceTest.java b/auth/src/test/java/com/alibaba/nacos/auth/GrpcProtocolAuthServiceTest.java
new file mode 100644
index 000000000..93753715b
--- /dev/null
+++ b/auth/src/test/java/com/alibaba/nacos/auth/GrpcProtocolAuthServiceTest.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 1999-2021 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.auth;
+
+import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
+import com.alibaba.nacos.api.naming.remote.request.AbstractNamingRequest;
+import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.IdentityContext;
+import com.alibaba.nacos.auth.api.Permission;
+import com.alibaba.nacos.auth.api.Resource;
+import com.alibaba.nacos.auth.config.AuthConfigs;
+import com.alibaba.nacos.auth.constant.SignType;
+import com.alibaba.nacos.auth.exception.AccessException;
+import com.alibaba.nacos.auth.mock.MockAuthPluginService;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.lang.reflect.Method;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(MockitoJUnitRunner.class)
+public class GrpcProtocolAuthServiceTest {
+
+ @Mock
+ private AuthConfigs authConfigs;
+
+ private ConfigPublishRequest configRequest;
+
+ private AbstractNamingRequest namingRequest;
+
+ private GrpcProtocolAuthService protocolAuthService;
+
+ @Before
+ public void setUp() throws Exception {
+ protocolAuthService = new GrpcProtocolAuthService(authConfigs);
+ protocolAuthService.initialize();
+ mockConfigRequest();
+ mockNamingRequest();
+ Mockito.when(authConfigs.isAuthEnabled()).thenReturn(true);
+ }
+
+ private void mockConfigRequest() {
+ configRequest = new ConfigPublishRequest();
+ configRequest.setTenant("testCNs");
+ configRequest.setGroup("testCG");
+ configRequest.setDataId("testD");
+ }
+
+ private void mockNamingRequest() {
+ namingRequest = new AbstractNamingRequest() {
+ };
+ namingRequest.setNamespace("testNNs");
+ namingRequest.setGroupName("testNG");
+ namingRequest.setServiceName("testS");
+ }
+
+ @Test
+ @Secured(resource = "testResource")
+ public void testParseResourceWithSpecifiedResource() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithSpecifiedResource");
+ Resource actual = protocolAuthService.parseResource(namingRequest, secured);
+ assertEquals("testResource", actual.getName());
+ assertEquals(SignType.NAMING, actual.getType());
+ assertNull(actual.getNamespaceId());
+ assertNull(actual.getGroup());
+ assertNull(actual.getProperties());
+ }
+
+ @Test
+ @Secured(signType = "non-exist")
+ public void testParseResourceWithNonExistType() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithNonExistType");
+ Resource actual = protocolAuthService.parseResource(namingRequest, secured);
+ assertEquals(Resource.EMPTY_RESOURCE, actual);
+ }
+
+ @Test
+ @Secured()
+ public void testParseResourceWithNamingType() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithNamingType");
+ Resource actual = protocolAuthService.parseResource(namingRequest, secured);
+ assertEquals(SignType.NAMING, actual.getType());
+ assertEquals("testS", actual.getName());
+ assertEquals("testNNs", actual.getNamespaceId());
+ assertEquals("testNG", actual.getGroup());
+ assertNotNull(actual.getProperties());
+ }
+
+ @Test
+ @Secured(signType = SignType.CONFIG)
+ public void testParseResourceWithConfigType() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithConfigType");
+ Resource actual = protocolAuthService.parseResource(configRequest, secured);
+ assertEquals(SignType.CONFIG, actual.getType());
+ assertEquals("testD", actual.getName());
+ assertEquals("testCNs", actual.getNamespaceId());
+ assertEquals("testCG", actual.getGroup());
+ assertNotNull(actual.getProperties());
+ }
+
+ @Test
+ public void testParseIdentity() {
+ IdentityContext actual = protocolAuthService.parseIdentity(namingRequest);
+ assertNotNull(actual);
+ }
+
+ @Test
+ public void testValidateIdentityWithoutPlugin() throws AccessException {
+ IdentityContext identityContext = new IdentityContext();
+ assertTrue(protocolAuthService.validateIdentity(identityContext));
+ }
+
+ @Test
+ public void testValidateIdentityWithPlugin() throws AccessException {
+ Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
+ IdentityContext identityContext = new IdentityContext();
+ assertFalse(protocolAuthService.validateIdentity(identityContext));
+ }
+
+ @Test
+ public void testValidateAuthorityWithoutPlugin() {
+ assertTrue(protocolAuthService
+ .validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
+ }
+
+ @Test
+ public void testValidateAuthorityWithPlugin() {
+ Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
+ assertFalse(protocolAuthService
+ .validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
+ }
+
+ private Secured getMethodSecure(String methodName) throws NoSuchMethodException {
+ Method method = GrpcProtocolAuthServiceTest.class.getMethod(methodName);
+ return method.getAnnotation(Secured.class);
+ }
+}
diff --git a/auth/src/test/java/com/alibaba/nacos/auth/HttpProtocolAuthServiceTest.java b/auth/src/test/java/com/alibaba/nacos/auth/HttpProtocolAuthServiceTest.java
new file mode 100644
index 000000000..0715f485b
--- /dev/null
+++ b/auth/src/test/java/com/alibaba/nacos/auth/HttpProtocolAuthServiceTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 1999-2021 Alibaba Group Holding Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.nacos.auth;
+
+import com.alibaba.nacos.api.common.Constants;
+import com.alibaba.nacos.api.naming.CommonParams;
+import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.IdentityContext;
+import com.alibaba.nacos.auth.api.Permission;
+import com.alibaba.nacos.auth.api.Resource;
+import com.alibaba.nacos.auth.config.AuthConfigs;
+import com.alibaba.nacos.auth.constant.SignType;
+import com.alibaba.nacos.auth.exception.AccessException;
+import com.alibaba.nacos.auth.mock.MockAuthPluginService;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+
+@RunWith(MockitoJUnitRunner.class)
+public class HttpProtocolAuthServiceTest {
+
+ @Mock
+ private AuthConfigs authConfigs;
+
+ @Mock
+ private HttpServletRequest request;
+
+ private HttpProtocolAuthService httpProtocolAuthService;
+
+ @Before
+ public void setUp() throws Exception {
+ httpProtocolAuthService = new HttpProtocolAuthService(authConfigs);
+ httpProtocolAuthService.initialize();
+ Mockito.when(request.getParameter(eq(CommonParams.NAMESPACE_ID))).thenReturn("testNNs");
+ Mockito.when(request.getParameter(eq(CommonParams.GROUP_NAME))).thenReturn("testNG");
+ Mockito.when(request.getParameter(eq(CommonParams.SERVICE_NAME))).thenReturn("testS");
+ Mockito.when(request.getParameter(eq("tenant"))).thenReturn("testCNs");
+ Mockito.when(request.getParameter(eq(Constants.GROUP))).thenReturn("testCG");
+ Mockito.when(request.getParameter(eq(Constants.DATAID))).thenReturn("testD");
+ Mockito.when(authConfigs.isAuthEnabled()).thenReturn(true);
+ }
+
+ @Test
+ @Secured(resource = "testResource")
+ public void testParseResourceWithSpecifiedResource() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithSpecifiedResource");
+ Resource actual = httpProtocolAuthService.parseResource(request, secured);
+ assertEquals("testResource", actual.getName());
+ assertEquals(SignType.NAMING, actual.getType());
+ assertNull(actual.getNamespaceId());
+ assertNull(actual.getGroup());
+ assertNull(actual.getProperties());
+ }
+
+ @Test
+ @Secured(signType = "non-exist")
+ public void testParseResourceWithNonExistType() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithNonExistType");
+ Resource actual = httpProtocolAuthService.parseResource(request, secured);
+ assertEquals(Resource.EMPTY_RESOURCE, actual);
+ }
+
+ @Test
+ @Secured()
+ public void testParseResourceWithNamingType() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithNamingType");
+ Resource actual = httpProtocolAuthService.parseResource(request, secured);
+ assertEquals(SignType.NAMING, actual.getType());
+ assertEquals("testS", actual.getName());
+ assertEquals("testNNs", actual.getNamespaceId());
+ assertEquals("testNG", actual.getGroup());
+ assertNotNull(actual.getProperties());
+ }
+
+ @Test
+ @Secured(signType = SignType.CONFIG)
+ public void testParseResourceWithConfigType() throws NoSuchMethodException {
+ Secured secured = getMethodSecure("testParseResourceWithConfigType");
+ Resource actual = httpProtocolAuthService.parseResource(request, secured);
+ assertEquals(SignType.CONFIG, actual.getType());
+ assertEquals("testD", actual.getName());
+ assertEquals("testCNs", actual.getNamespaceId());
+ assertEquals("testCG", actual.getGroup());
+ assertNotNull(actual.getProperties());
+ }
+
+ @Test
+ public void testParseIdentity() {
+ IdentityContext actual = httpProtocolAuthService.parseIdentity(request);
+ assertNotNull(actual);
+ }
+
+ @Test
+ public void testValidateIdentityWithoutPlugin() throws AccessException {
+ IdentityContext identityContext = new IdentityContext();
+ assertTrue(httpProtocolAuthService.validateIdentity(identityContext));
+ }
+
+ @Test
+ public void testValidateIdentityWithPlugin() throws AccessException {
+ Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
+ IdentityContext identityContext = new IdentityContext();
+ assertFalse(httpProtocolAuthService.validateIdentity(identityContext));
+ }
+
+ @Test
+ public void testValidateAuthorityWithoutPlugin() {
+ assertTrue(httpProtocolAuthService
+ .validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
+ }
+
+ @Test
+ public void testValidateAuthorityWithPlugin() {
+ Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
+ assertFalse(httpProtocolAuthService
+ .validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
+ }
+
+ private Secured getMethodSecure(String methodName) throws NoSuchMethodException {
+ Method method = HttpProtocolAuthServiceTest.class.getMethod(methodName);
+ return method.getAnnotation(Secured.class);
+ }
+}
diff --git a/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java b/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java
index 7a56abecc..1eddb5776 100644
--- a/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java
+++ b/console/src/main/java/com/alibaba/nacos/console/security/nacos/roles/NacosRoleServiceImpl.java
@@ -132,7 +132,7 @@ public class NacosRoleServiceImpl {
}
// Old global admin can pass resource 'console/':
- if (permission.getResource().startsWith(AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX)) {
+ if (permission.getResource().getName().startsWith(AuthConstants.CONSOLE_RESOURCE_NAME_PREFIX)) {
return false;
}
@@ -146,7 +146,7 @@ public class NacosRoleServiceImpl {
String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*");
String permissionAction = permissionInfo.getAction();
if (permissionAction.contains(permission.getAction()) && Pattern
- .matches(permissionResource, permission.getResource())) {
+ .matches(permissionResource, permission.getResource().getName())) {
return true;
}
}
diff --git a/core/src/main/java/com/alibaba/nacos/core/auth/AuthFilter.java b/core/src/main/java/com/alibaba/nacos/core/auth/AuthFilter.java
index 255dd7d40..d2316dd81 100644
--- a/core/src/main/java/com/alibaba/nacos/core/auth/AuthFilter.java
+++ b/core/src/main/java/com/alibaba/nacos/core/auth/AuthFilter.java
@@ -18,6 +18,7 @@ package com.alibaba.nacos.core.auth;
import com.alibaba.nacos.auth.AuthManager;
import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.Resource;
import com.alibaba.nacos.auth.config.AuthConfigs;
import com.alibaba.nacos.auth.exception.AccessException;
import com.alibaba.nacos.auth.api.Permission;
@@ -125,8 +126,9 @@ public class AuthFilter implements Filter {
// deny if we don't find any resource:
throw new AccessException("resource name invalid!");
}
-
- authManager.auth(new Permission(resource, action), authManager.login(req));
+
+ Resource resourceObj = new Resource(null, null, resource, secured.signType(), null);
+ authManager.auth(new Permission(resourceObj, action), authManager.login(req));
}
chain.doFilter(request, response);
diff --git a/core/src/main/java/com/alibaba/nacos/core/auth/RemoteRequestAuthFilter.java b/core/src/main/java/com/alibaba/nacos/core/auth/RemoteRequestAuthFilter.java
index e2be6f3af..ecb0d4eb1 100644
--- a/core/src/main/java/com/alibaba/nacos/core/auth/RemoteRequestAuthFilter.java
+++ b/core/src/main/java/com/alibaba/nacos/core/auth/RemoteRequestAuthFilter.java
@@ -22,6 +22,7 @@ import com.alibaba.nacos.api.remote.request.RequestMeta;
import com.alibaba.nacos.api.remote.response.Response;
import com.alibaba.nacos.auth.AuthManager;
import com.alibaba.nacos.auth.annotation.Secured;
+import com.alibaba.nacos.auth.api.Resource;
import com.alibaba.nacos.auth.config.AuthConfigs;
import com.alibaba.nacos.auth.exception.AccessException;
import com.alibaba.nacos.auth.api.Permission;
@@ -75,8 +76,9 @@ public class RemoteRequestAuthFilter extends AbstractRequestFilter {
// deny if we don't find any resource:
throw new AccessException("resource name invalid!");
}
-
- authManager.auth(new Permission(resource, action), authManager.loginRemote(request));
+
+ Resource resourceObj = new Resource(null, null, resource, secured.signType(), null);
+ authManager.auth(new Permission(resourceObj, action), authManager.loginRemote(request));
}
} catch (AccessException e) {