#1105 Add auth test case for config
This commit is contained in:
parent
29119d0956
commit
1fb1f5f3e3
@ -274,14 +274,14 @@ public class ServerHttpAgent implements HttpAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void injectSecurityInfo(List<String> params) {
|
private void injectSecurityInfo(List<String> params) {
|
||||||
ArrayList<String> list = (ArrayList) params;
|
//ArrayList<String> list = (ArrayList) params;
|
||||||
if (StringUtils.isNotBlank(securityProxy.getAccessToken())) {
|
if (StringUtils.isNotBlank(securityProxy.getAccessToken())) {
|
||||||
list.add(Constants.ACCESS_TOKEN);
|
params.add(Constants.ACCESS_TOKEN);
|
||||||
list.add(securityProxy.getAccessToken());
|
params.add(securityProxy.getAccessToken());
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(namespaceId)) {
|
if (StringUtils.isNotBlank(namespaceId)) {
|
||||||
list.add("tenant");
|
params.add("tenant");
|
||||||
list.add(namespaceId);
|
params.add(namespaceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +359,10 @@ public class ClientWorker {
|
|||||||
*/
|
*/
|
||||||
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
|
List<String> checkUpdateConfigStr(String probeUpdateString, boolean isInitializingCacheList) throws IOException {
|
||||||
|
|
||||||
List<String> params = Arrays.asList(Constants.PROBE_MODIFY_REQUEST, probeUpdateString);
|
|
||||||
|
List<String> params = new ArrayList<String>(2);
|
||||||
|
params.add(Constants.PROBE_MODIFY_REQUEST);
|
||||||
|
params.add(probeUpdateString);
|
||||||
|
|
||||||
List<String> headers = new ArrayList<String>(2);
|
List<String> headers = new ArrayList<String>(2);
|
||||||
headers.add("Long-Pulling-Timeout");
|
headers.add("Long-Pulling-Timeout");
|
||||||
@ -516,6 +519,7 @@ public class ClientWorker {
|
|||||||
|
|
||||||
// check server config
|
// check server config
|
||||||
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
|
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
|
||||||
|
LOGGER.info("get changedGroupKeys:" + changedGroupKeys);
|
||||||
|
|
||||||
for (String groupKey : changedGroupKeys) {
|
for (String groupKey : changedGroupKeys) {
|
||||||
String[] key = GroupKey.parseKey(groupKey);
|
String[] key = GroupKey.parseKey(groupKey);
|
||||||
|
@ -282,6 +282,8 @@ public class ConfigController {
|
|||||||
throw new IllegalArgumentException("invalid probeModify");
|
throw new IllegalArgumentException("invalid probeModify");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("listen config id:" + probeModify);
|
||||||
|
|
||||||
probeModify = URLDecoder.decode(probeModify, Constants.ENCODE);
|
probeModify = URLDecoder.decode(probeModify, Constants.ENCODE);
|
||||||
|
|
||||||
Map<String, String> clientMd5Map;
|
Map<String, String> clientMd5Map;
|
||||||
@ -291,6 +293,8 @@ public class ConfigController {
|
|||||||
throw new IllegalArgumentException("invalid probeModify");
|
throw new IllegalArgumentException("invalid probeModify");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.info("listen config id 2:" + probeModify);
|
||||||
|
|
||||||
// do long-polling
|
// do long-polling
|
||||||
inner.doPollingConfig(request, response, clientMd5Map, probeModify.length());
|
inner.doPollingConfig(request, response, clientMd5Map, probeModify.length());
|
||||||
}
|
}
|
||||||
@ -376,7 +380,7 @@ public class ConfigController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(params = "beta=true")
|
@DeleteMapping(params = "beta=true")
|
||||||
@Secured(action = ActionTypes.READ, parser = ConfigResourceParser.class)
|
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||||
public RestResult<Boolean> stopBeta(@RequestParam(value = "dataId") String dataId,
|
public RestResult<Boolean> stopBeta(@RequestParam(value = "dataId") String dataId,
|
||||||
@RequestParam(value = "group") String group,
|
@RequestParam(value = "group") String group,
|
||||||
@RequestParam(value = "tenant", required = false,
|
@RequestParam(value = "tenant", required = false,
|
||||||
@ -545,6 +549,7 @@ public class ConfigController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(params = "clone=true")
|
@PostMapping(params = "clone=true")
|
||||||
|
@Secured(action = ActionTypes.WRITE, parser = ConfigResourceParser.class)
|
||||||
public RestResult<Map<String, Object>> cloneConfig(HttpServletRequest request,
|
public RestResult<Map<String, Object>> cloneConfig(HttpServletRequest request,
|
||||||
@RequestParam(value = "src_user", required = false) String srcUser,
|
@RequestParam(value = "src_user", required = false) String srcUser,
|
||||||
@RequestParam(value = "tenant", required = true) String namespace,
|
@RequestParam(value = "tenant", required = true) String namespace,
|
||||||
|
@ -24,6 +24,7 @@ import com.alibaba.nacos.config.server.service.LongPollingService;
|
|||||||
import com.alibaba.nacos.config.server.service.PersistService;
|
import com.alibaba.nacos.config.server.service.PersistService;
|
||||||
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
import com.alibaba.nacos.config.server.service.trace.ConfigTraceService;
|
||||||
import com.alibaba.nacos.config.server.utils.*;
|
import com.alibaba.nacos.config.server.utils.*;
|
||||||
|
import com.alibaba.nacos.core.utils.Loggers;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -98,6 +99,8 @@ public class ConfigServletInner {
|
|||||||
request.setAttribute("content", newResult);
|
request.setAttribute("content", newResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loggers.AUTH.info("new content:" + newResult);
|
||||||
|
|
||||||
// 禁用缓存
|
// 禁用缓存
|
||||||
response.setHeader("Pragma", "no-cache");
|
response.setHeader("Pragma", "no-cache");
|
||||||
response.setDateHeader("Expires", 0);
|
response.setDateHeader("Expires", 0);
|
||||||
|
@ -186,7 +186,8 @@ CREATE TABLE users (
|
|||||||
|
|
||||||
CREATE TABLE roles (
|
CREATE TABLE roles (
|
||||||
username varchar(50) NOT NULL,
|
username varchar(50) NOT NULL,
|
||||||
role varchar(50) NOT NULL
|
role varchar(50) NOT NULL,
|
||||||
|
constraint uk_username_role UNIQUE (username,role)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE permissions (
|
CREATE TABLE permissions (
|
||||||
|
@ -181,7 +181,8 @@ CREATE TABLE users (
|
|||||||
|
|
||||||
CREATE TABLE roles (
|
CREATE TABLE roles (
|
||||||
username varchar(50) NOT NULL,
|
username varchar(50) NOT NULL,
|
||||||
role varchar(50) NOT NULL
|
role varchar(50) NOT NULL,
|
||||||
|
constraint uk_username_role UNIQUE (username,role)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE permissions (
|
CREATE TABLE permissions (
|
||||||
|
@ -51,7 +51,7 @@ public class HealthController {
|
|||||||
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
|
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
|
||||||
* Nacos is in broken states.
|
* Nacos is in broken states.
|
||||||
*/
|
*/
|
||||||
@GetMapping("liveness")
|
@GetMapping("/liveness")
|
||||||
public ResponseEntity liveness() {
|
public ResponseEntity liveness() {
|
||||||
return ResponseEntity.ok().body("OK");
|
return ResponseEntity.ok().body("OK");
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ public class HealthController {
|
|||||||
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
|
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
|
||||||
* ready.
|
* ready.
|
||||||
*/
|
*/
|
||||||
@GetMapping("readiness")
|
@GetMapping("/readiness")
|
||||||
public ResponseEntity readiness(HttpServletRequest request) {
|
public ResponseEntity readiness(HttpServletRequest request) {
|
||||||
boolean isConfigReadiness = isConfigReadiness();
|
boolean isConfigReadiness = isConfigReadiness();
|
||||||
boolean isNamingReadiness = isNamingReadiness(request);
|
boolean isNamingReadiness = isNamingReadiness(request);
|
||||||
|
@ -34,7 +34,7 @@ import java.util.Map;
|
|||||||
@RequestMapping("/v1/console/server")
|
@RequestMapping("/v1/console/server")
|
||||||
public class ServerStateController {
|
public class ServerStateController {
|
||||||
|
|
||||||
@GetMapping("state")
|
@GetMapping("/state")
|
||||||
public ResponseEntity serverState() {
|
public ResponseEntity serverState() {
|
||||||
Map<String,String> serverState = new HashMap<>(3);
|
Map<String,String> serverState = new HashMap<>(3);
|
||||||
serverState.put("standalone_mode",SystemUtils.STANDALONE_MODE ?
|
serverState.put("standalone_mode",SystemUtils.STANDALONE_MODE ?
|
||||||
|
@ -28,6 +28,7 @@ import com.alibaba.nacos.core.auth.Permission;
|
|||||||
import com.alibaba.nacos.core.utils.Loggers;
|
import com.alibaba.nacos.core.utils.Loggers;
|
||||||
import io.jsonwebtoken.lang.Collections;
|
import io.jsonwebtoken.lang.Collections;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.mina.util.ConcurrentHashSet;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -59,6 +60,8 @@ public class NacosRoleServiceImpl {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PermissionPersistService permissionPersistService;
|
private PermissionPersistService permissionPersistService;
|
||||||
|
|
||||||
|
private Set<String> roleSet = new ConcurrentHashSet<>();
|
||||||
|
|
||||||
private Map<String, List<RoleInfo>> roleInfoMap = new ConcurrentHashMap<>();
|
private Map<String, List<RoleInfo>> roleInfoMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private Map<String, List<PermissionInfo>> permissionInfoMap = new ConcurrentHashMap<>();
|
private Map<String, List<PermissionInfo>> permissionInfoMap = new ConcurrentHashMap<>();
|
||||||
@ -70,22 +73,23 @@ public class NacosRoleServiceImpl {
|
|||||||
if (roleInfoPage == null) {
|
if (roleInfoPage == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Set<String> roleSet = new HashSet<>(16);
|
Set<String> tmpRoleSet = new HashSet<>(16);
|
||||||
Map<String, List<RoleInfo>> tmpRoleInfoMap = new ConcurrentHashMap<>(16);
|
Map<String, List<RoleInfo>> tmpRoleInfoMap = new ConcurrentHashMap<>(16);
|
||||||
for (RoleInfo roleInfo : roleInfoPage.getPageItems()) {
|
for (RoleInfo roleInfo : roleInfoPage.getPageItems()) {
|
||||||
if (!tmpRoleInfoMap.containsKey(roleInfo.getUsername())) {
|
if (!tmpRoleInfoMap.containsKey(roleInfo.getUsername())) {
|
||||||
tmpRoleInfoMap.put(roleInfo.getUsername(), new ArrayList<>());
|
tmpRoleInfoMap.put(roleInfo.getUsername(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo);
|
tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo);
|
||||||
roleSet.add(roleInfo.getRole());
|
tmpRoleSet.add(roleInfo.getRole());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
|
Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
|
||||||
for (String role : roleSet) {
|
for (String role : tmpRoleSet) {
|
||||||
Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE);
|
Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE);
|
||||||
tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
|
tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
roleSet = tmpRoleSet;
|
||||||
roleInfoMap = tmpRoleInfoMap;
|
roleInfoMap = tmpRoleInfoMap;
|
||||||
permissionInfoMap = tmpPermissionInfoMap;
|
permissionInfoMap = tmpPermissionInfoMap;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -178,6 +182,9 @@ public class NacosRoleServiceImpl {
|
|||||||
if (userDetailsService.getUser(username) == null) {
|
if (userDetailsService.getUser(username) == null) {
|
||||||
throw new IllegalArgumentException("user '" + username + "' not found!");
|
throw new IllegalArgumentException("user '" + username + "' not found!");
|
||||||
}
|
}
|
||||||
|
if (GLOBAL_ADMIN_ROLE.equals(role)) {
|
||||||
|
throw new IllegalArgumentException("role '" + GLOBAL_ADMIN_ROLE + "' is not permitted to create!");
|
||||||
|
}
|
||||||
rolePersistService.addRole(role, username);
|
rolePersistService.addRole(role, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,6 +206,9 @@ public class NacosRoleServiceImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addPermission(String role, String resource, String action) {
|
public void addPermission(String role, String resource, String action) {
|
||||||
|
if (!roleSet.contains(role)) {
|
||||||
|
throw new IllegalArgumentException("role " + role + " not found!");
|
||||||
|
}
|
||||||
permissionPersistService.addPermission(role, resource, action);
|
permissionPersistService.addPermission(role, resource, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,3 +35,6 @@ nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/
|
|||||||
nacos.core.auth.system.type=nacos
|
nacos.core.auth.system.type=nacos
|
||||||
nacos.core.auth.enabled=false
|
nacos.core.auth.enabled=false
|
||||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
|
||||||
|
|
||||||
|
|
||||||
|
tldSkipPatterns=derbyLocale_*.jar,jaxb-api.jar,jsr173_1.0_api.jar,jaxb1-impl.jar,activation.jar
|
||||||
|
@ -67,7 +67,7 @@ public class AuthFilter implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Loggers.AUTH.isDebugEnabled()) {
|
if (Loggers.AUTH.isDebugEnabled()) {
|
||||||
Loggers.AUTH.debug("auth filter start, request: {}", req.getRequestURI());
|
Loggers.AUTH.debug("auth filter start, request: {} {}", req.getMethod(), req.getRequestURI());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -76,7 +76,8 @@ public class AuthFilter implements Filter {
|
|||||||
Method method = methodsCache.getMethod(req.getMethod(), path);
|
Method method = methodsCache.getMethod(req.getMethod(), path);
|
||||||
|
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
throw new NoSuchMethodException();
|
chain.doFilter(request, response);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method.isAnnotationPresent(Secured.class) && authConfigs.isAuthEnabled()) {
|
if (method.isAnnotationPresent(Secured.class) && authConfigs.isAuthEnabled()) {
|
||||||
@ -95,17 +96,20 @@ public class AuthFilter implements Filter {
|
|||||||
throw new AccessException("resource name invalid!");
|
throw new AccessException("resource name invalid!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Loggers.AUTH.isDebugEnabled()) {
|
||||||
|
Loggers.AUTH.debug("auth now, request: {} {}", req.getMethod(), req.getRequestURI());
|
||||||
|
}
|
||||||
|
|
||||||
authManager.auth(new Permission(resource, action), authManager.login(req));
|
authManager.auth(new Permission(resource, action), authManager.login(req));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (AccessException e) {
|
} catch (AccessException e) {
|
||||||
|
if (Loggers.AUTH.isDebugEnabled()) {
|
||||||
|
Loggers.AUTH.debug("access denied, request: {} {}", req.getMethod(), req.getRequestURI());
|
||||||
|
}
|
||||||
resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getErrMsg());
|
resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getErrMsg());
|
||||||
return;
|
return;
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED,
|
|
||||||
"no such api:" + req.getMethod() + ":" + req.getRequestURI());
|
|
||||||
return;
|
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ExceptionUtil.getAllExceptionMsg(e));
|
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, ExceptionUtil.getAllExceptionMsg(e));
|
||||||
return;
|
return;
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.core.auth;
|
package com.alibaba.nacos.core.auth;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permission to auth
|
* Permission to auth
|
||||||
*
|
*
|
||||||
@ -57,4 +59,9 @@ public class Permission {
|
|||||||
public void setAction(String action) {
|
public void setAction(String action) {
|
||||||
this.action = action;
|
this.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JSON.toJSONString(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +206,7 @@
|
|||||||
<descriptors>
|
<descriptors>
|
||||||
<descriptor>release-nacos.xml</descriptor>
|
<descriptor>release-nacos.xml</descriptor>
|
||||||
</descriptors>
|
</descriptors>
|
||||||
|
<tarLongFileMode>posix</tarLongFileMode>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.alibaba.nacos.test.core.auth;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.nacos.test.base.HttpClient4Test;
|
||||||
|
import com.alibaba.nacos.test.base.Params;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
public class AuthBase extends HttpClient4Test {
|
||||||
|
|
||||||
|
public String login() {
|
||||||
|
|
||||||
|
ResponseEntity<String> response = request("/nacos/v1/auth/users/login",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("username", "nacos")
|
||||||
|
.appendParam("password", "nacos")
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
JSONObject json = JSON.parseObject(response.getBody());
|
||||||
|
Assert.assertTrue(json.containsKey("accessToken"));
|
||||||
|
return json.getString("accessToken");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,271 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.core.auth;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.Nacos;
|
||||||
|
import com.alibaba.nacos.api.NacosFactory;
|
||||||
|
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||||
|
import com.alibaba.nacos.api.config.ConfigChangeEvent;
|
||||||
|
import com.alibaba.nacos.api.config.ConfigChangeItem;
|
||||||
|
import com.alibaba.nacos.api.config.ConfigService;
|
||||||
|
import com.alibaba.nacos.api.config.PropertyChangeType;
|
||||||
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
|
import com.alibaba.nacos.client.config.http.HttpAgent;
|
||||||
|
import com.alibaba.nacos.client.config.listener.impl.AbstractConfigChangeListener;
|
||||||
|
import com.alibaba.nacos.test.base.Params;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author nkorange
|
||||||
|
* @since 1.2.0
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7001"},
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
public class ConfigAuth_ITCase extends AuthBase {
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private String accessToken;
|
||||||
|
|
||||||
|
public static final long TIME_OUT = 2000;
|
||||||
|
|
||||||
|
public ConfigService iconfig = null;
|
||||||
|
|
||||||
|
private String dataId = "yanlin";
|
||||||
|
private String group = "yanlin";
|
||||||
|
|
||||||
|
private String username = "username1";
|
||||||
|
private String password = "password1";
|
||||||
|
private String role = "role1";
|
||||||
|
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
private String namespace1 = "namespace1";
|
||||||
|
private String namespace2 = "namespace2";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() throws Exception {
|
||||||
|
TimeUnit.SECONDS.sleep(5L);
|
||||||
|
String url = String.format("http://localhost:%d/", port);
|
||||||
|
this.base = new URL(url);
|
||||||
|
|
||||||
|
accessToken = login();
|
||||||
|
|
||||||
|
// Create a user:
|
||||||
|
ResponseEntity<String> response = request("/nacos/v1/auth/users",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("password", password)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Create a role:
|
||||||
|
response = request("/nacos/v1/auth/roles",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Add read permission for namespace1:
|
||||||
|
response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace1 + ":*:*")
|
||||||
|
.appendParam("action", "r")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Add read/write permission for namespace2:
|
||||||
|
response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace2 + ":*:*")
|
||||||
|
.appendParam("action", "rw")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Init properties:
|
||||||
|
properties = new Properties();
|
||||||
|
properties.put(PropertyKeyConst.USERNAME, username);
|
||||||
|
properties.put(PropertyKeyConst.PASSWORD, password);
|
||||||
|
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void destroy() {
|
||||||
|
|
||||||
|
// Delete permission:
|
||||||
|
ResponseEntity<String> response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace1 + ":*:*")
|
||||||
|
.appendParam("action", "r")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Delete permission:
|
||||||
|
response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace2 + ":*:*")
|
||||||
|
.appendParam("action", "rw")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Delete a role:
|
||||||
|
response = request("/nacos/v1/auth/roles",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Delete a user:
|
||||||
|
response = request("/nacos/v1/auth/users",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("password", password)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void publishConfigWithReadPermission() throws Exception {
|
||||||
|
|
||||||
|
properties.put(PropertyKeyConst.NAMESPACE, namespace1);
|
||||||
|
// Construct configService:
|
||||||
|
iconfig = NacosFactory.createConfigService(properties);
|
||||||
|
|
||||||
|
final String content = "test";
|
||||||
|
try {
|
||||||
|
iconfig.publishConfig(dataId, group, content);
|
||||||
|
fail();
|
||||||
|
} catch (NacosException ne) {
|
||||||
|
Assert.assertEquals(HttpStatus.FORBIDDEN.value(), ne.getErrCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void publishConfigWithReadWritePermission() throws Exception {
|
||||||
|
|
||||||
|
properties.put(PropertyKeyConst.NAMESPACE, namespace2);
|
||||||
|
// Construct configService:
|
||||||
|
iconfig = NacosFactory.createConfigService(properties);
|
||||||
|
|
||||||
|
final String content = "test";
|
||||||
|
boolean result = iconfig.publishConfig(dataId, group, content);
|
||||||
|
Assert.assertTrue(result);
|
||||||
|
|
||||||
|
TimeUnit.SECONDS.sleep(2L);
|
||||||
|
|
||||||
|
String value = iconfig.getConfig(dataId, group, TIME_OUT);
|
||||||
|
Assert.assertEquals(content, value);
|
||||||
|
|
||||||
|
result = iconfig.removeConfig(dataId, group);
|
||||||
|
Thread.sleep(TIME_OUT);
|
||||||
|
Assert.assertTrue(result);
|
||||||
|
|
||||||
|
TimeUnit.SECONDS.sleep(2L);
|
||||||
|
|
||||||
|
value = iconfig.getConfig(dataId, group, TIME_OUT);
|
||||||
|
System.out.println(value);
|
||||||
|
Assert.assertNull(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void listenConfigWithReadWritePermission() throws Exception {
|
||||||
|
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
final String dataId = "test" + System.currentTimeMillis();
|
||||||
|
final String group = "DEFAULT_GROUP";
|
||||||
|
final String content = "config data";
|
||||||
|
|
||||||
|
properties.put(PropertyKeyConst.NAMESPACE, namespace2);
|
||||||
|
// Construct configService:
|
||||||
|
iconfig = NacosFactory.createConfigService(properties);
|
||||||
|
iconfig.addListener(dataId, group, new AbstractConfigChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void receiveConfigChange(ConfigChangeEvent event) {
|
||||||
|
ConfigChangeItem cci = event.getChangeItem("content");
|
||||||
|
Assert.assertEquals(null, cci.getOldValue());
|
||||||
|
Assert.assertEquals(content, cci.getNewValue());
|
||||||
|
Assert.assertEquals(PropertyChangeType.ADDED, cci.getType());
|
||||||
|
System.out.println(cci);
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
iconfig.publishConfig(dataId, group, content);
|
||||||
|
|
||||||
|
latch.await();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
* 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.test.core.auth;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.Nacos;
|
||||||
|
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||||
|
import com.alibaba.nacos.test.base.Params;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.web.server.LocalServerPort;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author nkorange
|
||||||
|
* @since 1.2.0
|
||||||
|
*/
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest(classes = Nacos.class, properties = {"server.servlet.context-path=/nacos", "server.port=7001"},
|
||||||
|
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||||
|
public class NamingAuth_ITCase extends AuthBase {
|
||||||
|
|
||||||
|
@LocalServerPort
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private String accessToken;
|
||||||
|
|
||||||
|
private String username = "username1";
|
||||||
|
private String password = "password1";
|
||||||
|
private String role = "role1";
|
||||||
|
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
private String namespace1 = "namespace1";
|
||||||
|
private String namespace2 = "namespace2";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
accessToken = login();
|
||||||
|
// Create a user:
|
||||||
|
ResponseEntity<String> response = request("/nacos/v1/auth/users",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("password", password)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Create a role:
|
||||||
|
response = request("/nacos/v1/auth/roles",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Add read permission for namespace1:
|
||||||
|
response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace1 + ":*:*")
|
||||||
|
.appendParam("action", "r")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Add read/write permission for namespace2:
|
||||||
|
response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace2 + ":*:*")
|
||||||
|
.appendParam("action", "rw")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.POST);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Init properties:
|
||||||
|
properties = new Properties();
|
||||||
|
properties.put(PropertyKeyConst.USERNAME, username);
|
||||||
|
properties.put(PropertyKeyConst.PASSWORD, password);
|
||||||
|
properties.put(PropertyKeyConst.SERVER_ADDR, "127.0.0.1" + ":" + port);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void destroy() {
|
||||||
|
|
||||||
|
// Delete permission:
|
||||||
|
ResponseEntity<String> response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace1 + ":*:*")
|
||||||
|
.appendParam("action", "r")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Delete permission:
|
||||||
|
response = request("/nacos/v1/auth/permissions",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("resource", namespace2 + ":*:*")
|
||||||
|
.appendParam("action", "rw")
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Delete a role:
|
||||||
|
response = request("/nacos/v1/auth/roles",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("role", role)
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
|
||||||
|
// Delete a user:
|
||||||
|
response = request("/nacos/v1/auth/users",
|
||||||
|
Params.newParams()
|
||||||
|
.appendParam("username", username)
|
||||||
|
.appendParam("password", password)
|
||||||
|
.appendParam("accessToken", accessToken)
|
||||||
|
.done(),
|
||||||
|
String.class,
|
||||||
|
HttpMethod.DELETE);
|
||||||
|
|
||||||
|
Assert.assertTrue(response.getStatusCode().is2xxSuccessful());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void writeWithReadPermission() {
|
||||||
|
|
||||||
|
properties.put(PropertyKeyConst.NAMESPACE, namespace1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -14,7 +14,7 @@ management.metrics.export.influx.enabled=false
|
|||||||
#management.metrics.export.influx.consistency=one
|
#management.metrics.export.influx.consistency=one
|
||||||
#management.metrics.export.influx.compressed=true
|
#management.metrics.export.influx.compressed=true
|
||||||
|
|
||||||
server.tomcat.accesslog.enabled=false
|
server.tomcat.accesslog.enabled=true
|
||||||
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
|
server.tomcat.accesslog.pattern=%h %l %u %t "%r" %s %b %D
|
||||||
# default current work dir
|
# default current work dir
|
||||||
server.tomcat.basedir=
|
server.tomcat.basedir=
|
||||||
@ -26,7 +26,7 @@ nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/
|
|||||||
nacos.core.auth.system.type=nacos
|
nacos.core.auth.system.type=nacos
|
||||||
|
|
||||||
### If turn on auth system:
|
### If turn on auth system:
|
||||||
nacos.core.auth.enabled=true
|
nacos.core.auth.enabled=false
|
||||||
|
|
||||||
nacos.core.auth.caching.enabled=false
|
nacos.core.auth.caching.enabled=false
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user