🎨 改进结构和代码格式. add spring-javaformat plugin and format all code

This commit is contained in:
lengleng committed 2020-06-14 17:59:04 +08:00
1 parent 5414983f3d
commit bd47066299
651 files changed
+13034 -12462

No files matched your search

@@ -24,8 +24,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author nacos
* <p>
* nacos console 源码运行,方便开发
* 生产建议从官网下载最新版配置运行
* nacos console 源码运行,方便开发 生产建议从官网下载最新版配置运行
*/
@EnableScheduling
@SpringBootApplication
@@ -36,4 +35,5 @@ public class PigxNacosApplication {
System.setProperty(ConfigConstants.AUTH_ENABLED, "false");
SpringApplication.run(PigxNacosApplication.class, args);
}
}
@@ -24,8 +24,9 @@ package com.alibaba.nacos.console.config;
* 覆盖nacos 默认配置
*/
public interface ConfigConstants {
/**
* The System property name of Standalone mode
* The System property name of Standalone mode
*/
String STANDALONE_MODE = "nacos.standalone";
@@ -33,4 +34,5 @@ public interface ConfigConstants {
* 是否开启认证
*/
String AUTH_ENABLED = "nacos.core.auth.enabled";
}
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.console.config;
import com.alibaba.nacos.core.code.ControllerMethodsCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -38,26 +37,27 @@ import javax.annotation.PostConstruct;
@PropertySource("/application.properties")
public class ConsoleConfig {
@Autowired
private ControllerMethodsCache methodsCache;
@Autowired
private ControllerMethodsCache methodsCache;
@PostConstruct
public void init() {
methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers");
methodsCache.initClassMethod("com.alibaba.nacos.console.controller");
methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller");
}
@PostConstruct
public void init() {
methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers");
methodsCache.initClassMethod("com.alibaba.nacos.console.controller");
methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller");
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setMaxAge(18000L);
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.setMaxAge(18000L);
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
@@ -34,72 +34,75 @@ import javax.servlet.http.HttpServletRequest;
@RequestMapping("/v1/console/health")
public class HealthController {
private static final Logger logger = LoggerFactory.getLogger(HealthController.class);
private static final Logger logger = LoggerFactory.getLogger(HealthController.class);
private final PersistService persistService;
private final OperatorController apiCommands;
private final PersistService persistService;
@Autowired
public HealthController(PersistService persistService, OperatorController apiCommands) {
this.persistService = persistService;
this.apiCommands = apiCommands;
}
private final OperatorController apiCommands;
/**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted
*
* @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.
*/
@GetMapping("/liveness")
public ResponseEntity liveness() {
return ResponseEntity.ok().body("OK");
}
@Autowired
public HealthController(PersistService persistService, OperatorController apiCommands) {
this.persistService = persistService;
this.apiCommands = apiCommands;
}
/**
* Ready to receive the request or not
*
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
* ready.
*/
@GetMapping("/readiness")
public ResponseEntity readiness(HttpServletRequest request) {
boolean isConfigReadiness = isConfigReadiness();
boolean isNamingReadiness = isNamingReadiness(request);
/**
* Whether the Nacos is in broken states or not, and cannot recover except by being
* restarted
* @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.
*/
@GetMapping("/liveness")
public ResponseEntity liveness() {
return ResponseEntity.ok().body("OK");
}
if (isConfigReadiness && isNamingReadiness) {
return ResponseEntity.ok().body("OK");
}
/**
* Ready to receive the request or not
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to
* 500 indicates that Nacos is not ready.
*/
@GetMapping("/readiness")
public ResponseEntity readiness(HttpServletRequest request) {
boolean isConfigReadiness = isConfigReadiness();
boolean isNamingReadiness = isNamingReadiness(request);
if (!isConfigReadiness && !isNamingReadiness) {
return ResponseEntity.status(500).body("Config and Naming are not in readiness");
}
if (isConfigReadiness && isNamingReadiness) {
return ResponseEntity.ok().body("OK");
}
if (!isConfigReadiness) {
return ResponseEntity.status(500).body("Config is not in readiness");
}
if (!isConfigReadiness && !isNamingReadiness) {
return ResponseEntity.status(500).body("Config and Naming are not in readiness");
}
return ResponseEntity.status(500).body("Naming is not in readiness");
}
if (!isConfigReadiness) {
return ResponseEntity.status(500).body("Config is not in readiness");
}
private boolean isConfigReadiness() {
// check db
try {
persistService.configInfoCount("");
return true;
} catch (Exception e) {
logger.error("Config health check fail.", e);
}
return false;
}
return ResponseEntity.status(500).body("Naming is not in readiness");
}
private boolean isConfigReadiness() {
// check db
try {
persistService.configInfoCount("");
return true;
}
catch (Exception e) {
logger.error("Config health check fail.", e);
}
return false;
}
private boolean isNamingReadiness(HttpServletRequest request) {
try {
apiCommands.metrics(request);
return true;
}
catch (Exception e) {
logger.error("Naming health check fail.", e);
}
return false;
}
private boolean isNamingReadiness(HttpServletRequest request) {
try {
apiCommands.metrics(request);
return true;
} catch (Exception e) {
logger.error("Naming health check fail.", e);
}
return false;
}
}
@@ -43,144 +43,140 @@ import java.util.regex.Pattern;
@RequestMapping("/v1/console/namespaces")
public class NamespaceController {
@Autowired
private PersistService persistService;
@Autowired
private PersistService persistService;
private Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
private Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
private static final int NAMESPACE_ID_MAX_LENGTH = 128;
private static final int NAMESPACE_ID_MAX_LENGTH = 128;
/**
* Get namespace list
*
* @param request request
* @param response response
* @return namespace list
*/
@GetMapping
public RestResult<List<Namespace>> getNamespaces(HttpServletRequest request, HttpServletResponse response) {
RestResult<List<Namespace>> rr = new RestResult<List<Namespace>>();
rr.setCode(200);
// TODO 获取用kp
List<TenantInfo> tenantInfos = persistService.findTenantByKp("1");
Namespace namespace0 = new Namespace("", "public", 200, persistService.configInfoCount(""), 0);
List<Namespace> namespaces = new ArrayList<Namespace>();
namespaces.add(namespace0);
for (TenantInfo tenantInfo : tenantInfos) {
int configCount = persistService.configInfoCount(tenantInfo.getTenantId());
Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(), 200,
configCount, 2);
namespaces.add(namespaceTmp);
}
rr.setData(namespaces);
return rr;
}
/**
* Get namespace list
* @param request request
* @param response response
* @return namespace list
*/
@GetMapping
public RestResult<List<Namespace>> getNamespaces(HttpServletRequest request, HttpServletResponse response) {
RestResult<List<Namespace>> rr = new RestResult<List<Namespace>>();
rr.setCode(200);
// TODO 获取用kp
List<TenantInfo> tenantInfos = persistService.findTenantByKp("1");
Namespace namespace0 = new Namespace("", "public", 200, persistService.configInfoCount(""), 0);
List<Namespace> namespaces = new ArrayList<Namespace>();
namespaces.add(namespace0);
for (TenantInfo tenantInfo : tenantInfos) {
int configCount = persistService.configInfoCount(tenantInfo.getTenantId());
Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(), 200,
configCount, 2);
namespaces.add(namespaceTmp);
}
rr.setData(namespaces);
return rr;
}
/**
* get namespace all info by namespace id
*
* @param request request
* @param response response
* @param namespaceId namespaceId
* @return namespace all info
*/
@GetMapping(params = "show=all")
public NamespaceAllInfo getNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) {
// TODO 获取用kp
if (StringUtils.isBlank(namespaceId)) {
return new NamespaceAllInfo(namespaceId, "Public", 200,
persistService.configInfoCount(""), 0, "Public Namespace");
} else {
TenantInfo tenantInfo = persistService.findTenantByKp("1", namespaceId);
int configCount = persistService.configInfoCount(namespaceId);
return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200,
configCount, 2, tenantInfo.getTenantDesc());
}
}
/**
* get namespace all info by namespace id
* @param request request
* @param response response
* @param namespaceId namespaceId
* @return namespace all info
*/
@GetMapping(params = "show=all")
public NamespaceAllInfo getNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) {
// TODO 获取用kp
if (StringUtils.isBlank(namespaceId)) {
return new NamespaceAllInfo(namespaceId, "Public", 200, persistService.configInfoCount(""), 0,
"Public Namespace");
}
else {
TenantInfo tenantInfo = persistService.findTenantByKp("1", namespaceId);
int configCount = persistService.configInfoCount(namespaceId);
return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200, configCount, 2,
tenantInfo.getTenantDesc());
}
}
/**
* create namespace
*
* @param request request
* @param response response
* @param namespaceName namespace Name
* @param namespaceDesc namespace Desc
* @return whether create ok
*/
@PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("customNamespaceId") String namespaceId,
@RequestParam("namespaceName") String namespaceName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// TODO 获取用kp
if(StringUtils.isBlank(namespaceId)){
namespaceId = UUID.randomUUID().toString();
} else {
namespaceId = namespaceId.trim();
if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) {
return false;
}
if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) {
return false;
}
if(persistService.tenantInfoCountByTenantId(namespaceId) > 0){
return false;
}
}
persistService.insertTenantInfoAtomic("1", namespaceId, namespaceName, namespaceDesc, "nacos",
System.currentTimeMillis());
return true;
}
/**
* create namespace
* @param request request
* @param response response
* @param namespaceName namespace Name
* @param namespaceDesc namespace Desc
* @return whether create ok
*/
@PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("customNamespaceId") String namespaceId, @RequestParam("namespaceName") String namespaceName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// TODO 获取用kp
if (StringUtils.isBlank(namespaceId)) {
namespaceId = UUID.randomUUID().toString();
}
else {
namespaceId = namespaceId.trim();
if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) {
return false;
}
if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) {
return false;
}
if (persistService.tenantInfoCountByTenantId(namespaceId) > 0) {
return false;
}
}
persistService.insertTenantInfoAtomic("1", namespaceId, namespaceName, namespaceDesc, "nacos",
System.currentTimeMillis());
return true;
}
/**
* @author klw(213539@qq.com)
* @Description: check namespaceId exist
* @Date 2019/12/10 21:41
* @param: namespaceId
* @return java.lang.Boolean
*/
@GetMapping(params = "checkNamespaceIdExist=true")
public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId){
if(StringUtils.isBlank(namespaceId)){
return false;
}
return (persistService.tenantInfoCountByTenantId(namespaceId) > 0);
}
/**
* @author klw(213539@qq.com)
* @Description: check namespaceId exist
* @Date 2019/12/10 21:41
* @param: namespaceId
* @return java.lang.Boolean
*/
@GetMapping(params = "checkNamespaceIdExist=true")
public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId) {
if (StringUtils.isBlank(namespaceId)) {
return false;
}
return (persistService.tenantInfoCountByTenantId(namespaceId) > 0);
}
/**
* edit namespace
*
* @param namespace namespace
* @param namespaceShowName namespace ShowName
* @param namespaceDesc namespace Desc
* @return whether edit ok
*/
@PutMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean editNamespace(@RequestParam("namespace") String namespace,
@RequestParam("namespaceShowName") String namespaceShowName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// TODO 获取用kp
persistService.updateTenantNameAtomic("1", namespace, namespaceShowName, namespaceDesc);
return true;
}
/**
* edit namespace
* @param namespace namespace
* @param namespaceShowName namespace ShowName
* @param namespaceDesc namespace Desc
* @return whether edit ok
*/
@PutMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean editNamespace(@RequestParam("namespace") String namespace,
@RequestParam("namespaceShowName") String namespaceShowName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// TODO 获取用kp
persistService.updateTenantNameAtomic("1", namespace, namespaceShowName, namespaceDesc);
return true;
}
/**
* del namespace by id
*
* @param request request
* @param response response
* @param namespaceId namespace Id
* @return whether del ok
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) {
persistService.removeTenantInfoAtomic("1", namespaceId);
return true;
}
/**
* del namespace by id
* @param request request
* @param response response
* @param namespaceId namespace Id
* @return whether del ok
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) {
persistService.removeTenantInfoAtomic("1", namespaceId);
return true;
}
}
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.config.server.model.RestResult;
import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
import com.alibaba.nacos.console.security.nacos.roles.NacosRoleServiceImpl;
@@ -25,7 +24,6 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* Permission operation controller
*
@@ -36,51 +34,50 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/v1/auth/permissions")
public class PermissionController {
@Autowired
private NacosRoleServiceImpl nacosRoleService;
@Autowired
private NacosRoleServiceImpl nacosRoleService;
/**
* Query permissions of a role
*
* @param role the role
* @param pageNo page index
* @param pageSize page size
* @return permission of a role
*/
@GetMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.READ)
public Object getPermissions(@RequestParam int pageNo, @RequestParam int pageSize,
@RequestParam(name = "role", defaultValue = StringUtils.EMPTY) String role) {
return nacosRoleService.getPermissionsFromDatabase(role, pageNo, pageSize);
}
/**
* Query permissions of a role
* @param role the role
* @param pageNo page index
* @param pageSize page size
* @return permission of a role
*/
@GetMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.READ)
public Object getPermissions(@RequestParam int pageNo, @RequestParam int pageSize,
@RequestParam(name = "role", defaultValue = StringUtils.EMPTY) String role) {
return nacosRoleService.getPermissionsFromDatabase(role, pageNo, pageSize);
}
/**
* Add a permission to a role
*
* @param role the role
* @param resource the related resource
* @param action the related action
* @return ok if succeed
*/
@PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
public Object addPermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) {
nacosRoleService.addPermission(role, resource, action);
return new RestResult<>(200, "add permission ok!");
}
/**
* Add a permission to a role
* @param role the role
* @param resource the related resource
* @param action the related action
* @return ok if succeed
*/
@PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
public Object addPermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) {
nacosRoleService.addPermission(role, resource, action);
return new RestResult<>(200, "add permission ok!");
}
/**
* Delete a permission from a role
* @param role the role
* @param resource the related resource
* @param action the related action
* @return ok if succeed
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
public Object deletePermission(@RequestParam String role, @RequestParam String resource,
@RequestParam String action) {
nacosRoleService.deletePermission(role, resource, action);
return new RestResult<>(200, "delete permission ok!");
}
/**
* Delete a permission from a role
*
* @param role the role
* @param resource the related resource
* @param action the related action
* @return ok if succeed
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
public Object deletePermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) {
nacosRoleService.deletePermission(role, resource, action);
return new RestResult<>(200, "delete permission ok!");
}
}
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.config.server.model.RestResult;
import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
import com.alibaba.nacos.console.security.nacos.roles.NacosRoleServiceImpl;
@@ -35,59 +34,56 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/v1/auth/roles")
public class RoleController {
@Autowired
private NacosRoleServiceImpl roleService;
@Autowired
private NacosRoleServiceImpl roleService;
/**
* Get roles list
*
* @param pageNo number index of page
* @param pageSize page size
* @param username optional, username of user
* @return role list
*/
@GetMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.READ)
public Object getRoles(@RequestParam int pageNo, @RequestParam int pageSize,
@RequestParam(name = "username", defaultValue = "") String username) {
return roleService.getRolesFromDatabase(username, pageNo, pageSize);
}
/**
* Get roles list
* @param pageNo number index of page
* @param pageSize page size
* @param username optional, username of user
* @return role list
*/
@GetMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.READ)
public Object getRoles(@RequestParam int pageNo, @RequestParam int pageSize,
@RequestParam(name = "username", defaultValue = "") String username) {
return roleService.getRolesFromDatabase(username, pageNo, pageSize);
}
/**
* Add a role to a user
* <p>
* This method is used for 2 functions:
* 1. create a role and bind it to GLOBAL_ADMIN.
* 2. bind a role to an user.
*
* @param role
* @param username
* @return
*/
@PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
public Object addRole(@RequestParam String role, @RequestParam String username) {
roleService.addRole(role, username);
return new RestResult<>(200, "add role ok!");
}
/**
* Add a role to a user
* <p>
* This method is used for 2 functions: 1. create a role and bind it to GLOBAL_ADMIN.
* 2. bind a role to an user.
* @param role
* @param username
* @return
*/
@PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
public Object addRole(@RequestParam String role, @RequestParam String username) {
roleService.addRole(role, username);
return new RestResult<>(200, "add role ok!");
}
/**
* Delete a role. If no username is specified, all users under this role are deleted
*
* @param role role
* @param username username
* @return ok if succeed
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
public Object deleteRole(@RequestParam String role,
@RequestParam(name = "username", defaultValue = StringUtils.EMPTY) String username) {
if (StringUtils.isBlank(username)) {
roleService.deleteRole(role);
} else {
roleService.deleteRole(role, username);
}
return new RestResult<>(200, "delete role of user " + username + " ok!");
}
/**
* Delete a role. If no username is specified, all users under this role are deleted
* @param role role
* @param username username
* @return ok if succeed
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
public Object deleteRole(@RequestParam String role,
@RequestParam(name = "username", defaultValue = StringUtils.EMPTY) String username) {
if (StringUtils.isBlank(username)) {
roleService.deleteRole(role);
}
else {
roleService.deleteRole(role, username);
}
return new RestResult<>(200, "delete role of user " + username + " ok!");
}
}
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.utils.VersionUtils;
import com.alibaba.nacos.core.utils.SystemUtils;
import org.springframework.http.ResponseEntity;
@@ -27,23 +26,22 @@ import java.util.HashMap;
import java.util.Map;
/**
* @author xingxuechao
* on:2019/2/27 11:17 AM
* @author xingxuechao on:2019/2/27 11:17 AM
*/
@RestController
@RequestMapping("/v1/console/server")
public class ServerStateController {
@GetMapping("/state")
public ResponseEntity serverState() {
Map<String,String> serverState = new HashMap<>(3);
serverState.put("standalone_mode",SystemUtils.STANDALONE_MODE ?
SystemUtils.STANDALONE_MODE_ALONE : SystemUtils.STANDALONE_MODE_CLUSTER);
@GetMapping("/state")
public ResponseEntity serverState() {
Map<String, String> serverState = new HashMap<>(3);
serverState.put("standalone_mode",
SystemUtils.STANDALONE_MODE ? SystemUtils.STANDALONE_MODE_ALONE : SystemUtils.STANDALONE_MODE_CLUSTER);
serverState.put("function_mode", SystemUtils.FUNCTION_MODE);
serverState.put("version", VersionUtils.VERSION);
serverState.put("function_mode", SystemUtils.FUNCTION_MODE);
serverState.put("version", VersionUtils.VERSION);
return ResponseEntity.ok().body(serverState);
}
return ResponseEntity.ok().body(serverState);
}
}
@@ -48,185 +48,184 @@ import java.util.List;
* @author nkorange
*/
@RestController("user")
@RequestMapping({"/v1/auth", "/v1/auth/users"})
@RequestMapping({ "/v1/auth", "/v1/auth/users" })
public class UserController {
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private NacosRoleServiceImpl roleService;
@Autowired
private NacosRoleServiceImpl roleService;
@Autowired
private AuthConfigs authConfigs;
@Autowired
private AuthConfigs authConfigs;
@Autowired
private NacosAuthManager authManager;
@Autowired
private NacosAuthManager authManager;
/**
* Create a new user
*
* @param username username
* @param password password
* @return ok if create succeed
* @throws IllegalArgumentException if user already exist
* @since 1.2.0
*/
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
@PostMapping
public Object createUser(@RequestParam String username, @RequestParam String password) {
/**
* Create a new user
* @param username username
* @param password password
* @return ok if create succeed
* @throws IllegalArgumentException if user already exist
* @since 1.2.0
*/
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
@PostMapping
public Object createUser(@RequestParam String username, @RequestParam String password) {
User user = userDetailsService.getUserFromDatabase(username);
if (user != null) {
throw new IllegalArgumentException("user '" + username + "' already exist!");
}
userDetailsService.createUser(username, PasswordEncoderUtil.encode(password));
return new RestResult<>(200, "create user ok!");
}
User user = userDetailsService.getUserFromDatabase(username);
if (user != null) {
throw new IllegalArgumentException("user '" + username + "' already exist!");
}
userDetailsService.createUser(username, PasswordEncoderUtil.encode(password));
return new RestResult<>(200, "create user ok!");
}
/**
* Delete an existed user
*
* @param username username of user
* @return ok if deleted succeed, keep silent if user not exist
* @since 1.2.0
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
public Object deleteUser(@RequestParam String username) {
List<RoleInfo> roleInfoList = roleService.getRoles(username);
if (roleInfoList != null) {
for (RoleInfo roleInfo : roleInfoList) {
if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) {
throw new IllegalArgumentException("cannot delete admin: " + username);
}
}
}
userDetailsService.deleteUser(username);
return new RestResult<>(200, "delete user ok!");
}
/**
* Delete an existed user
* @param username username of user
* @return ok if deleted succeed, keep silent if user not exist
* @since 1.2.0
*/
@DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
public Object deleteUser(@RequestParam String username) {
List<RoleInfo> roleInfoList = roleService.getRoles(username);
if (roleInfoList != null) {
for (RoleInfo roleInfo : roleInfoList) {
if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) {
throw new IllegalArgumentException("cannot delete admin: " + username);
}
}
}
userDetailsService.deleteUser(username);
return new RestResult<>(200, "delete user ok!");
}
/**
* Update an user
*
* @param username username of user
* @param newPassword new password of user
* @return ok if update succeed
* @throws IllegalArgumentException if user not exist or oldPassword is incorrect
* @since 1.2.0
*/
@PutMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
public Object updateUser(@RequestParam String username, @RequestParam String newPassword) {
/**
* Update an user
* @param username username of user
* @param newPassword new password of user
* @return ok if update succeed
* @throws IllegalArgumentException if user not exist or oldPassword is incorrect
* @since 1.2.0
*/
@PutMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE)
public Object updateUser(@RequestParam String username, @RequestParam String newPassword) {
User user = userDetailsService.getUserFromDatabase(username);
if (user == null) {
throw new IllegalArgumentException("user " + username + " not exist!");
}
User user = userDetailsService.getUserFromDatabase(username);
if (user == null) {
throw new IllegalArgumentException("user " + username + " not exist!");
}
userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
return new RestResult<>(200, "update user ok!");
}
return new RestResult<>(200, "update user ok!");
}
/**
* Get paged users
*
* @param pageNo number index of page
* @param pageSize size of page
* @return A collection of users, empty set if no user is found
* @since 1.2.0
*/
@GetMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.READ)
public Object getUsers(@RequestParam int pageNo, @RequestParam int pageSize) {
return userDetailsService.getUsersFromDatabase(pageNo, pageSize);
}
/**
* Get paged users
* @param pageNo number index of page
* @param pageSize size of page
* @return A collection of users, empty set if no user is found
* @since 1.2.0
*/
@GetMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.READ)
public Object getUsers(@RequestParam int pageNo, @RequestParam int pageSize) {
return userDetailsService.getUsersFromDatabase(pageNo, pageSize);
}
/**
* Login to Nacos
* <p>
* This methods uses username and password to require a new token.
*
* @param username username of user
* @param password password
* @param response http response
* @param request http request
* @return new token of the user
* @throws AccessException if user info is incorrect
*/
@PostMapping("/login")
public Object login(@RequestParam String username, @RequestParam String password,
HttpServletResponse response, HttpServletRequest request) throws AccessException {
/**
* Login to Nacos
* <p>
* This methods uses username and password to require a new token.
* @param username username of user
* @param password password
* @param response http response
* @param request http request
* @return new token of the user
* @throws AccessException if user info is incorrect
*/
@PostMapping("/login")
public Object login(@RequestParam String username, @RequestParam String password, HttpServletResponse response,
HttpServletRequest request) throws AccessException {
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
NacosUser user = (NacosUser) authManager.login(request);
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
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());
JSONObject result = new JSONObject();
result.put(Constants.ACCESS_TOKEN, user.getToken());
result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
return result;
}
JSONObject result = new JSONObject();
result.put(Constants.ACCESS_TOKEN, user.getToken());
result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
return result;
}
// 通过用户名和密码创建一个 Authentication 认证对象,实现类为 UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
password);
// 通过用户名和密码创建一个 Authentication 认证对象,实现类为 UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
RestResult<String> rr = new RestResult<String>();
try {
// 通过 AuthenticationManager(默认实现为ProviderManager)的authenticate方法验证
// Authentication 对象
Authentication authentication = authenticationManager.authenticate(authenticationToken);
// 将 Authentication 绑定到 SecurityContext
SecurityContextHolder.getContext().setAuthentication(authentication);
// 生成Token
String token = jwtTokenUtils.createToken(authentication);
// 将Token写入到Http头部
response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token);
rr.setCode(200);
rr.setData("Bearer " + token);
return rr;
}
catch (BadCredentialsException authentication) {
rr.setCode(401);
rr.setMessage("Login failed");
return rr;
}
}
RestResult<String> rr = new RestResult<String>();
try {
//通过 AuthenticationManager(默认实现为ProviderManager)的authenticate方法验证 Authentication 对象
Authentication authentication = authenticationManager.authenticate(authenticationToken);
//将 Authentication 绑定到 SecurityContext
SecurityContextHolder.getContext().setAuthentication(authentication);
//生成Token
String token = jwtTokenUtils.createToken(authentication);
//将Token写入到Http头部
response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token);
rr.setCode(200);
rr.setData("Bearer " + token);
return rr;
} catch (BadCredentialsException authentication) {
rr.setCode(401);
rr.setMessage("Login failed");
return rr;
}
}
@PutMapping("/password")
@Deprecated
public RestResult<String> updatePassword(@RequestParam(value = "oldPassword") String oldPassword,
@RequestParam(value = "newPassword") String newPassword) {
@PutMapping("/password")
@Deprecated
public RestResult<String> updatePassword(@RequestParam(value = "oldPassword") String oldPassword,
@RequestParam(value = "newPassword") String newPassword) {
RestResult<String> rr = new RestResult<String>();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = ((UserDetails) principal).getUsername();
User user = userDetailsService.getUserFromDatabase(username);
String password = user.getPassword();
RestResult<String> rr = new RestResult<String>();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String username = ((UserDetails) principal).getUsername();
User user = userDetailsService.getUserFromDatabase(username);
String password = user.getPassword();
// TODO: throw out more fine grained exceptions
try {
if (PasswordEncoderUtil.matches(oldPassword, password)) {
userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
rr.setCode(200);
rr.setMessage("Update password success");
}
else {
rr.setCode(401);
rr.setMessage("Old password is invalid");
}
}
catch (Exception e) {
rr.setCode(500);
rr.setMessage("Update userpassword failed");
}
return rr;
}
// TODO: throw out more fine grained exceptions
try {
if (PasswordEncoderUtil.matches(oldPassword, password)) {
userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword));
rr.setCode(200);
rr.setMessage("Update password success");
} else {
rr.setCode(401);
rr.setMessage("Old password is invalid");
}
} catch (Exception e) {
rr.setCode(500);
rr.setMessage("Update userpassword failed");
}
return rr;
}
}
@@ -32,21 +32,22 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class ConsoleExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(ConsoleExceptionHandler.class);
private static final Logger logger = LoggerFactory.getLogger(ConsoleExceptionHandler.class);
@ExceptionHandler(AccessException.class)
private ResponseEntity<String> handleAccessException(AccessException e) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg());
}
@ExceptionHandler(AccessException.class)
private ResponseEntity<String> handleAccessException(AccessException e) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getErrMsg());
}
@ExceptionHandler(IllegalArgumentException.class)
private ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.toString());
}
@ExceptionHandler(IllegalArgumentException.class)
private ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.toString());
}
@ExceptionHandler(Exception.class)
private ResponseEntity<String> handleException(Exception e) {
logger.error("CONSOLE", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.toString());
}
@ExceptionHandler(Exception.class)
private ResponseEntity<String> handleException(Exception e) {
logger.error("CONSOLE", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.toString());
}
}
@@ -36,40 +36,41 @@ import java.io.IOException;
*/
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private static final String TOKEN_PREFIX = "Bearer ";
private static final String TOKEN_PREFIX = "Bearer ";
private JwtTokenManager tokenManager;
private JwtTokenManager tokenManager;
public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) {
this.tokenManager = tokenManager;
}
public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) {
this.tokenManager = tokenManager;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String jwt = resolveToken(request);
String jwt = resolveToken(request);
if (StringUtils.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
this.tokenManager.validateToken(jwt);
Authentication authentication = this.tokenManager.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
if (StringUtils.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
this.tokenManager.validateToken(jwt);
Authentication authentication = this.tokenManager.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
chain.doFilter(request, response);
}
/**
* Get token from header
*/
private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7);
}
String jwt = request.getParameter(Constants.ACCESS_TOKEN);
if (StringUtils.isNotBlank(jwt)) {
return jwt;
}
return null;
}
/**
* Get token from header
*/
private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7);
}
String jwt = request.getParameter(Constants.ACCESS_TOKEN);
if (StringUtils.isNotBlank(jwt)) {
return jwt;
}
return null;
}
}
@@ -22,72 +22,73 @@ package com.alibaba.nacos.console.model;
*/
public class Namespace {
private String namespace;
private String namespace;
private String namespaceShowName;
private String namespaceShowName;
private int quota;
private int quota;
private int configCount;
/**
* 0 : Global configuration, 1 : Default private namespace ,2 : Custom namespace
*/
private int type;
private int configCount;
public String getNamespaceShowName() {
return namespaceShowName;
}
/**
* 0 : Global configuration, 1 : Default private namespace ,2 : Custom namespace
*/
private int type;
public void setNamespaceShowName(String namespaceShowName) {
this.namespaceShowName = namespaceShowName;
}
public String getNamespaceShowName() {
return namespaceShowName;
}
public String getNamespace() {
return namespace;
}
public void setNamespaceShowName(String namespaceShowName) {
this.namespaceShowName = namespaceShowName;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getNamespace() {
return namespace;
}
public Namespace() {
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public Namespace(String namespace, String namespaceShowName) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
}
public Namespace() {
}
public Namespace(String namespace, String namespaceShowName, int quota, int configCount, int type) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
this.quota = quota;
this.configCount = configCount;
this.type = type;
}
public Namespace(String namespace, String namespaceShowName) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
}
public int getQuota() {
return quota;
}
public Namespace(String namespace, String namespaceShowName, int quota, int configCount, int type) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
this.quota = quota;
this.configCount = configCount;
this.type = type;
}
public void setQuota(int quota) {
this.quota = quota;
}
public int getQuota() {
return quota;
}
public int getConfigCount() {
return configCount;
}
public void setQuota(int quota) {
this.quota = quota;
}
public void setConfigCount(int configCount) {
this.configCount = configCount;
}
public int getConfigCount() {
return configCount;
}
public int getType() {
return type;
}
public void setConfigCount(int configCount) {
this.configCount = configCount;
}
public void setType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
@@ -22,23 +22,23 @@ package com.alibaba.nacos.console.model;
*/
public class NamespaceAllInfo extends Namespace {
private String namespaceDesc;
private String namespaceDesc;
public String getNamespaceDesc() {
return namespaceDesc;
}
public String getNamespaceDesc() {
return namespaceDesc;
}
public void setNamespaceDesc(String namespaceDesc) {
this.namespaceDesc = namespaceDesc;
}
public void setNamespaceDesc(String namespaceDesc) {
this.namespaceDesc = namespaceDesc;
}
public NamespaceAllInfo() {
}
public NamespaceAllInfo() {
}
public NamespaceAllInfo(String namespace, String namespaceShowName, int quota, int configCount, int type,
String namespaceDesc) {
super(namespace, namespaceShowName, quota, configCount, type);
this.namespaceDesc = namespaceDesc;
}
public NamespaceAllInfo(String namespace, String namespaceShowName, int quota, int configCount, int type,
String namespaceDesc) {
super(namespace, namespaceShowName, quota, configCount, type);
this.namespaceDesc = namespaceDesc;
}
}
@@ -32,25 +32,25 @@ import org.springframework.stereotype.Component;
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (!password.equals(userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(username, null, null);
}
return null;
}
if (!password.equals(userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(username, null, null);
}
return null;
}
@Override
public boolean supports(Class<?> aClass) {
return aClass.equals(UsernamePasswordAuthenticationToken.class);
}
@Override
public boolean supports(Class<?> aClass) {
return aClass.equals(UsernamePasswordAuthenticationToken.class);
}
}
@@ -34,13 +34,13 @@ import java.io.IOException;
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
throws IOException, ServletException {
logger.error("Responding with unauthorized error. Message:{}, url:{}", e.getMessage(), request.getRequestURI());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException e) throws IOException, ServletException {
logger.error("Responding with unauthorized error. Message:{}, url:{}", e.getMessage(), request.getRequestURI());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
@@ -40,65 +40,58 @@ import java.util.List;
@Component
public class JwtTokenManager {
private static final String AUTHORITIES_KEY = "auth";
private static final String AUTHORITIES_KEY = "auth";
@Autowired
private AuthConfigs authConfigs;
@Autowired
private AuthConfigs authConfigs;
/**
* Create token
*
* @param authentication auth info
* @return token
*/
public String createToken(Authentication authentication) {
return createToken(authentication.getName());
}
/**
* Create token
* @param authentication auth info
* @return token
*/
public String createToken(Authentication authentication) {
return createToken(authentication.getName());
}
public String createToken(String userName) {
public String createToken(String userName) {
long now = (new Date()).getTime();
long now = (new Date()).getTime();
Date validity;
validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L);
Date validity;
validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L);
Claims claims = Jwts.claims().setSubject(userName);
Claims claims = Jwts.claims().setSubject(userName);
return Jwts.builder()
.setClaims(claims)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, authConfigs.getSecretKey())
.compact();
}
return Jwts.builder().setClaims(claims).setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, authConfigs.getSecretKey()).compact();
}
/**
* Get auth Info
*
* @param token token
* @return auth info
*/
public Authentication getAuthentication(String token) {
/**
* parse the payload of token
*/
Claims claims = Jwts.parser()
.setSigningKey(authConfigs.getSecretKey())
.parseClaimsJws(token)
.getBody();
/**
* Get auth Info
* @param token token
* @return auth info
*/
public Authentication getAuthentication(String token) {
/**
* parse the payload of token
*/
Claims claims = Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token).getBody();
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
List<GrantedAuthority> authorities = AuthorityUtils
.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
}
User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
}
/**
* validate token
* @param token token
* @return whether valid
*/
public void validateToken(String token) {
Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token);
}
/**
* validate token
*
* @param token token
* @return whether valid
*/
public void validateToken(String token) {
Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token);
}
}
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.console.security.nacos;
import com.alibaba.nacos.console.filter.JwtAuthenticationTokenFilter;
import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
import com.alibaba.nacos.core.auth.AuthConfigs;
@@ -48,99 +47,92 @@ import org.springframework.web.cors.CorsUtils;
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String SECURITY_IGNORE_URLS_SPILT_CHAR = ",";
public static final String SECURITY_IGNORE_URLS_SPILT_CHAR = ",";
public static final String LOGIN_ENTRY_POINT = "/v1/auth/login";
public static final String LOGIN_ENTRY_POINT = "/v1/auth/login";
public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/v1/auth/**";
public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/v1/auth/**";
public static final String TOKEN_PREFIX = "Bearer ";
public static final String TOKEN_PREFIX = "Bearer ";
public static final String CONSOLE_RESOURCE_NAME_PREFIX = "console/";
public static final String CONSOLE_RESOURCE_NAME_PREFIX = "console/";
@Autowired
private Environment env;
@Autowired
private Environment env;
@Autowired
private JwtTokenManager tokenProvider;
@Autowired
private JwtTokenManager tokenProvider;
@Autowired
private AuthConfigs authConfigs;
@Autowired
private AuthConfigs authConfigs;
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Value("${nacos.security.ignore.urls}")
@Value("${nacos.security.ignore.urls}")
private String ignoreURLs;
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(WebSecurity web) {
@Override
public void configure(WebSecurity web) {
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
ignoreURLs = "/**";
}
//
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**");
}
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
ignoreURLs = "/**";
}
//
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**");
}
if (StringUtils.isNotBlank(ignoreURLs)) {
for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
web.ignoring().antMatchers(ignoreURL.trim());
}
}
if (StringUtils.isNotBlank(ignoreURLs)) {
for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
web.ignoring().antMatchers(ignoreURL.trim());
}
}
}
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
@Override
protected void configure(HttpSecurity http) throws Exception {
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
http
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
http
.csrf().disable()
.cors() // We don't need CSRF for JWT based authentication
.csrf().disable().cors() // We don't need CSRF for JWT based
// authentication
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.antMatchers(LOGIN_ENTRY_POINT).permitAll()
.and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.antMatchers(LOGIN_ENTRY_POINT).permitAll()
.and()
.authorizeRequests()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and().authorizeRequests().antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(new JwtAuthenticationEntryPoint());
.and().exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint());
// disable cache
http.headers().cacheControl();
// disable cache
http.headers().cacheControl();
http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
}
}
http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider),
UsernamePasswordAuthenticationFilter.class);
}
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@@ -46,91 +46,96 @@ import java.util.List;
@Component
public class NacosAuthManager implements AuthManager {
private static final String TOKEN_PREFIX = "Bearer ";
private static final String TOKEN_PREFIX = "Bearer ";
@Autowired
private JwtTokenManager tokenManager;
@Autowired
private JwtTokenManager tokenManager;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private NacosRoleServiceImpl roleService;
@Autowired
private NacosRoleServiceImpl roleService;
@Override
public User login(Object request) throws AccessException {
HttpServletRequest req = (HttpServletRequest) request;
String token = resolveToken(req);
if (StringUtils.isBlank(token)) {
throw new AccessException("user not found!");
}
@Override
public User login(Object request) throws AccessException {
HttpServletRequest req = (HttpServletRequest) 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!");
}
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);
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;
}
}
}
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;
}
return user;
}
@Override
public void auth(Permission permission, User user) throws AccessException {
if (Loggers.AUTH.isDebugEnabled()) {
Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user);
}
@Override
public void auth(Permission permission, User user) throws AccessException {
if (Loggers.AUTH.isDebugEnabled()) {
Loggers.AUTH.debug("auth permission: {}, user: {}", permission, user);
}
if (!roleService.hasPermission(user.getUserName(), permission)) {
throw new AccessException("authorization failed!");
}
}
if (!roleService.hasPermission(user.getUserName(), permission)) {
throw new AccessException("authorization failed!");
}
}
/**
* Get token from header
*/
private String resolveToken(HttpServletRequest request) throws AccessException {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7);
}
bearerToken = request.getParameter(Constants.ACCESS_TOKEN);
if (StringUtils.isBlank(bearerToken)) {
String userName = request.getParameter("username");
String password = request.getParameter("password");
bearerToken = resolveTokenFromUser(userName, password);
}
/**
* Get token from header
*/
private String resolveToken(HttpServletRequest request) throws AccessException {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
if (StringUtils.isNotBlank(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7);
}
bearerToken = request.getParameter(Constants.ACCESS_TOKEN);
if (StringUtils.isBlank(bearerToken)) {
String userName = request.getParameter("username");
String password = request.getParameter("password");
bearerToken = resolveTokenFromUser(userName, password);
}
return bearerToken;
}
return bearerToken;
}
private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException {
private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException {
try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, rawPassword);
authenticationManager.authenticate(authenticationToken);
} catch (AuthenticationException e) {
throw new AccessException("unknown user!");
}
try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName,
rawPassword);
authenticationManager.authenticate(authenticationToken);
}
catch (AuthenticationException e) {
throw new AccessException("unknown user!");
}
return tokenManager.createToken(userName);
}
return tokenManager.createToken(userName);
}
}
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.console.security.nacos.roles;
import com.alibaba.nacos.config.server.auth.PermissionInfo;
import com.alibaba.nacos.config.server.auth.PermissionPersistService;
import com.alibaba.nacos.config.server.auth.RoleInfo;
@@ -46,174 +45,177 @@ import java.util.regex.Pattern;
@Service
public class NacosRoleServiceImpl {
public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN";
public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN";
@Autowired
private AuthConfigs authConfigs;
@Autowired
private AuthConfigs authConfigs;
@Autowired
private RolePersistService rolePersistService;
@Autowired
private RolePersistService rolePersistService;
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private NacosUserDetailsServiceImpl userDetailsService;
@Autowired
private PermissionPersistService permissionPersistService;
@Autowired
private PermissionPersistService permissionPersistService;
private Set<String> roleSet = new ConcurrentHashSet<>();
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<>();
@Scheduled(initialDelay = 5000, fixedDelay = 15000)
private void reload() {
try {
Page<RoleInfo> roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, 1, Integer.MAX_VALUE);
if (roleInfoPage == null) {
return;
}
Set<String> tmpRoleSet = new HashSet<>(16);
Map<String, List<RoleInfo>> tmpRoleInfoMap = new ConcurrentHashMap<>(16);
for (RoleInfo roleInfo : roleInfoPage.getPageItems()) {
if (!tmpRoleInfoMap.containsKey(roleInfo.getUsername())) {
tmpRoleInfoMap.put(roleInfo.getUsername(), new ArrayList<>());
}
tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo);
tmpRoleSet.add(roleInfo.getRole());
}
@Scheduled(initialDelay = 5000, fixedDelay = 15000)
private void reload() {
try {
Page<RoleInfo> roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, 1,
Integer.MAX_VALUE);
if (roleInfoPage == null) {
return;
}
Set<String> tmpRoleSet = new HashSet<>(16);
Map<String, List<RoleInfo>> tmpRoleInfoMap = new ConcurrentHashMap<>(16);
for (RoleInfo roleInfo : roleInfoPage.getPageItems()) {
if (!tmpRoleInfoMap.containsKey(roleInfo.getUsername())) {
tmpRoleInfoMap.put(roleInfo.getUsername(), new ArrayList<>());
}
tmpRoleInfoMap.get(roleInfo.getUsername()).add(roleInfo);
tmpRoleSet.add(roleInfo.getRole());
}
Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
for (String role : tmpRoleSet) {
Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE);
tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
}
Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
for (String role : tmpRoleSet) {
Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1,
Integer.MAX_VALUE);
tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
}
roleSet = tmpRoleSet;
roleInfoMap = tmpRoleInfoMap;
permissionInfoMap = tmpPermissionInfoMap;
} catch (Exception e) {
Loggers.AUTH.warn("[LOAD-ROLES] load failed", e);
}
}
roleSet = tmpRoleSet;
roleInfoMap = tmpRoleInfoMap;
permissionInfoMap = tmpPermissionInfoMap;
}
catch (Exception e) {
Loggers.AUTH.warn("[LOAD-ROLES] load failed", e);
}
}
/**
* Determine if the user has permission of the resource.
* <p>
* Note if the user has many roles, this method returns true if any one role of the user has the
* desired permission.
*
* @param username user info
* @param permission permission to auth
* @return true if granted, false otherwise
*/
public boolean hasPermission(String username, Permission permission) {
/**
* Determine if the user has permission of the resource.
* <p>
* Note if the user has many roles, this method returns true if any one role of the
* user has the desired permission.
* @param username user info
* @param permission permission to auth
* @return true if granted, false otherwise
*/
public boolean hasPermission(String username, Permission permission) {
List<RoleInfo> roleInfoList = getRoles(username);
if (Collections.isEmpty(roleInfoList)) {
return false;
}
List<RoleInfo> roleInfoList = getRoles(username);
if (Collections.isEmpty(roleInfoList)) {
return false;
}
// Global admin pass:
for (RoleInfo roleInfo : roleInfoList) {
if (GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) {
return true;
}
}
// Global admin pass:
for (RoleInfo roleInfo : roleInfoList) {
if (GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) {
return true;
}
}
// Old global admin can pass resource 'console/':
if (permission.getResource().startsWith(NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX)) {
return false;
}
// Old global admin can pass resource 'console/':
if (permission.getResource().startsWith(NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX)) {
return false;
}
// For other roles, use a pattern match to decide if pass or not.
for (RoleInfo roleInfo : roleInfoList) {
List<PermissionInfo> permissionInfoList = getPermissions(roleInfo.getRole());
if (Collections.isEmpty(permissionInfoList)) {
continue;
}
for (PermissionInfo permissionInfo : permissionInfoList) {
String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*");
String permissionAction = permissionInfo.getAction();
if (permissionAction.contains(permission.getAction()) &&
Pattern.matches(permissionResource, permission.getResource())) {
return true;
}
}
}
return false;
}
// For other roles, use a pattern match to decide if pass or not.
for (RoleInfo roleInfo : roleInfoList) {
List<PermissionInfo> permissionInfoList = getPermissions(roleInfo.getRole());
if (Collections.isEmpty(permissionInfoList)) {
continue;
}
for (PermissionInfo permissionInfo : permissionInfoList) {
String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*");
String permissionAction = permissionInfo.getAction();
if (permissionAction.contains(permission.getAction())
&& Pattern.matches(permissionResource, permission.getResource())) {
return true;
}
}
}
return false;
}
public List<RoleInfo> getRoles(String username) {
List<RoleInfo> roleInfoList = roleInfoMap.get(username);
if (!authConfigs.isCachingEnabled()) {
Page<RoleInfo> roleInfoPage = getRolesFromDatabase(username, 1, Integer.MAX_VALUE);
if (roleInfoPage != null) {
roleInfoList = roleInfoPage.getPageItems();
}
}
return roleInfoList;
}
public List<RoleInfo> getRoles(String username) {
List<RoleInfo> roleInfoList = roleInfoMap.get(username);
if (!authConfigs.isCachingEnabled()) {
Page<RoleInfo> roleInfoPage = getRolesFromDatabase(username, 1, Integer.MAX_VALUE);
if (roleInfoPage != null) {
roleInfoList = roleInfoPage.getPageItems();
}
}
return roleInfoList;
}
public Page<RoleInfo> getRolesFromDatabase(String userName, int pageNo, int pageSize) {
Page<RoleInfo> roles = rolePersistService.getRolesByUserName(userName, pageNo, pageSize);
if (roles == null) {
return new Page<>();
}
return roles;
}
public Page<RoleInfo> getRolesFromDatabase(String userName, int pageNo, int pageSize) {
Page<RoleInfo> roles = rolePersistService.getRolesByUserName(userName, pageNo, pageSize);
if (roles == null) {
return new Page<>();
}
return roles;
}
public List<PermissionInfo> getPermissions(String role) {
List<PermissionInfo> permissionInfoList = permissionInfoMap.get(role);
if (!authConfigs.isCachingEnabled()) {
Page<PermissionInfo> permissionInfoPage = getPermissionsFromDatabase(role, 1, Integer.MAX_VALUE);
if (permissionInfoPage != null) {
permissionInfoList = permissionInfoPage.getPageItems();
}
}
return permissionInfoList;
}
public List<PermissionInfo> getPermissions(String role) {
List<PermissionInfo> permissionInfoList = permissionInfoMap.get(role);
if (!authConfigs.isCachingEnabled()) {
Page<PermissionInfo> permissionInfoPage = getPermissionsFromDatabase(role, 1, Integer.MAX_VALUE);
if (permissionInfoPage != null) {
permissionInfoList = permissionInfoPage.getPageItems();
}
}
return permissionInfoList;
}
public Page<PermissionInfo> getPermissionsByRoleFromDatabase(String role, int pageNo, int pageSize) {
return permissionPersistService.getPermissions(role, pageNo, pageSize);
}
public Page<PermissionInfo> getPermissionsByRoleFromDatabase(String role, int pageNo, int pageSize) {
return permissionPersistService.getPermissions(role, pageNo, pageSize);
}
public void addRole(String role, String username) {
if (userDetailsService.getUser(username) == null) {
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);
roleSet.add(role);
}
public void addRole(String role, String username) {
if (userDetailsService.getUser(username) == null) {
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);
roleSet.add(role);
}
public void deleteRole(String role, String userName) {
rolePersistService.deleteRole(role, userName);
}
public void deleteRole(String role, String userName) {
rolePersistService.deleteRole(role, userName);
}
public void deleteRole(String role) {
rolePersistService.deleteRole(role);
roleSet.remove(role);
}
public void deleteRole(String role) {
rolePersistService.deleteRole(role);
roleSet.remove(role);
}
public Page<PermissionInfo> getPermissionsFromDatabase(String role, int pageNo, int pageSize) {
Page<PermissionInfo> pageInfo = permissionPersistService.getPermissions(role, pageNo, pageSize);
if (pageInfo == null) {
return new Page<>();
}
return pageInfo;
}
public Page<PermissionInfo> getPermissionsFromDatabase(String role, int pageNo, int pageSize) {
Page<PermissionInfo> pageInfo = permissionPersistService.getPermissions(role, pageNo, pageSize);
if (pageInfo == null) {
return new Page<>();
}
return pageInfo;
}
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);
}
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);
}
public void deletePermission(String role, String resource, String action) {
permissionPersistService.deletePermission(role, resource, action);
}
public void deletePermission(String role, String resource, String action) {
permissionPersistService.deletePermission(role, resource, action);
}
}
@@ -25,28 +25,29 @@ import com.alibaba.nacos.core.auth.User;
*/
public class NacosUser extends User {
private String token;
private String token;
private boolean globalAdmin = false;
private boolean globalAdmin = false;
public String getToken() {
return token;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public void setToken(String token) {
this.token = token;
}
public boolean isGlobalAdmin() {
return globalAdmin;
}
public boolean isGlobalAdmin() {
return globalAdmin;
}
public void setGlobalAdmin(boolean globalAdmin) {
this.globalAdmin = globalAdmin;
}
public void setGlobalAdmin(boolean globalAdmin) {
this.globalAdmin = globalAdmin;
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}
@@ -29,45 +29,46 @@ import java.util.Collection;
*/
public class NacosUserDetails implements UserDetails {
private User user;
private User user;
public NacosUserDetails(User user) {
this.user = user;
}
public NacosUserDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO: get authorities
return AuthorityUtils.commaSeparatedStringToAuthorityList("");
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO: get authorities
return AuthorityUtils.commaSeparatedStringToAuthorityList("");
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@@ -15,7 +15,6 @@
*/
package com.alibaba.nacos.console.security.nacos.users;
import com.alibaba.nacos.config.server.auth.UserPersistService;
import com.alibaba.nacos.config.server.model.Page;
import com.alibaba.nacos.config.server.model.User;
@@ -40,71 +39,73 @@ import java.util.concurrent.ConcurrentHashMap;
@Service
public class NacosUserDetailsServiceImpl implements UserDetailsService {
private Map<String, User> userMap = new ConcurrentHashMap<>();
private Map<String, User> userMap = new ConcurrentHashMap<>();
@Autowired
private UserPersistService userPersistService;
@Autowired
private UserPersistService userPersistService;
@Autowired
private AuthConfigs authConfigs;
@Autowired
private AuthConfigs authConfigs;
@Scheduled(initialDelay = 5000, fixedDelay = 15000)
private void reload() {
try {
Page<User> users = getUsersFromDatabase(1, Integer.MAX_VALUE);
if (users == null) {
return;
}
@Scheduled(initialDelay = 5000, fixedDelay = 15000)
private void reload() {
try {
Page<User> users = getUsersFromDatabase(1, Integer.MAX_VALUE);
if (users == null) {
return;
}
Map<String, User> map = new ConcurrentHashMap<>(16);
for (User user : users.getPageItems()) {
map.put(user.getUsername(), user);
}
userMap = map;
} catch (Exception e) {
Loggers.AUTH.warn("[LOAD-USERS] load failed", e);
}
}
Map<String, User> map = new ConcurrentHashMap<>(16);
for (User user : users.getPageItems()) {
map.put(user.getUsername(), user);
}
userMap = map;
}
catch (Exception e) {
Loggers.AUTH.warn("[LOAD-USERS] load failed", e);
}
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userMap.get(username);
if (!authConfigs.isCachingEnabled()) {
user = userPersistService.findUserByUsername(username);
}
User user = userMap.get(username);
if (!authConfigs.isCachingEnabled()) {
user = userPersistService.findUserByUsername(username);
}
if (user == null) {
throw new UsernameNotFoundException(username);
}
return new NacosUserDetails(user);
}
if (user == null) {
throw new UsernameNotFoundException(username);
}
return new NacosUserDetails(user);
}
public void updateUserPassword(String username, String password) {
userPersistService.updateUserPassword(username, password);
}
public void updateUserPassword(String username, String password) {
userPersistService.updateUserPassword(username, password);
}
public Page<User> getUsersFromDatabase(int pageNo, int pageSize) {
return userPersistService.getUsers(pageNo, pageSize);
}
public Page<User> getUsersFromDatabase(int pageNo, int pageSize) {
return userPersistService.getUsers(pageNo, pageSize);
}
public User getUser(String username) {
User user = userMap.get(username);
if (!authConfigs.isCachingEnabled()) {
user = getUserFromDatabase(username);
}
return user;
}
public User getUser(String username) {
User user = userMap.get(username);
if (!authConfigs.isCachingEnabled()) {
user = getUserFromDatabase(username);
}
return user;
}
public User getUserFromDatabase(String username) {
return userPersistService.findUserByUsername(username);
}
public User getUserFromDatabase(String username) {
return userPersistService.findUserByUsername(username);
}
public void createUser(String username, String password) {
userPersistService.createUser(username, password);
}
public void createUser(String username, String password) {
userPersistService.createUser(username, password);
}
public void deleteUser(String username) {
userPersistService.deleteUser(username);
}
public void deleteUser(String username) {
userPersistService.deleteUser(username);
}
}
@@ -32,7 +32,6 @@ import javax.crypto.SecretKey;
import java.util.Date;
import java.util.List;
/**
* Jwt token tool
*
@@ -41,135 +40,133 @@ import java.util.List;
@Component
public class JwtTokenUtils {
private final Logger log = LoggerFactory.getLogger(JwtTokenUtils.class);
private final Logger log = LoggerFactory.getLogger(JwtTokenUtils.class);
private static final String AUTHORITIES_KEY = "auth";
private static final String AUTHORITIES_KEY = "auth";
/**
* minimum SHA_256 secretKey string length
*/
private static final int SHA_256_SECRET_CHAR_SIZE = 256 / 8;
/**
* minimum SHA_256 secretKey string length
*/
private static final int SHA_256_SECRET_CHAR_SIZE = 256 / 8;
/**
* default SHA_256 secretKey flag
*/
private static final String DEFAULT_SECRET_FLAG = "default";
/**
* default SHA_256 secretKey flag
*/
private static final String DEFAULT_SECRET_FLAG = "default";
/**
* custom SHA_256 secretKey from config property
*/
@Value("${nacos.security.token.secret-key:default}")
private String customSecretKeyStr;
/**
* custom SHA_256 secretKey from config property
*/
@Value("${nacos.security.token.secret-key:default}")
private String customSecretKeyStr;
/**
* secret key
*/
private SecretKey secretKey;
/**
* secret key
*/
private SecretKey secretKey;
/**
* Token validity time(ms)
*/
private long tokenValidityInMilliseconds;
/**
* Token validity time(ms)
*/
private long tokenValidityInMilliseconds;
@PostConstruct
public void init() {
//use default secretKey for SHA-256
if (customSecretKeyStr == null || DEFAULT_SECRET_FLAG.equals(customSecretKeyStr)) {
this.secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
} else {
//use custom secretKey
int size = customSecretKeyStr.length();
int left = SHA_256_SECRET_CHAR_SIZE - size;
if (left > 0) {
//character for padding
StringBuilder stringBuilder = new StringBuilder(customSecretKeyStr);
for (int i = 0 ;i < left ; i ++){
stringBuilder.append(i%10);
}
this.secretKey = Keys.hmacShaKeyFor(stringBuilder.toString().getBytes());
}else {
this.secretKey = Keys.hmacShaKeyFor(customSecretKeyStr.getBytes());
}
}
this.tokenValidityInMilliseconds = 1000 * 60 * 30L;
}
@PostConstruct
public void init() {
// use default secretKey for SHA-256
if (customSecretKeyStr == null || DEFAULT_SECRET_FLAG.equals(customSecretKeyStr)) {
this.secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
}
else {
// use custom secretKey
int size = customSecretKeyStr.length();
int left = SHA_256_SECRET_CHAR_SIZE - size;
if (left > 0) {
// character for padding
StringBuilder stringBuilder = new StringBuilder(customSecretKeyStr);
for (int i = 0; i < left; i++) {
stringBuilder.append(i % 10);
}
this.secretKey = Keys.hmacShaKeyFor(stringBuilder.toString().getBytes());
}
else {
this.secretKey = Keys.hmacShaKeyFor(customSecretKeyStr.getBytes());
}
}
this.tokenValidityInMilliseconds = 1000 * 60 * 30L;
}
/**
* Create token
*
* @param authentication auth info
* @return token
*/
public String createToken(Authentication authentication) {
/**
* Current time
*/
long now = (new Date()).getTime();
/**
* Validity date
*/
Date validity;
validity = new Date(now + this.tokenValidityInMilliseconds);
/**
* Create token
* @param authentication auth info
* @return token
*/
public String createToken(Authentication authentication) {
/**
* Current time
*/
long now = (new Date()).getTime();
/**
* Validity date
*/
Date validity;
validity = new Date(now + this.tokenValidityInMilliseconds);
/**
* create token
*/
return Jwts.builder()
.setSubject(authentication.getName())
.claim(AUTHORITIES_KEY, "")
.setExpiration(validity)
.signWith(secretKey, SignatureAlgorithm.HS256)
.compact();
}
/**
* create token
*/
return Jwts.builder().setSubject(authentication.getName()).claim(AUTHORITIES_KEY, "").setExpiration(validity)
.signWith(secretKey, SignatureAlgorithm.HS256).compact();
}
/**
* Get auth Info
*
* @param token token
* @return auth info
*/
public Authentication getAuthentication(String token) {
/**
* parse the payload of token
*/
Claims claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
/**
* Get auth Info
* @param token token
* @return auth info
*/
public Authentication getAuthentication(String token) {
/**
* parse the payload of token
*/
Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
List<GrantedAuthority> authorities = AuthorityUtils
.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
}
User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
}
/**
* validate token
* @param token token
* @return whether valid
*/
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
return true;
}
catch (SignatureException e) {
log.info("Invalid JWT signature.");
log.trace("Invalid JWT signature trace: {}", e);
}
catch (MalformedJwtException e) {
log.info("Invalid JWT token.");
log.trace("Invalid JWT token trace: {}", e);
}
catch (ExpiredJwtException e) {
log.info("Expired JWT token.");
log.trace("Expired JWT token trace: {}", e);
}
catch (UnsupportedJwtException e) {
log.info("Unsupported JWT token.");
log.trace("Unsupported JWT token trace: {}", e);
}
catch (IllegalArgumentException e) {
log.info("JWT token compact of handler are invalid.");
log.trace("JWT token compact of handler are invalid trace: {}", e);
}
return false;
}
/**
* validate token
*
* @param token token
* @return whether valid
*/
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
return true;
} catch (SignatureException e) {
log.info("Invalid JWT signature.");
log.trace("Invalid JWT signature trace: {}", e);
} catch (MalformedJwtException e) {
log.info("Invalid JWT token.");
log.trace("Invalid JWT token trace: {}", e);
} catch (ExpiredJwtException e) {
log.info("Expired JWT token.");
log.trace("Expired JWT token trace: {}", e);
} catch (UnsupportedJwtException e) {
log.info("Unsupported JWT token.");
log.trace("Unsupported JWT token trace: {}", e);
} catch (IllegalArgumentException e) {
log.info("JWT token compact of handler are invalid.");
log.trace("JWT token compact of handler are invalid trace: {}", e);
}
return false;
}
}
@@ -24,15 +24,16 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
*/
public class PasswordEncoderUtil {
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("nacos"));
}
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("nacos"));
}
public static Boolean matches(String raw, String encoded) {
return new BCryptPasswordEncoder().matches(raw, encoded);
}
public static Boolean matches(String raw, String encoded) {
return new BCryptPasswordEncoder().matches(raw, encoded);
}
public static String encode(String raw) {
return new BCryptPasswordEncoder().encode(raw);
}
public static String encode(String raw) {
return new BCryptPasswordEncoder().encode(raw);
}
}