⬆️ #2838 up nacos 2.0.2

This commit is contained in:
lbw committed 2021-06-25 16:58:41 +08:00
1 parent 864e0948a3
commit c85bdab9be
154 files changed
+808 -142

No files matched your search

+7 -1
View File
@@ -27,7 +27,7 @@
<description>nacos 注册配置中心</description> <description>nacos 注册配置中心</description>
<properties> <properties>
<nacos.version>1.4.1</nacos.version> <nacos.version>2.0.2</nacos.version>
</properties> </properties>
<dependencies> <dependencies>
@@ -56,6 +56,12 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-system</artifactId>
<version>${hutool.version}</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
@@ -16,7 +16,10 @@
package com.alibaba.nacos; package com.alibaba.nacos;
import cn.hutool.core.lang.Validator;
import cn.hutool.system.SystemUtil;
import com.alibaba.nacos.config.ConfigConstants; import com.alibaba.nacos.config.ConfigConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@@ -26,15 +29,32 @@ import org.springframework.scheduling.annotation.EnableScheduling;
* <p> * <p>
* nacos console 源码运行,方便开发 生产建议从官网下载最新版配置运行 * nacos console 源码运行,方便开发 生产建议从官网下载最新版配置运行
*/ */
@Slf4j
@EnableScheduling @EnableScheduling
@SpringBootApplication @SpringBootApplication
public class PigxNacosApplication { public class PigxNacosApplication {
public static void main(String[] args) { public static void main(String[] args) {
if (initEnv()) {
SpringApplication.run(PigxNacosApplication.class, args);
}
}
/**
* 初始化运行环境
*/
private static boolean initEnv() {
// 特殊处理 window 且用户名包含中文的用户,避免RocksDB 初始化失败
// System.setProperty(SystemUtil.USER_HOME, "不包含中文的路径");
if (SystemUtil.getOsInfo().isWindows() && Validator.hasChinese(SystemUtil.getUserInfo().getHomeDir())) {
log.error("路径包含中文,需要打开以上注释配置指定不包含中文目录");
return false;
}
System.setProperty(ConfigConstants.STANDALONE_MODE, "true"); System.setProperty(ConfigConstants.STANDALONE_MODE, "true");
System.setProperty(ConfigConstants.AUTH_ENABLED, "false"); System.setProperty(ConfigConstants.AUTH_ENABLED, "false");
System.setProperty(ConfigConstants.LOG_BASEDIR, "logs"); System.setProperty(ConfigConstants.LOG_BASEDIR, "logs");
SpringApplication.run(PigxNacosApplication.class, args); return true;
} }
} }
+19 -5
View File
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.config;
import javax.annotation.PostConstruct; package com.alibaba.nacos.config;
import com.alibaba.nacos.core.code.ControllerMethodsCache; import com.alibaba.nacos.core.code.ControllerMethodsCache;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@@ -27,7 +27,12 @@ import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.CorsFilter;
import javax.annotation.PostConstruct;
import java.time.ZoneId;
/** /**
* Console config.
*
* @author yshen * @author yshen
* @author nkorange * @author nkorange
* @since 1.2.0 * @since 1.2.0
@@ -40,24 +45,33 @@ public class ConsoleConfig {
@Autowired @Autowired
private ControllerMethodsCache methodsCache; private ControllerMethodsCache methodsCache;
/**
* Init.
*/
@PostConstruct @PostConstruct
public void init() { public void init() {
methodsCache.initClassMethod("com.alibaba.nacos.core.controller");
methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers"); methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers");
methodsCache.initClassMethod("com.alibaba.nacos.controller");
methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller"); methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller");
methodsCache.initClassMethod("com.alibaba.nacos.controller");
} }
@Bean @Bean
public CorsFilter corsFilter() { public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration(); CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); config.setAllowCredentials(true);
config.addAllowedOriginPattern("*"); config.addAllowedOrigin("*");
config.addAllowedHeader("*"); config.addAllowedHeader("*");
config.setMaxAge(18000L); config.setMaxAge(18000L);
config.addAllowedMethod("*"); config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); source.registerCorsConfiguration("/**", config);
return new CorsFilter(source); return new CorsFilter(source);
} }
@Bean
public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(ZoneId.systemDefault().toString());
}
} }
+9 -8
View File
@@ -16,19 +16,19 @@
package com.alibaba.nacos.controller; package com.alibaba.nacos.controller;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.config.server.service.repository.PersistService;
import com.alibaba.nacos.naming.controllers.OperatorController; import com.alibaba.nacos.naming.controllers.OperatorController;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/** /**
* Health Controller. * Health Controller.
* *
@@ -57,7 +57,7 @@ public class HealthController {
* equal to 500 indicates that Nacos is in broken states. * equal to 500 indicates that Nacos is in broken states.
*/ */
@GetMapping("/liveness") @GetMapping("/liveness")
public ResponseEntity liveness() { public ResponseEntity<String> liveness() {
return ResponseEntity.ok().body("OK"); return ResponseEntity.ok().body("OK");
} }
@@ -67,7 +67,7 @@ public class HealthController {
* 500 indicates that Nacos is not ready. * 500 indicates that Nacos is not ready.
*/ */
@GetMapping("/readiness") @GetMapping("/readiness")
public ResponseEntity readiness(HttpServletRequest request) { public ResponseEntity<String> readiness(HttpServletRequest request) {
boolean isConfigReadiness = isConfigReadiness(); boolean isConfigReadiness = isConfigReadiness();
boolean isNamingReadiness = isNamingReadiness(request); boolean isNamingReadiness = isNamingReadiness(request);
@@ -76,14 +76,15 @@ public class HealthController {
} }
if (!isConfigReadiness && !isNamingReadiness) { if (!isConfigReadiness && !isNamingReadiness) {
return ResponseEntity.status(500).body("Config and Naming are not in readiness"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Config and Naming are not in readiness");
} }
if (!isConfigReadiness) { if (!isConfigReadiness) {
return ResponseEntity.status(500).body("Config is not in readiness"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config is not in readiness");
} }
return ResponseEntity.status(500).body("Naming is not in readiness"); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Naming is not in readiness");
} }
private boolean isConfigReadiness() { private boolean isConfigReadiness() {
+40 -32
View File
@@ -16,31 +16,26 @@
package com.alibaba.nacos.controller; package com.alibaba.nacos.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.nacos.auth.annotation.Secured; import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.auth.common.ActionTypes; import com.alibaba.nacos.auth.common.ActionTypes;
import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.config.server.model.TenantInfo; import com.alibaba.nacos.config.server.model.TenantInfo;
import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.config.server.service.repository.PersistService;
import com.alibaba.nacos.enums.NamespaceTypeEnum;
import com.alibaba.nacos.model.Namespace; import com.alibaba.nacos.model.Namespace;
import com.alibaba.nacos.model.NamespaceAllInfo; import com.alibaba.nacos.model.NamespaceAllInfo;
import com.alibaba.nacos.security.nacos.NacosAuthConfig; import com.alibaba.nacos.security.nacos.NacosAuthConfig;
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.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.PutMapping; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping; import java.util.ArrayList;
import org.springframework.web.bind.annotation.RequestParam; import java.util.List;
import org.springframework.web.bind.annotation.RestController; import java.util.UUID;
import java.util.regex.Pattern;
/** /**
* namespace service. * namespace service.
@@ -58,6 +53,20 @@ public class NamespaceController {
private static final int NAMESPACE_ID_MAX_LENGTH = 128; private static final int NAMESPACE_ID_MAX_LENGTH = 128;
private static final String DEFAULT_NAMESPACE = "public";
private static final int DEFAULT_QUOTA = 200;
private static final String DEFAULT_CREATE_SOURCE = "nacos";
private static final String DEFAULT_NAMESPACE_SHOW_NAME = "Public";
private static final String DEFAULT_NAMESPACE_DESCRIPTION = "Public Namespace";
private static final String DEFAULT_TENANT = "";
private static final String DEFAULT_KP = "1";
/** /**
* Get namespace list. * Get namespace list.
* @param request request * @param request request
@@ -66,21 +75,19 @@ public class NamespaceController {
*/ */
@GetMapping @GetMapping
public RestResult<List<Namespace>> getNamespaces(HttpServletRequest request, HttpServletResponse response) { public RestResult<List<Namespace>> getNamespaces(HttpServletRequest request, HttpServletResponse response) {
RestResult<List<Namespace>> rr = new RestResult<List<Namespace>>();
rr.setCode(200);
// TODO 获取用kp // TODO 获取用kp
List<TenantInfo> tenantInfos = persistService.findTenantByKp("1"); List<TenantInfo> tenantInfos = persistService.findTenantByKp(DEFAULT_KP);
Namespace namespace0 = new Namespace("", "public", 200, persistService.configInfoCount(""), 0); Namespace namespace0 = new Namespace("", DEFAULT_NAMESPACE, DEFAULT_QUOTA,
persistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType());
List<Namespace> namespaces = new ArrayList<Namespace>(); List<Namespace> namespaces = new ArrayList<Namespace>();
namespaces.add(namespace0); namespaces.add(namespace0);
for (TenantInfo tenantInfo : tenantInfos) { for (TenantInfo tenantInfo : tenantInfos) {
int configCount = persistService.configInfoCount(tenantInfo.getTenantId()); int configCount = persistService.configInfoCount(tenantInfo.getTenantId());
Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(), 200, Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(), DEFAULT_QUOTA,
configCount, 2); configCount, NamespaceTypeEnum.CUSTOM.getType());
namespaces.add(namespaceTmp); namespaces.add(namespaceTmp);
} }
rr.setData(namespaces); return RestResultUtils.success(namespaces);
return rr;
} }
/** /**
@@ -95,14 +102,15 @@ public class NamespaceController {
@RequestParam("namespaceId") String namespaceId) { @RequestParam("namespaceId") String namespaceId) {
// TODO 获取用kp // TODO 获取用kp
if (StringUtils.isBlank(namespaceId)) { if (StringUtils.isBlank(namespaceId)) {
return new NamespaceAllInfo(namespaceId, "Public", 200, persistService.configInfoCount(""), 0, return new NamespaceAllInfo(namespaceId, DEFAULT_NAMESPACE_SHOW_NAME, DEFAULT_QUOTA,
"Public Namespace"); persistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType(),
DEFAULT_NAMESPACE_DESCRIPTION);
} }
else { else {
TenantInfo tenantInfo = persistService.findTenantByKp("1", namespaceId); TenantInfo tenantInfo = persistService.findTenantByKp(DEFAULT_KP, namespaceId);
int configCount = persistService.configInfoCount(namespaceId); int configCount = persistService.configInfoCount(namespaceId);
return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200, configCount, 2, return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), DEFAULT_QUOTA, configCount,
tenantInfo.getTenantDesc()); NamespaceTypeEnum.CUSTOM.getType(), tenantInfo.getTenantDesc());
} }
} }
@@ -135,8 +143,8 @@ public class NamespaceController {
return false; return false;
} }
} }
persistService.insertTenantInfoAtomic("1", namespaceId, namespaceName, namespaceDesc, "nacos", persistService.insertTenantInfoAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc,
System.currentTimeMillis()); DEFAULT_CREATE_SOURCE, System.currentTimeMillis());
return true; return true;
} }
@@ -166,7 +174,7 @@ public class NamespaceController {
@RequestParam("namespaceShowName") String namespaceShowName, @RequestParam("namespaceShowName") String namespaceShowName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// TODO 获取用kp // TODO 获取用kp
persistService.updateTenantNameAtomic("1", namespace, namespaceShowName, namespaceDesc); persistService.updateTenantNameAtomic(DEFAULT_KP, namespace, namespaceShowName, namespaceDesc);
return true; return true;
} }
@@ -181,7 +189,7 @@ public class NamespaceController {
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response, public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) { @RequestParam("namespaceId") String namespaceId) {
persistService.removeTenantInfoAtomic("1", namespaceId); persistService.removeTenantInfoAtomic(DEFAULT_KP, namespaceId);
return true; return true;
} }
@@ -18,7 +18,7 @@ package com.alibaba.nacos.controller;
import com.alibaba.nacos.auth.annotation.Secured; import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.auth.common.ActionTypes; import com.alibaba.nacos.auth.common.ActionTypes;
import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.security.nacos.NacosAuthConfig; import com.alibaba.nacos.security.nacos.NacosAuthConfig;
import com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl; import com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -68,7 +68,7 @@ public class PermissionController {
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE) @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
public Object addPermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) { public Object addPermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) {
nacosRoleService.addPermission(role, resource, action); nacosRoleService.addPermission(role, resource, action);
return new RestResult<>(200, "add permission ok!"); return RestResultUtils.success("add permission ok!");
} }
/** /**
@@ -83,7 +83,7 @@ public class PermissionController {
public Object deletePermission(@RequestParam String role, @RequestParam String resource, public Object deletePermission(@RequestParam String role, @RequestParam String resource,
@RequestParam String action) { @RequestParam String action) {
nacosRoleService.deletePermission(role, resource, action); nacosRoleService.deletePermission(role, resource, action);
return new RestResult<>(200, "delete permission ok!"); return RestResultUtils.success("delete permission ok!");
} }
} }
+3 -3
View File
@@ -18,7 +18,7 @@ package com.alibaba.nacos.controller;
import com.alibaba.nacos.auth.annotation.Secured; import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.auth.common.ActionTypes; import com.alibaba.nacos.auth.common.ActionTypes;
import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.security.nacos.NacosAuthConfig; import com.alibaba.nacos.security.nacos.NacosAuthConfig;
import com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl; import com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -84,7 +84,7 @@ public class RoleController {
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE) @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
public Object addRole(@RequestParam String role, @RequestParam String username) { public Object addRole(@RequestParam String role, @RequestParam String username) {
roleService.addRole(role, username); roleService.addRole(role, username);
return new RestResult<>(200, "add role ok!"); return RestResultUtils.success("add role ok!");
} }
/** /**
@@ -103,7 +103,7 @@ public class RoleController {
else { else {
roleService.deleteRole(role, username); roleService.deleteRole(role, username);
} }
return new RestResult<>(200, "delete role of user " + username + " ok!"); return RestResultUtils.success("delete role of user " + username + " ok!");
} }
} }
@@ -40,8 +40,8 @@ public class ServerStateController {
* @return state json. * @return state json.
*/ */
@GetMapping("/state") @GetMapping("/state")
public ResponseEntity serverState() { public ResponseEntity<Map<String, String>> serverState() {
Map<String, String> serverState = new HashMap<>(3); Map<String, String> serverState = new HashMap<>(4);
serverState.put("standalone_mode", serverState.put("standalone_mode",
EnvUtil.getStandaloneMode() ? EnvUtil.STANDALONE_MODE_ALONE : EnvUtil.STANDALONE_MODE_CLUSTER); EnvUtil.getStandaloneMode() ? EnvUtil.STANDALONE_MODE_ALONE : EnvUtil.STANDALONE_MODE_CLUSTER);
+25 -36
View File
@@ -16,12 +16,6 @@
package com.alibaba.nacos.controller; package com.alibaba.nacos.controller;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.auth.annotation.Secured; import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.auth.common.ActionTypes; import com.alibaba.nacos.auth.common.ActionTypes;
@@ -29,6 +23,7 @@ import com.alibaba.nacos.auth.common.AuthConfigs;
import com.alibaba.nacos.auth.common.AuthSystemTypes; import com.alibaba.nacos.auth.common.AuthSystemTypes;
import com.alibaba.nacos.auth.exception.AccessException; import com.alibaba.nacos.auth.exception.AccessException;
import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.model.RestResultUtils;
import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.Objects; import com.alibaba.nacos.common.utils.Objects;
import com.alibaba.nacos.config.server.auth.RoleInfo; import com.alibaba.nacos.config.server.auth.RoleInfo;
@@ -42,8 +37,8 @@ import com.alibaba.nacos.security.nacos.users.NacosUser;
import com.alibaba.nacos.security.nacos.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.security.nacos.users.NacosUserDetailsServiceImpl;
import com.alibaba.nacos.utils.PasswordEncoderUtil; import com.alibaba.nacos.utils.PasswordEncoderUtil;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -58,6 +53,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/** /**
* User related methods entry. * User related methods entry.
* *
@@ -103,7 +103,7 @@ public class UserController {
throw new IllegalArgumentException("user '" + username + "' already exist!"); throw new IllegalArgumentException("user '" + username + "' already exist!");
} }
userDetailsService.createUser(username, PasswordEncoderUtil.encode(password)); userDetailsService.createUser(username, PasswordEncoderUtil.encode(password));
return new RestResult<>(200, "create user ok!"); return RestResultUtils.success("create user ok!");
} }
/** /**
@@ -124,7 +124,7 @@ public class UserController {
} }
} }
userDetailsService.deleteUser(username); userDetailsService.deleteUser(username);
return new RestResult<>(200, "delete user ok!"); return RestResultUtils.success("delete user ok!");
} }
/** /**
@@ -153,7 +153,7 @@ public class UserController {
userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword)); userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
return new RestResult<>(200, "update user ok!"); return RestResultUtils.success("update user ok!");
} }
private boolean hasPermission(String username, HttpServletRequest request) { private boolean hasPermission(String username, HttpServletRequest request) {
@@ -202,42 +202,39 @@ public class UserController {
public Object login(@RequestParam String username, @RequestParam String password, HttpServletResponse response, public Object login(@RequestParam String username, @RequestParam String password, HttpServletResponse response,
HttpServletRequest request) throws AccessException { HttpServletRequest request) throws AccessException {
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())
|| AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
NacosUser user = (NacosUser) authManager.login(request); NacosUser user = (NacosUser) authManager.login(request);
response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, NacosAuthConfig.TOKEN_PREFIX + user.getToken()); response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, NacosAuthConfig.TOKEN_PREFIX + user.getToken());
ObjectNode result = JacksonUtils.createEmptyJsonNode(); ObjectNode result = JacksonUtils.createEmptyJsonNode();
// JSONObject result = new JSONObject();
result.put(Constants.ACCESS_TOKEN, user.getToken()); result.put(Constants.ACCESS_TOKEN, user.getToken());
result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds()); result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin()); result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
result.put(Constants.USERNAME, user.getUserName());
return result; return result;
} }
// 通过用户名和密码创建一个 Authentication 认证对象,实现类为 UsernamePasswordAuthenticationToken // create Authentication class through username and password, the implement class
// is UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
password); password);
RestResult<String> rr = new RestResult<String>();
try { try {
// 通过 AuthenticationManager(默认实现为ProviderManager)的authenticate方法验证 // use the method authenticate of AuthenticationManager(default implement is
// Authentication 对象 // ProviderManager) to valid Authentication
Authentication authentication = authenticationManager.authenticate(authenticationToken); Authentication authentication = authenticationManager.authenticate(authenticationToken);
// 将 Authentication 绑定到 SecurityContext // bind SecurityContext to Authentication
SecurityContextHolder.getContext().setAuthentication(authentication); SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成Token // generate Token
String token = jwtTokenManager.createToken(authentication); String token = jwtTokenManager.createToken(authentication);
// 将Token写入到Http头部 // write Token to Http header
response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token); response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token);
rr.setCode(200); return RestResultUtils.success("Bearer " + token);
rr.setData("Bearer " + token);
return rr;
} }
catch (BadCredentialsException authentication) { catch (BadCredentialsException authentication) {
rr.setCode(401); return RestResultUtils.failed(HttpStatus.UNAUTHORIZED.value(), null, "Login failed");
rr.setMessage("Login failed");
return rr;
} }
} }
@@ -252,8 +249,6 @@ public class UserController {
@Deprecated @Deprecated
public RestResult<String> updatePassword(@RequestParam(value = "oldPassword") String oldPassword, public RestResult<String> updatePassword(@RequestParam(value = "oldPassword") String oldPassword,
@RequestParam(value = "newPassword") String newPassword) { @RequestParam(value = "newPassword") String newPassword) {
RestResult<String> rr = new RestResult<String>();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = ((UserDetails) principal).getUsername(); String username = ((UserDetails) principal).getUsername();
User user = userDetailsService.getUserFromDatabase(username); User user = userDetailsService.getUserFromDatabase(username);
@@ -263,19 +258,13 @@ public class UserController {
try { try {
if (PasswordEncoderUtil.matches(oldPassword, password)) { if (PasswordEncoderUtil.matches(oldPassword, password)) {
userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword)); userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
rr.setCode(200); return RestResultUtils.success("Update password success");
rr.setMessage("Update password success");
}
else {
rr.setCode(401);
rr.setMessage("Old password is invalid");
} }
return RestResultUtils.failed(HttpStatus.UNAUTHORIZED.value(), "Old password is invalid");
} }
catch (Exception e) { catch (Exception e) {
rr.setCode(500); return RestResultUtils.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Update userpassword failed");
rr.setMessage("Update userpassword failed");
} }
return rr;
} }
/** /**
@@ -0,0 +1,66 @@
/*
* 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.enums;
/**
* the enum of namespace. 0 : Global configuration, 1 : Default private namespace ,2 :
* Custom namespace.
*
* @author chenglu
* @date 2021-05-25 17:01
*/
public enum NamespaceTypeEnum {
/**
* Global configuration.
*/
GLOBAL(0, "Global configuration"),
/**
* Default private namespace.
*/
PRIVATE(1, "Default private namespace"),
/**
* Custom namespace.
*/
CUSTOM(2, "Custom namespace");
/**
* the namespace type.
*/
private final int type;
/**
* the description.
*/
private final String description;
NamespaceTypeEnum(int type, String description) {
this.type = type;
this.description = description;
}
public int getType() {
return type;
}
public String getDescription() {
return description;
}
}
File mode changed.
@@ -65,7 +65,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private String resolveToken(HttpServletRequest request) { private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER); String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) { if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7); return bearerToken.substring(TOKEN_PREFIX.length());
} }
String jwt = request.getParameter(Constants.ACCESS_TOKEN); String jwt = request.getParameter(Constants.ACCESS_TOKEN);
if (StringUtils.isNotBlank(jwt)) { if (StringUtils.isNotBlank(jwt)) {
+1 -1
View File
@@ -32,7 +32,7 @@ public class Namespace {
private int configCount; private int configCount;
/** /**
* 0 : Global configuration, 1 : Default private namespace ,2 : Custom namespace. * see {@link com.alibaba.nacos.console.enums.NamespaceTypeEnum}.
*/ */
private int type; private int type;
File mode changed.
File mode changed.
File mode changed.
File mode changed.
@@ -0,0 +1,172 @@
/*
* 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.security.nacos;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.config.server.auth.RoleInfo;
import com.alibaba.nacos.config.server.model.User;
import com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl;
import com.alibaba.nacos.security.nacos.users.NacosUserDetails;
import com.alibaba.nacos.security.nacos.users.NacosUserDetailsServiceImpl;
import com.alibaba.nacos.utils.PasswordEncoderUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.directory.DirContext;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import java.util.Hashtable;
import java.util.List;
import static com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE;
/**
* LDAP auth provider.
*
* @author zjw
*/
@Component
public class LdapAuthenticationProvider implements AuthenticationProvider {
private static final Logger LOG = LoggerFactory.getLogger(LdapAuthenticationProvider.class);
private static final String FACTORY = "com.sun.jndi.ldap.LdapCtxFactory";
private static final String TIMEOUT = "com.sun.jndi.ldap.connect.timeout";
private static final String DEFAULT_PASSWORD = "nacos";
private static final String LDAP_PREFIX = "LDAP_";
private static final String DEFAULT_SECURITY_AUTH = "simple";
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private NacosRoleServiceImpl nacosRoleService;
@Value(("${nacos.core.auth.ldap.url:ldap://localhost:389}"))
private String ldapUrl;
@Value(("${nacos.core.auth.ldap.timeout:3000}"))
private String time;
@Value(("${nacos.core.auth.ldap.userdn:cn={0},ou=user,dc=company,dc=com}"))
private String userNamePattern;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
if (isAdmin(username)) {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (PasswordEncoderUtil.matches(password, userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
}
else {
return null;
}
}
if (!ldapLogin(username, password)) {
return null;
}
UserDetails userDetails;
try {
userDetails = userDetailsService.loadUserByUsername(LDAP_PREFIX + username);
}
catch (UsernameNotFoundException exception) {
String nacosPassword = PasswordEncoderUtil.encode(DEFAULT_PASSWORD);
userDetailsService.createUser(LDAP_PREFIX + username, nacosPassword);
User user = new User();
user.setUsername(LDAP_PREFIX + username);
user.setPassword(nacosPassword);
userDetails = new NacosUserDetails(user);
}
return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
}
private boolean isAdmin(String username) {
List<RoleInfo> roleInfos = nacosRoleService.getRoles(username);
if (CollectionUtils.isEmpty(roleInfos)) {
return false;
}
for (RoleInfo roleinfo : roleInfos) {
if (GLOBAL_ADMIN_ROLE.equals(roleinfo.getRole())) {
return true;
}
}
return false;
}
private boolean ldapLogin(String username, String password) throws AuthenticationException {
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
env.put(Context.PROVIDER_URL, ldapUrl);
env.put(Context.SECURITY_AUTHENTICATION, DEFAULT_SECURITY_AUTH);
env.put(Context.SECURITY_PRINCIPAL, userNamePattern.replace("{0}", username));
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(TIMEOUT, time);
LdapContext ctx = null;
try {
ctx = new InitialLdapContext(env, null);
}
catch (CommunicationException e) {
throw new RuntimeException("LDAP Service connect timeout");
}
catch (Exception e) {
LOG.warn("Exception cause by:{}", e.getMessage());
return false;
}
finally {
closeContext(ctx);
}
return true;
}
@Override
public boolean supports(Class<?> aClass) {
return aClass.equals(UsernamePasswordAuthenticationToken.class);
}
private void closeContext(DirContext ctx) {
if (ctx != null) {
try {
ctx.close();
}
catch (Exception e) {
LOG.error("Exception closing context", e);
}
}
}
}
+24 -17
View File
@@ -59,6 +59,10 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
public static final String UPDATE_PASSWORD_ENTRY_POINT = CONSOLE_RESOURCE_NAME_PREFIX + "user/password"; public static final String UPDATE_PASSWORD_ENTRY_POINT = CONSOLE_RESOURCE_NAME_PREFIX + "user/password";
private static final String DEFAULT_ALL_PATH_PATTERN = "/**";
private static final String PROPERTY_IGNORE_URLS = "nacos.security.ignore.urls";
@Autowired @Autowired
private Environment env; private Environment env;
@@ -71,6 +75,9 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
@Autowired @Autowired
private NacosUserDetailsServiceImpl userDetailsService; private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private LdapAuthenticationProvider ldapAuthenticationProvider;
@Bean(name = BeanIds.AUTHENTICATION_MANAGER) @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override @Override
public AuthenticationManager authenticationManagerBean() throws Exception { public AuthenticationManager authenticationManagerBean() throws Exception {
@@ -82,10 +89,13 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
String ignoreUrls = null; String ignoreUrls = null;
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
ignoreUrls = "/**"; ignoreUrls = DEFAULT_ALL_PATH_PATTERN;
}
else if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
ignoreUrls = DEFAULT_ALL_PATH_PATTERN;
} }
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
ignoreUrls = env.getProperty("nacos.security.ignore.urls", "/**"); ignoreUrls = env.getProperty(PROPERTY_IGNORE_URLS, DEFAULT_ALL_PATH_PATTERN);
} }
if (StringUtils.isNotBlank(ignoreUrls)) { if (StringUtils.isNotBlank(ignoreUrls)) {
for (String each : ignoreUrls.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) { for (String each : ignoreUrls.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
@@ -96,27 +106,24 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
else if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
auth.authenticationProvider(ldapAuthenticationProvider);
}
} }
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
http http.csrf().disable().cors()// We don't need CSRF for JWT based authentication
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.csrf().disable().cors() // We don't need CSRF for JWT based .authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
// authentication .antMatchers(LOGIN_ENTRY_POINT).permitAll().and().authorizeRequests()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated().and().exceptionHandling()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .authenticationEntryPoint(new JwtAuthenticationEntryPoint());
.and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.antMatchers(LOGIN_ENTRY_POINT).permitAll()
.and().authorizeRequests().antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and().exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint());
// disable cache // disable cache
http.headers().cacheControl(); http.headers().cacheControl();
@@ -17,15 +17,16 @@
package com.alibaba.nacos.security.nacos; package com.alibaba.nacos.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.auth.AuthManager; import com.alibaba.nacos.auth.AuthManager;
import com.alibaba.nacos.auth.exception.AccessException; import com.alibaba.nacos.auth.exception.AccessException;
import com.alibaba.nacos.auth.model.Permission; import com.alibaba.nacos.auth.model.Permission;
import com.alibaba.nacos.auth.model.User; import com.alibaba.nacos.auth.model.User;
import com.alibaba.nacos.config.server.auth.RoleInfo; import com.alibaba.nacos.config.server.auth.RoleInfo;
import com.alibaba.nacos.config.server.utils.RequestUtil; import com.alibaba.nacos.config.server.utils.RequestUtil;
import com.alibaba.nacos.core.utils.Loggers;
import com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl; import com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl;
import com.alibaba.nacos.security.nacos.users.NacosUser; import com.alibaba.nacos.security.nacos.users.NacosUser;
import com.alibaba.nacos.core.utils.Loggers;
import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.ExpiredJwtException;
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;
@@ -50,6 +51,10 @@ public class NacosAuthManager implements AuthManager {
private static final String TOKEN_PREFIX = "Bearer "; private static final String TOKEN_PREFIX = "Bearer ";
private static final String PARAM_USERNAME = "username";
private static final String PARAM_PASSWORD = "password";
@Autowired @Autowired
private JwtTokenManager tokenManager; private JwtTokenManager tokenManager;
@@ -97,6 +102,43 @@ public class NacosAuthManager implements AuthManager {
return user; return user;
} }
@Override
public User loginRemote(Object request) throws AccessException {
Request req = (Request) request;
String token = resolveToken(req);
if (StringUtils.isBlank(token)) {
throw new AccessException("user not found!");
}
try {
tokenManager.validateToken(token);
}
catch (ExpiredJwtException e) {
throw new AccessException("token expired!");
}
catch (Exception e) {
throw new AccessException("token invalid!");
}
Authentication authentication = tokenManager.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
String username = authentication.getName();
NacosUser user = new NacosUser();
user.setUserName(username);
user.setToken(token);
List<RoleInfo> roleInfoList = roleService.getRoles(username);
if (roleInfoList != null) {
for (RoleInfo roleInfo : roleInfoList) {
if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) {
user.setGlobalAdmin(true);
break;
}
}
}
return user;
}
@Override @Override
public void auth(Permission permission, User user) throws AccessException { public void auth(Permission permission, User user) throws AccessException {
if (Loggers.AUTH.isDebugEnabled()) { if (Loggers.AUTH.isDebugEnabled()) {
@@ -118,8 +160,26 @@ public class NacosAuthManager implements AuthManager {
} }
bearerToken = request.getParameter(Constants.ACCESS_TOKEN); bearerToken = request.getParameter(Constants.ACCESS_TOKEN);
if (StringUtils.isBlank(bearerToken)) { if (StringUtils.isBlank(bearerToken)) {
String userName = request.getParameter("username"); String userName = request.getParameter(PARAM_USERNAME);
String password = request.getParameter("password"); String password = request.getParameter(PARAM_PASSWORD);
bearerToken = resolveTokenFromUser(userName, password);
}
return bearerToken;
}
/**
* Get token from header.
*/
private String resolveToken(Request request) throws AccessException {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7);
}
bearerToken = request.getHeader(Constants.ACCESS_TOKEN);
if (StringUtils.isBlank(bearerToken)) {
String userName = request.getHeader(PARAM_USERNAME);
String password = request.getHeader(PARAM_PASSWORD);
bearerToken = resolveTokenFromUser(userName, password); bearerToken = resolveTokenFromUser(userName, password);
} }
@@ -127,17 +187,25 @@ public class NacosAuthManager implements AuthManager {
} }
private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException { private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException {
String finalName;
Authentication authenticate;
try { try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName,
rawPassword); rawPassword);
authenticationManager.authenticate(authenticationToken); authenticate = authenticationManager.authenticate(authenticationToken);
} }
catch (AuthenticationException e) { catch (AuthenticationException e) {
throw new AccessException("unknown user!"); throw new AccessException("unknown user!");
} }
return tokenManager.createToken(userName); if (null == authenticate || StringUtils.isBlank(authenticate.getName())) {
finalName = userName;
}
else {
finalName = authenticate.getName();
}
return tokenManager.createToken(finalName);
} }
} }
@@ -23,9 +23,9 @@ import com.alibaba.nacos.config.server.auth.PermissionPersistService;
import com.alibaba.nacos.config.server.auth.RoleInfo; import com.alibaba.nacos.config.server.auth.RoleInfo;
import com.alibaba.nacos.config.server.auth.RolePersistService; import com.alibaba.nacos.config.server.auth.RolePersistService;
import com.alibaba.nacos.config.server.model.Page; import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.core.utils.Loggers;
import com.alibaba.nacos.security.nacos.NacosAuthConfig; import com.alibaba.nacos.security.nacos.NacosAuthConfig;
import com.alibaba.nacos.security.nacos.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.security.nacos.users.NacosUserDetailsServiceImpl;
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.apache.mina.util.ConcurrentHashSet;
@@ -52,6 +52,8 @@ public class NacosRoleServiceImpl {
public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN"; public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN";
private static final int DEFAULT_PAGE_NO = 1;
@Autowired @Autowired
private AuthConfigs authConfigs; private AuthConfigs authConfigs;
@@ -73,7 +75,7 @@ public class NacosRoleServiceImpl {
@Scheduled(initialDelay = 5000, fixedDelay = 15000) @Scheduled(initialDelay = 5000, fixedDelay = 15000)
private void reload() { private void reload() {
try { try {
Page<RoleInfo> roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, 1, Page<RoleInfo> roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, DEFAULT_PAGE_NO,
Integer.MAX_VALUE); Integer.MAX_VALUE);
if (roleInfoPage == null) { if (roleInfoPage == null) {
return; return;
@@ -90,7 +92,7 @@ public class NacosRoleServiceImpl {
Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16); Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
for (String role : tmpRoleSet) { for (String role : tmpRoleSet) {
Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1, Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, DEFAULT_PAGE_NO,
Integer.MAX_VALUE); Integer.MAX_VALUE);
tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems()); tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
} }
@@ -158,7 +160,7 @@ public class NacosRoleServiceImpl {
public List<RoleInfo> getRoles(String username) { public List<RoleInfo> getRoles(String username) {
List<RoleInfo> roleInfoList = roleInfoMap.get(username); List<RoleInfo> roleInfoList = roleInfoMap.get(username);
if (!authConfigs.isCachingEnabled()) { if (!authConfigs.isCachingEnabled()) {
Page<RoleInfo> roleInfoPage = getRolesFromDatabase(username, 1, Integer.MAX_VALUE); Page<RoleInfo> roleInfoPage = getRolesFromDatabase(username, DEFAULT_PAGE_NO, Integer.MAX_VALUE);
if (roleInfoPage != null) { if (roleInfoPage != null) {
roleInfoList = roleInfoPage.getPageItems(); roleInfoList = roleInfoPage.getPageItems();
} }
@@ -177,7 +179,8 @@ public class NacosRoleServiceImpl {
public List<PermissionInfo> getPermissions(String role) { public List<PermissionInfo> getPermissions(String role) {
List<PermissionInfo> permissionInfoList = permissionInfoMap.get(role); List<PermissionInfo> permissionInfoList = permissionInfoMap.get(role);
if (!authConfigs.isCachingEnabled()) { if (!authConfigs.isCachingEnabled()) {
Page<PermissionInfo> permissionInfoPage = getPermissionsFromDatabase(role, 1, Integer.MAX_VALUE); Page<PermissionInfo> permissionInfoPage = getPermissionsFromDatabase(role, DEFAULT_PAGE_NO,
Integer.MAX_VALUE);
if (permissionInfoPage != null) { if (permissionInfoPage != null) {
permissionInfoList = permissionInfoPage.getPageItems(); permissionInfoList = permissionInfoPage.getPageItems();
} }
File mode changed.
File mode changed.
@@ -25,10 +25,6 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
*/ */
public class PasswordEncoderUtil { public class PasswordEncoderUtil {
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("nacos"));
}
public static Boolean matches(String raw, String encoded) { public static Boolean matches(String raw, String encoded) {
return new BCryptPasswordEncoder().matches(raw, encoded); return new BCryptPasswordEncoder().matches(raw, encoded);
} }
+8 -12
View File
@@ -5,11 +5,12 @@ server:
db: db:
num: 1 num: 1
user: ${MYSQL_USER:root} user: ${MYSQL-USER:root}
password: ${MYSQL_PWD:root} password: ${MYSQL-PWD:root}
url: url:
0: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_config}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true 0: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_config}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
nacos: nacos:
core: core:
auth: auth:
@@ -20,20 +21,20 @@ nacos:
urls: /,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/** urls: /,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/v1/auth/**,/v1/console/health/**,/actuator/**,/v1/console/server/**
spring: spring:
application:
name: @artifactId@
datasource: datasource:
platform: mysql platform: mysql #这个过期属性不能修改,nacos 代码对此有硬编码
security: security:
enabled: true enabled: true
boot: # 接入 spring boot admin boot: # 接入 spring boot admin
admin: admin:
client: client:
url: http://pigx-monitor:5001 url: http://pigx-monitor:5001
username: pigx username: pig
password: pigx password: pig
instance: instance:
prefer-ip: true prefer-ip: true
application:
name: @project.artifactId@
useAddressServer: true useAddressServer: true
@@ -48,8 +49,3 @@ management:
enabled: false enabled: false
elastic: elastic:
enabled: false enabled: false
# 屏蔽scanner warning 日志
logging:
level:
org.apache.tomcat.util.scan.StandardJarScanner: ERROR
View File
File mode changed.
File mode changed.
File mode changed.
View File
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
View File
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

File mode changed.
File mode changed.
File mode changed.

Before

Width:  |  Height:  |  Size: 114 B

After

Width:  |  Height:  |  Size: 114 B

File mode changed.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

File mode changed.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

File mode changed.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

File mode changed.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
View File
File mode changed.
View File
File mode changed.
View File
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
File mode changed.
Loaded 100 of 154 files, more files were not shown because too many files have changed in this diff. Show more