Http request use new plugin.
This commit is contained in:
parent
88818d0816
commit
80a6821bb7
@ -22,6 +22,7 @@ import com.alibaba.nacos.auth.api.Permission;
|
|||||||
import com.alibaba.nacos.auth.api.Resource;
|
import com.alibaba.nacos.auth.api.Resource;
|
||||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
import com.alibaba.nacos.auth.config.AuthConfigs;
|
||||||
import com.alibaba.nacos.auth.constant.Constants;
|
import com.alibaba.nacos.auth.constant.Constants;
|
||||||
|
import com.alibaba.nacos.auth.constant.SignType;
|
||||||
import com.alibaba.nacos.auth.exception.AccessException;
|
import com.alibaba.nacos.auth.exception.AccessException;
|
||||||
import com.alibaba.nacos.auth.util.Loggers;
|
import com.alibaba.nacos.auth.util.Loggers;
|
||||||
|
|
||||||
@ -79,6 +80,6 @@ public abstract class AbstractProtocolAuthService<R> implements ProtocolAuthServ
|
|||||||
* @return resource
|
* @return resource
|
||||||
*/
|
*/
|
||||||
protected Resource parseSpecifiedResource(Secured secured) {
|
protected Resource parseSpecifiedResource(Secured secured) {
|
||||||
return new Resource(null, null, secured.resource(), secured.signType(), null);
|
return new Resource(null, null, secured.resource(), SignType.SPECIFIED, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,4 +28,6 @@ public class SignType {
|
|||||||
public static final String CONFIG = "config";
|
public static final String CONFIG = "config";
|
||||||
|
|
||||||
public static final String CONSOLE = "console";
|
public static final String CONSOLE = "console";
|
||||||
|
|
||||||
|
public static final String SPECIFIED = "specified";
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ public class GrpcProtocolAuthServiceTest {
|
|||||||
Secured secured = getMethodSecure("testParseResourceWithSpecifiedResource");
|
Secured secured = getMethodSecure("testParseResourceWithSpecifiedResource");
|
||||||
Resource actual = protocolAuthService.parseResource(namingRequest, secured);
|
Resource actual = protocolAuthService.parseResource(namingRequest, secured);
|
||||||
assertEquals("testResource", actual.getName());
|
assertEquals("testResource", actual.getName());
|
||||||
assertEquals(SignType.NAMING, actual.getType());
|
assertEquals(SignType.SPECIFIED, actual.getType());
|
||||||
assertNull(actual.getNamespaceId());
|
assertNull(actual.getNamespaceId());
|
||||||
assertNull(actual.getGroup());
|
assertNull(actual.getGroup());
|
||||||
assertNull(actual.getProperties());
|
assertNull(actual.getProperties());
|
||||||
@ -141,13 +141,13 @@ public class GrpcProtocolAuthServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateAuthorityWithoutPlugin() {
|
public void testValidateAuthorityWithoutPlugin() throws AccessException {
|
||||||
assertTrue(protocolAuthService
|
assertTrue(protocolAuthService
|
||||||
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateAuthorityWithPlugin() {
|
public void testValidateAuthorityWithPlugin() throws AccessException {
|
||||||
Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
|
Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
|
||||||
assertFalse(protocolAuthService
|
assertFalse(protocolAuthService
|
||||||
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
||||||
|
@ -73,7 +73,7 @@ public class HttpProtocolAuthServiceTest {
|
|||||||
Secured secured = getMethodSecure("testParseResourceWithSpecifiedResource");
|
Secured secured = getMethodSecure("testParseResourceWithSpecifiedResource");
|
||||||
Resource actual = httpProtocolAuthService.parseResource(request, secured);
|
Resource actual = httpProtocolAuthService.parseResource(request, secured);
|
||||||
assertEquals("testResource", actual.getName());
|
assertEquals("testResource", actual.getName());
|
||||||
assertEquals(SignType.NAMING, actual.getType());
|
assertEquals(SignType.SPECIFIED, actual.getType());
|
||||||
assertNull(actual.getNamespaceId());
|
assertNull(actual.getNamespaceId());
|
||||||
assertNull(actual.getGroup());
|
assertNull(actual.getGroup());
|
||||||
assertNull(actual.getProperties());
|
assertNull(actual.getProperties());
|
||||||
@ -131,13 +131,13 @@ public class HttpProtocolAuthServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateAuthorityWithoutPlugin() {
|
public void testValidateAuthorityWithoutPlugin() throws AccessException {
|
||||||
assertTrue(httpProtocolAuthService
|
assertTrue(httpProtocolAuthService
|
||||||
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidateAuthorityWithPlugin() {
|
public void testValidateAuthorityWithPlugin() throws AccessException {
|
||||||
Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
|
Mockito.when(authConfigs.getNacosAuthSystemType()).thenReturn(MockAuthPluginService.TEST_PLUGIN);
|
||||||
assertFalse(httpProtocolAuthService
|
assertFalse(httpProtocolAuthService
|
||||||
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
.validateAuthority(new IdentityContext(), new Permission(Resource.EMPTY_RESOURCE, "")));
|
||||||
|
@ -19,7 +19,6 @@ package com.alibaba.nacos.console.security.nacos;
|
|||||||
import com.alibaba.nacos.api.common.Constants;
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
import com.alibaba.nacos.api.remote.request.Request;
|
import com.alibaba.nacos.api.remote.request.Request;
|
||||||
import com.alibaba.nacos.auth.AuthManager;
|
import com.alibaba.nacos.auth.AuthManager;
|
||||||
import com.alibaba.nacos.auth.AuthPluginService;
|
|
||||||
import com.alibaba.nacos.auth.api.IdentityContext;
|
import com.alibaba.nacos.auth.api.IdentityContext;
|
||||||
import com.alibaba.nacos.auth.api.Permission;
|
import com.alibaba.nacos.auth.api.Permission;
|
||||||
import com.alibaba.nacos.auth.exception.AccessException;
|
import com.alibaba.nacos.auth.exception.AccessException;
|
||||||
@ -41,8 +40,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,21 +49,7 @@ import java.util.List;
|
|||||||
* @since 1.2.0
|
* @since 1.2.0
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
|
public class NacosAuthManager implements AuthManager {
|
||||||
public class NacosAuthManager implements AuthManager, AuthPluginService {
|
|
||||||
|
|
||||||
private static final String AUTH_PLUGIN_TYPE = "nacos";
|
|
||||||
|
|
||||||
private static final String USER_IDENTITY_PARAM_KEY = "user";
|
|
||||||
|
|
||||||
private static final List<String> IDENTITY_NAMES = new LinkedList<String>() {
|
|
||||||
{
|
|
||||||
add(AuthConstants.AUTHORIZATION_HEADER);
|
|
||||||
add(Constants.ACCESS_TOKEN);
|
|
||||||
add(AuthConstants.PARAM_USERNAME);
|
|
||||||
add(AuthConstants.PARAM_PASSWORD);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private JwtTokenManager tokenManager;
|
private JwtTokenManager tokenManager;
|
||||||
@ -87,6 +70,12 @@ public class NacosAuthManager implements AuthManager, AuthPluginService {
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
User login(IdentityContext identityContext) throws AccessException {
|
||||||
|
String token = resolveToken(identityContext);
|
||||||
|
validate0(token);
|
||||||
|
return getNacosUser(token);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User loginRemote(Object request) throws AccessException {
|
public User loginRemote(Object request) throws AccessException {
|
||||||
Request req = (Request) request;
|
Request req = (Request) request;
|
||||||
@ -97,33 +86,13 @@ public class NacosAuthManager implements AuthManager, AuthPluginService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void auth(Permission permission, User user) throws AccessException {
|
public void auth(Permission permission, User user) throws AccessException {
|
||||||
auth0(permission, user);
|
if (Loggers.AUTH.isDebugEnabled()) {
|
||||||
|
Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
if (!roleService.hasPermission(user.getUserName(), permission)) {
|
||||||
public Collection<String> identityNames() {
|
throw new AccessException("authorization failed!");
|
||||||
return IDENTITY_NAMES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean validateIdentity(IdentityContext identityContext) throws AccessException {
|
|
||||||
String token = resolveToken(identityContext);
|
|
||||||
validate0(token);
|
|
||||||
NacosUser user = getNacosUser(token);
|
|
||||||
identityContext.setParameter(USER_IDENTITY_PARAM_KEY, user);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean validateAuthority(IdentityContext identityContext, Permission permission) throws AccessException {
|
|
||||||
NacosUser user = (NacosUser) identityContext.getParameter(USER_IDENTITY_PARAM_KEY);
|
|
||||||
auth0(permission, user);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getAuthServiceName() {
|
|
||||||
return AUTH_PLUGIN_TYPE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -228,14 +197,4 @@ public class NacosAuthManager implements AuthManager, AuthPluginService {
|
|||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void auth0(Permission permission, User user) throws AccessException {
|
|
||||||
if (Loggers.AUTH.isDebugEnabled()) {
|
|
||||||
Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!roleService.hasPermission(user.getUserName(), permission)) {
|
|
||||||
throw new AccessException("authorization failed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* 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.console.security.nacos;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
|
import com.alibaba.nacos.auth.AuthPluginService;
|
||||||
|
import com.alibaba.nacos.auth.api.IdentityContext;
|
||||||
|
import com.alibaba.nacos.auth.api.Permission;
|
||||||
|
import com.alibaba.nacos.auth.exception.AccessException;
|
||||||
|
import com.alibaba.nacos.auth.model.User;
|
||||||
|
import com.alibaba.nacos.console.security.nacos.constant.AuthConstants;
|
||||||
|
import com.alibaba.nacos.console.security.nacos.users.NacosUser;
|
||||||
|
import com.alibaba.nacos.sys.utils.ApplicationUtils;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nacos default auth plugin service implementation.
|
||||||
|
*
|
||||||
|
* @author xiweng.yy
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("PMD.ServiceOrDaoClassShouldEndWithImplRule")
|
||||||
|
public class NacosAuthPluginService implements AuthPluginService {
|
||||||
|
|
||||||
|
private static final String AUTH_PLUGIN_TYPE = "nacos";
|
||||||
|
|
||||||
|
private static final String USER_IDENTITY_PARAM_KEY = "user";
|
||||||
|
|
||||||
|
private static final List<String> IDENTITY_NAMES = new LinkedList<String>() {
|
||||||
|
{
|
||||||
|
add(AuthConstants.AUTHORIZATION_HEADER);
|
||||||
|
add(Constants.ACCESS_TOKEN);
|
||||||
|
add(AuthConstants.PARAM_USERNAME);
|
||||||
|
add(AuthConstants.PARAM_PASSWORD);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private NacosAuthManager nacosAuthManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> identityNames() {
|
||||||
|
return IDENTITY_NAMES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validateIdentity(IdentityContext identityContext) throws AccessException {
|
||||||
|
checkNacosAuthManager();
|
||||||
|
User user = nacosAuthManager.login(identityContext);
|
||||||
|
identityContext.setParameter(USER_IDENTITY_PARAM_KEY, user);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean validateAuthority(IdentityContext identityContext, Permission permission) throws AccessException {
|
||||||
|
NacosUser user = (NacosUser) identityContext.getParameter(USER_IDENTITY_PARAM_KEY);
|
||||||
|
nacosAuthManager.auth(permission, user);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAuthServiceName() {
|
||||||
|
return AUTH_PLUGIN_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkNacosAuthManager() {
|
||||||
|
if (null == nacosAuthManager) {
|
||||||
|
nacosAuthManager = ApplicationUtils.getBean(NacosAuthManager.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
package com.alibaba.nacos.console.security.nacos.roles;
|
package com.alibaba.nacos.console.security.nacos.roles;
|
||||||
|
|
||||||
import com.alibaba.nacos.auth.config.AuthConfigs;
|
|
||||||
import com.alibaba.nacos.auth.api.Permission;
|
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.constant.SignType;
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
import com.alibaba.nacos.config.server.auth.PermissionInfo;
|
import com.alibaba.nacos.config.server.auth.PermissionInfo;
|
||||||
import com.alibaba.nacos.config.server.auth.PermissionPersistService;
|
import com.alibaba.nacos.config.server.auth.PermissionPersistService;
|
||||||
@ -115,7 +118,7 @@ public class NacosRoleServiceImpl {
|
|||||||
*/
|
*/
|
||||||
public boolean hasPermission(String username, Permission permission) {
|
public boolean hasPermission(String username, Permission permission) {
|
||||||
//update password
|
//update password
|
||||||
if (AuthConstants.UPDATE_PASSWORD_ENTRY_POINT.equals(permission.getResource())) {
|
if (AuthConstants.UPDATE_PASSWORD_ENTRY_POINT.equals(permission.getResource().getName())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ public class NacosRoleServiceImpl {
|
|||||||
String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*");
|
String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*");
|
||||||
String permissionAction = permissionInfo.getAction();
|
String permissionAction = permissionInfo.getAction();
|
||||||
if (permissionAction.contains(permission.getAction()) && Pattern
|
if (permissionAction.contains(permission.getAction()) && Pattern
|
||||||
.matches(permissionResource, permission.getResource().getName())) {
|
.matches(permissionResource, joinResource(permission.getResource()))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,4 +254,29 @@ public class NacosRoleServiceImpl {
|
|||||||
public List<String> findRolesLikeRoleName(String role) {
|
public List<String> findRolesLikeRoleName(String role) {
|
||||||
return rolePersistService.findRolesLikeRoleName(role);
|
return rolePersistService.findRolesLikeRoleName(role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String joinResource(Resource resource) {
|
||||||
|
if (SignType.SPECIFIED.equals(resource.getType())) {
|
||||||
|
return resource.getName();
|
||||||
|
}
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
String namespaceId = resource.getNamespaceId();
|
||||||
|
if (StringUtils.isNotBlank(namespaceId)) {
|
||||||
|
result.append(namespaceId);
|
||||||
|
}
|
||||||
|
String group = resource.getGroup();
|
||||||
|
if (StringUtils.isBlank(group)) {
|
||||||
|
result.append(Constants.Resource.SPLITTER).append('*');
|
||||||
|
} else {
|
||||||
|
result.append(Constants.Resource.SPLITTER).append(group);
|
||||||
|
}
|
||||||
|
String resourceName = resource.getName();
|
||||||
|
if (StringUtils.isBlank(resourceName)) {
|
||||||
|
result.append(Constants.Resource.SPLITTER).append(resource.getType().toLowerCase()).append("/*");
|
||||||
|
} else {
|
||||||
|
result.append(Constants.Resource.SPLITTER).append(resource.getType().toLowerCase()).append('/')
|
||||||
|
.append(resourceName);
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
com.alibaba.nacos.console.security.nacos.NacosAuthPluginService
|
@ -19,6 +19,9 @@ package com.alibaba.nacos.core.auth;
|
|||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,12 +30,16 @@ import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
|||||||
* @author chenglu
|
* @author chenglu
|
||||||
* @date 2021-07-06 13:36
|
* @date 2021-07-06 13:36
|
||||||
*/
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class AuthConfigTest {
|
public class AuthConfigTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AuthFilter authFilter;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAuthFilterRegistration() {
|
public void testAuthFilterRegistration() {
|
||||||
AuthConfig config = new AuthConfig();
|
AuthConfig config = new AuthConfig();
|
||||||
FilterRegistrationBean filter = config.authFilterRegistration();
|
FilterRegistrationBean filter = config.authFilterRegistration(authFilter);
|
||||||
Assert.assertTrue(filter.getFilter() instanceof AuthFilter);
|
Assert.assertTrue(filter.getFilter() instanceof AuthFilter);
|
||||||
|
|
||||||
Assert.assertTrue(filter.getUrlPatterns().contains("/*"));
|
Assert.assertTrue(filter.getUrlPatterns().contains("/*"));
|
||||||
|
Loading…
Reference in New Issue
Block a user