diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java index 35d1d819..74bef319 100755 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/endpoint/PigTokenEndpoint.java @@ -19,12 +19,10 @@ package com.pig4cloud.pig.auth.endpoint; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.pig4cloud.pig.auth.handler.PigLogoutSuccessEventHandler; import com.pig4cloud.pig.common.core.constant.CacheConstants; import com.pig4cloud.pig.common.core.constant.CommonConstants; import com.pig4cloud.pig.common.core.util.R; import com.pig4cloud.pig.common.core.util.SpringContextHolder; -import com.pig4cloud.pig.common.log.event.SysLogEvent; import com.pig4cloud.pig.common.security.annotation.Inner; import com.pig4cloud.pig.common.security.util.SecurityUtils; import lombok.RequiredArgsConstructor; @@ -38,7 +36,6 @@ import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.http.HttpHeaders; -import org.springframework.security.authentication.event.AuthenticationSuccessEvent; import org.springframework.security.authentication.event.LogoutSuccessEvent; import org.springframework.security.oauth2.common.OAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2RefreshToken; @@ -148,7 +145,7 @@ public class PigTokenEndpoint { OAuth2RefreshToken refreshToken = accessToken.getRefreshToken(); tokenStore.removeRefreshToken(refreshToken); - //处理自定义退出事件,保存相关日志 + // 处理自定义退出事件,保存相关日志 SpringContextHolder.publishEvent(new LogoutSuccessEvent(auth2Authentication)); return R.ok(); } diff --git a/pig-auth/src/main/java/com/pig4cloud/pig/auth/handler/PigLogoutSuccessEventHandler.java b/pig-auth/src/main/java/com/pig4cloud/pig/auth/handler/PigLogoutSuccessEventHandler.java index 50edc245..f7908c75 100644 --- a/pig-auth/src/main/java/com/pig4cloud/pig/auth/handler/PigLogoutSuccessEventHandler.java +++ b/pig-auth/src/main/java/com/pig4cloud/pig/auth/handler/PigLogoutSuccessEventHandler.java @@ -39,7 +39,6 @@ public class PigLogoutSuccessEventHandler extends AbstractLogoutSuccessEventHand * 处理退出成功方法 *

* 获取到登录的authentication 对象 - * * @param authentication 登录对象 */ @Override diff --git a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java index c45808a4..ff0176e7 100755 --- a/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java +++ b/pig-common/pig-common-log/src/main/java/com/pig4cloud/pig/common/log/util/SysLogUtils.java @@ -69,13 +69,14 @@ public class SysLogUtils { OAuth2Authentication auth2Authentication = (OAuth2Authentication) authentication; return auth2Authentication.getOAuth2Request().getClientId(); } - if (authentication instanceof UsernamePasswordAuthenticationToken){ + if (authentication instanceof UsernamePasswordAuthenticationToken) { // 通过请求参数拿到clientId String authorizationHeaderValue = request.getHeader("Authorization"); String base64AuthorizationHeader = Optional.ofNullable(authorizationHeaderValue) - .map(headerValue->headerValue.substring("Basic ".length())).orElse(""); - if(StrUtil.isNotEmpty(base64AuthorizationHeader)) { - String decodedAuthorizationHeader = new String(Base64.getDecoder().decode(base64AuthorizationHeader), Charset.forName("UTF-8")); + .map(headerValue -> headerValue.substring("Basic ".length())).orElse(""); + if (StrUtil.isNotEmpty(base64AuthorizationHeader)) { + String decodedAuthorizationHeader = new String(Base64.getDecoder().decode(base64AuthorizationHeader), + Charset.forName("UTF-8")); return decodedAuthorizationHeader.split(":")[0]; } } diff --git a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/handler/AbstractLogoutSuccessEventHandler.java b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/handler/AbstractLogoutSuccessEventHandler.java index 0863cd2a..add83481 100644 --- a/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/handler/AbstractLogoutSuccessEventHandler.java +++ b/pig-common/pig-common-security/src/main/java/com/pig4cloud/pig/common/security/handler/AbstractLogoutSuccessEventHandler.java @@ -26,8 +26,7 @@ import org.springframework.security.core.Authentication; * @author zhangran * @date 2021/6/23 退出成功事件处理器 */ -public abstract class AbstractLogoutSuccessEventHandler - implements ApplicationListener { +public abstract class AbstractLogoutSuccessEventHandler implements ApplicationListener { /** * Handle an application event. diff --git a/pig-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java b/pig-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java index cb51b0a9..76d295fe 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java +++ b/pig-register/src/main/java/com/alibaba/nacos/config/ConsoleConfig.java @@ -42,37 +42,37 @@ import org.springframework.web.filter.CorsFilter; @EnableScheduling @PropertySource("/application.properties") public class ConsoleConfig { - - @Autowired - private ControllerMethodsCache methodsCache; - - /** - * Init. - */ - @PostConstruct - public void init() { - methodsCache.initClassMethod("com.alibaba.nacos.core.controller"); - methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers"); - methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller"); - methodsCache.initClassMethod("com.alibaba.nacos.controller"); - } - - @Bean - public CorsFilter corsFilter() { - CorsConfiguration config = new CorsConfiguration(); - config.setAllowCredentials(true); - config.addAllowedOrigin("*"); - config.addAllowedHeader("*"); - config.setMaxAge(18000L); - config.addAllowedMethod("*"); - UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/**", config); - return new CorsFilter(source); - } - - @Bean - public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() { - return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(ZoneId.systemDefault().toString()); - } + + @Autowired + private ControllerMethodsCache methodsCache; + + /** + * Init. + */ + @PostConstruct + public void init() { + methodsCache.initClassMethod("com.alibaba.nacos.core.controller"); + methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers"); + methodsCache.initClassMethod("com.alibaba.nacos.config.server.controller"); + methodsCache.initClassMethod("com.alibaba.nacos.controller"); + } + + @Bean + public CorsFilter corsFilter() { + CorsConfiguration config = new CorsConfiguration(); + config.setAllowCredentials(true); + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.setMaxAge(18000L); + config.addAllowedMethod("*"); + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } + + @Bean + public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() { + return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(ZoneId.systemDefault().toString()); + } } diff --git a/pig-register/src/main/java/com/alibaba/nacos/controller/HealthController.java b/pig-register/src/main/java/com/alibaba/nacos/controller/HealthController.java index cf889cb6..4cb798ac 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/controller/HealthController.java +++ b/pig-register/src/main/java/com/alibaba/nacos/controller/HealthController.java @@ -37,74 +37,77 @@ import javax.servlet.http.HttpServletRequest; @RestController("consoleHealth") @RequestMapping("/v1/console/health") public class HealthController { - - private static final Logger LOGGER = LoggerFactory.getLogger(HealthController.class); - - private final PersistService persistService; - - private final OperatorController apiCommands; - - @Autowired - public HealthController(PersistService persistService, OperatorController apiCommands) { - this.persistService = persistService; - this.apiCommands = 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"); - } - - /** - * 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.ok().body("OK"); - } - - if (!isConfigReadiness && !isNamingReadiness) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config and Naming are not in readiness"); - } - - if (!isConfigReadiness) { - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config is not in readiness"); - } - - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).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 static final Logger LOGGER = LoggerFactory.getLogger(HealthController.class); + + private final PersistService persistService; + + private final OperatorController apiCommands; + + @Autowired + public HealthController(PersistService persistService, OperatorController apiCommands) { + this.persistService = persistService; + this.apiCommands = 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"); + } + + /** + * 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.ok().body("OK"); + } + + if (!isConfigReadiness && !isNamingReadiness) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("Config and Naming are not in readiness"); + } + + if (!isConfigReadiness) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Config is not in readiness"); + } + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).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; + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/controller/NamespaceController.java b/pig-register/src/main/java/com/alibaba/nacos/controller/NamespaceController.java index b9b7c20a..6a9d6070 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/controller/NamespaceController.java +++ b/pig-register/src/main/java/com/alibaba/nacos/controller/NamespaceController.java @@ -69,8 +69,7 @@ public class NamespaceController { /** * Get namespace list. - * - * @param request request + * @param request request * @param response response * @return namespace list */ @@ -78,8 +77,8 @@ public class NamespaceController { public RestResult> getNamespaces(HttpServletRequest request, HttpServletResponse response) { // TODO 获取用kp List tenantInfos = persistService.findTenantByKp(DEFAULT_KP); - Namespace namespace0 = new Namespace("", DEFAULT_NAMESPACE, DEFAULT_QUOTA, persistService.configInfoCount(DEFAULT_TENANT), - NamespaceTypeEnum.GLOBAL.getType()); + Namespace namespace0 = new Namespace("", DEFAULT_NAMESPACE, DEFAULT_QUOTA, + persistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType()); List namespaces = new ArrayList(); namespaces.add(namespace0); for (TenantInfo tenantInfo : tenantInfos) { @@ -93,32 +92,32 @@ public class NamespaceController { /** * get namespace all info by namespace id. - * - * @param request request - * @param response response + * @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) { + @RequestParam("namespaceId") String namespaceId) { // TODO 获取用kp if (StringUtils.isBlank(namespaceId)) { - return new NamespaceAllInfo(namespaceId, DEFAULT_NAMESPACE_SHOW_NAME, DEFAULT_QUOTA, persistService.configInfoCount(DEFAULT_TENANT), - NamespaceTypeEnum.GLOBAL.getType(), DEFAULT_NAMESPACE_DESCRIPTION); - } else { + return new NamespaceAllInfo(namespaceId, DEFAULT_NAMESPACE_SHOW_NAME, DEFAULT_QUOTA, + persistService.configInfoCount(DEFAULT_TENANT), NamespaceTypeEnum.GLOBAL.getType(), + DEFAULT_NAMESPACE_DESCRIPTION); + } + else { TenantInfo tenantInfo = persistService.findTenantByKp(DEFAULT_KP, namespaceId); int configCount = persistService.configInfoCount(namespaceId); - return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), DEFAULT_QUOTA, configCount, NamespaceTypeEnum.CUSTOM.getType(), - tenantInfo.getTenantDesc()); + return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), DEFAULT_QUOTA, configCount, + NamespaceTypeEnum.CUSTOM.getType(), tenantInfo.getTenantDesc()); } } /** * create namespace. - * - * @param request request - * @param response response + * @param request request + * @param response response * @param namespaceName namespace Name * @param namespaceDesc namespace Desc * @return whether create ok @@ -126,12 +125,13 @@ public class NamespaceController { @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) { + @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 { + } + else { namespaceId = namespaceId.trim(); if (!namespaceIdCheckPattern.matcher(namespaceId).matches()) { return false; @@ -143,14 +143,13 @@ public class NamespaceController { return false; } } - persistService.insertTenantInfoAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc, DEFAULT_CREATE_SOURCE, - System.currentTimeMillis()); + persistService.insertTenantInfoAtomic(DEFAULT_KP, namespaceId, namespaceName, namespaceDesc, + DEFAULT_CREATE_SOURCE, System.currentTimeMillis()); return true; } /** * check namespaceId exist. - * * @param namespaceId namespace id * @return true if exist, otherwise false */ @@ -164,17 +163,16 @@ public class NamespaceController { /** * edit namespace. - * - * @param namespace namespace + * @param namespace namespace * @param namespaceShowName namespace ShowName - * @param namespaceDesc namespace Desc + * @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) { + @RequestParam("namespaceShowName") String namespaceShowName, + @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { // TODO 获取用kp persistService.updateTenantNameAtomic(DEFAULT_KP, namespace, namespaceShowName, namespaceDesc); return true; @@ -182,16 +180,15 @@ public class NamespaceController { /** * del namespace by id. - * - * @param request request - * @param response response + * @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) { + @RequestParam("namespaceId") String namespaceId) { persistService.removeTenantInfoAtomic(DEFAULT_KP, namespaceId); return true; } diff --git a/pig-register/src/main/java/com/alibaba/nacos/controller/PermissionController.java b/pig-register/src/main/java/com/alibaba/nacos/controller/PermissionController.java index 1acb2d96..74cc79e1 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/controller/PermissionController.java +++ b/pig-register/src/main/java/com/alibaba/nacos/controller/PermissionController.java @@ -39,53 +39,51 @@ import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/v1/auth/permissions") public class PermissionController { - - @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); - } - - /** - * 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 RestResultUtils.success("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 RestResultUtils.success("delete permission ok!"); - } + + @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); + } + + /** + * 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 RestResultUtils.success("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 RestResultUtils.success("delete permission ok!"); + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/controller/RoleController.java b/pig-register/src/main/java/com/alibaba/nacos/controller/RoleController.java index 71a9c2be..5c31c376 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/controller/RoleController.java +++ b/pig-register/src/main/java/com/alibaba/nacos/controller/RoleController.java @@ -41,70 +41,69 @@ import java.util.List; @RestController @RequestMapping("/v1/auth/roles") public class RoleController { - - @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); - } - - /** - * Fuzzy matching role name . - * - * @param role role id - * @return role list - */ - @GetMapping("/search") - @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.READ) - public List searchRoles(@RequestParam String role) { - return roleService.findRolesLikeRoleName(role); - } - - /** - * Add a role to a user - * - *

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 role name - * @param username username - * @return Code 200 and message 'add role ok!' - */ - @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 RestResultUtils.success("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 RestResultUtils.success("delete role of user " + username + " ok!"); - } - + + @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); + } + + /** + * Fuzzy matching role name . + * @param role role id + * @return role list + */ + @GetMapping("/search") + @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.READ) + public List searchRoles(@RequestParam String role) { + return roleService.findRolesLikeRoleName(role); + } + + /** + * Add a role to a user + * + *

+ * 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 role name + * @param username username + * @return Code 200 and message 'add role ok!' + */ + @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 RestResultUtils.success("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 RestResultUtils.success("delete role of user " + username + " ok!"); + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/controller/ServerStateController.java b/pig-register/src/main/java/com/alibaba/nacos/controller/ServerStateController.java index c5c2db42..1ed07f9d 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/controller/ServerStateController.java +++ b/pig-register/src/main/java/com/alibaba/nacos/controller/ServerStateController.java @@ -34,22 +34,21 @@ import java.util.Map; @RestController @RequestMapping("/v1/console/server") public class ServerStateController { - - /** - * Get server state of current server. - * - * @return state json. - */ - @GetMapping("/state") - public ResponseEntity> serverState() { - Map serverState = new HashMap<>(4); - serverState.put("standalone_mode", - EnvUtil.getStandaloneMode() ? EnvUtil.STANDALONE_MODE_ALONE : EnvUtil.STANDALONE_MODE_CLUSTER); - - serverState.put("function_mode", EnvUtil.getFunctionMode()); - serverState.put("version", VersionUtils.version); - - return ResponseEntity.ok().body(serverState); - } - + + /** + * Get server state of current server. + * @return state json. + */ + @GetMapping("/state") + public ResponseEntity> serverState() { + Map serverState = new HashMap<>(4); + serverState.put("standalone_mode", + EnvUtil.getStandaloneMode() ? EnvUtil.STANDALONE_MODE_ALONE : EnvUtil.STANDALONE_MODE_CLUSTER); + + serverState.put("function_mode", EnvUtil.getFunctionMode()); + serverState.put("version", VersionUtils.version); + + return ResponseEntity.ok().body(serverState); + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/controller/UserController.java b/pig-register/src/main/java/com/alibaba/nacos/controller/UserController.java index ffb02a06..8f40fd64 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/controller/UserController.java +++ b/pig-register/src/main/java/com/alibaba/nacos/controller/UserController.java @@ -65,218 +65,217 @@ 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 JwtTokenManager jwtTokenManager; - - @Autowired - private AuthenticationManager authenticationManager; - - @Autowired - private NacosUserDetailsServiceImpl userDetailsService; - - @Autowired - private NacosRoleServiceImpl roleService; - - @Autowired - private AuthConfigs authConfigs; - - @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) { - - User user = userDetailsService.getUserFromDatabase(username); - if (user != null) { - throw new IllegalArgumentException("user '" + username + "' already exist!"); - } - userDetailsService.createUser(username, PasswordEncoderUtil.encode(password)); - return RestResultUtils.success("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 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 RestResultUtils.success("delete user ok!"); - } - - /** - * Update an user. - * - * @param username username of user - * @param newPassword new password of user - * @param response http response - * @param request http request - * @return ok if update succeed - * @throws IllegalArgumentException if user not exist or oldPassword is incorrect - * @since 1.2.0 - */ - @PutMapping - @Secured(resource = NacosAuthConfig.UPDATE_PASSWORD_ENTRY_POINT, action = ActionTypes.WRITE) - public Object updateUser(@RequestParam String username, @RequestParam String newPassword, - HttpServletResponse response, HttpServletRequest request) throws IOException { - // admin or same user - if (!hasPermission(username, request)) { - response.sendError(HttpServletResponse.SC_FORBIDDEN, "authorization failed!"); - } - User user = userDetailsService.getUserFromDatabase(username); - if (user == null) { - throw new IllegalArgumentException("user " + username + " not exist!"); - } - - userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword)); - - return RestResultUtils.success("update user ok!"); - } + @Autowired + private JwtTokenManager jwtTokenManager; - private boolean hasPermission(String username, HttpServletRequest request) { - if (!authConfigs.isAuthEnabled()) { - return true; - } - if (Objects.isNull(request.getAttribute(RequestUtil.NACOS_USER_KEY))) { - return false; - } + @Autowired + private AuthenticationManager authenticationManager; - NacosUser user = (NacosUser) request.getAttribute(RequestUtil.NACOS_USER_KEY); - // admin - if (user.isGlobalAdmin()) { - return true; - } - // same user - return user.getUserName().equals(username); - } - - /** - * 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 - * - *

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()) || AuthSystemTypes.LDAP - .name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { - NacosUser user = (NacosUser) authManager.login(request); - - response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, NacosAuthConfig.TOKEN_PREFIX + user.getToken()); - - ObjectNode result = JacksonUtils.createEmptyJsonNode(); - result.put(Constants.ACCESS_TOKEN, user.getToken()); - result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds()); - result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin()); - result.put(Constants.USERNAME, user.getUserName()); - return result; - } - - // create Authentication class through username and password, the implement class is UsernamePasswordAuthenticationToken - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, - password); - - try { - // use the method authenticate of AuthenticationManager(default implement is ProviderManager) to valid Authentication - Authentication authentication = authenticationManager.authenticate(authenticationToken); - // bind SecurityContext to Authentication - SecurityContextHolder.getContext().setAuthentication(authentication); - // generate Token - String token = jwtTokenManager.createToken(authentication); - // write Token to Http header - response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token); - return RestResultUtils.success("Bearer " + token); - } catch (BadCredentialsException authentication) { - return RestResultUtils.failed(HttpStatus.UNAUTHORIZED.value(), null, "Login failed"); - } - } - - /** - * Update password. - * - * @param oldPassword old password - * @param newPassword new password - * @return Code 200 if update successfully, Code 401 if old password invalid, otherwise 500 - */ - @PutMapping("/password") - @Deprecated - public RestResult updatePassword(@RequestParam(value = "oldPassword") String oldPassword, - @RequestParam(value = "newPassword") String newPassword) { - 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)); - return RestResultUtils.success("Update password success"); - } - return RestResultUtils.failed(HttpStatus.UNAUTHORIZED.value(), "Old password is invalid"); - } catch (Exception e) { - return RestResultUtils.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Update userpassword failed"); - } - } + @Autowired + private NacosUserDetailsServiceImpl userDetailsService; + @Autowired + private NacosRoleServiceImpl roleService; + + @Autowired + private AuthConfigs authConfigs; + + @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) { + + User user = userDetailsService.getUserFromDatabase(username); + if (user != null) { + throw new IllegalArgumentException("user '" + username + "' already exist!"); + } + userDetailsService.createUser(username, PasswordEncoderUtil.encode(password)); + return RestResultUtils.success("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 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 RestResultUtils.success("delete user ok!"); + } + + /** + * Update an user. + * @param username username of user + * @param newPassword new password of user + * @param response http response + * @param request http request + * @return ok if update succeed + * @throws IllegalArgumentException if user not exist or oldPassword is incorrect + * @since 1.2.0 + */ + @PutMapping + @Secured(resource = NacosAuthConfig.UPDATE_PASSWORD_ENTRY_POINT, action = ActionTypes.WRITE) + public Object updateUser(@RequestParam String username, @RequestParam String newPassword, + HttpServletResponse response, HttpServletRequest request) throws IOException { + // admin or same user + if (!hasPermission(username, request)) { + response.sendError(HttpServletResponse.SC_FORBIDDEN, "authorization failed!"); + } + + User user = userDetailsService.getUserFromDatabase(username); + if (user == null) { + throw new IllegalArgumentException("user " + username + " not exist!"); + } + + userDetailsService.updateUserPassword(username, PasswordEncoderUtil.encode(newPassword)); + + return RestResultUtils.success("update user ok!"); + } + + private boolean hasPermission(String username, HttpServletRequest request) { + if (!authConfigs.isAuthEnabled()) { + return true; + } + if (Objects.isNull(request.getAttribute(RequestUtil.NACOS_USER_KEY))) { + return false; + } + + NacosUser user = (NacosUser) request.getAttribute(RequestUtil.NACOS_USER_KEY); + // admin + if (user.isGlobalAdmin()) { + return true; + } + // same user + return user.getUserName().equals(username); + } + + /** + * 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 + * + *

+ * 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()) + || AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { + NacosUser user = (NacosUser) authManager.login(request); + + response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, NacosAuthConfig.TOKEN_PREFIX + user.getToken()); + + ObjectNode result = JacksonUtils.createEmptyJsonNode(); + result.put(Constants.ACCESS_TOKEN, user.getToken()); + result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds()); + result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin()); + result.put(Constants.USERNAME, user.getUserName()); + return result; + } + + // create Authentication class through username and password, the implement class + // is UsernamePasswordAuthenticationToken + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, + password); + + try { + // use the method authenticate of AuthenticationManager(default implement is + // ProviderManager) to valid Authentication + Authentication authentication = authenticationManager.authenticate(authenticationToken); + // bind SecurityContext to Authentication + SecurityContextHolder.getContext().setAuthentication(authentication); + // generate Token + String token = jwtTokenManager.createToken(authentication); + // write Token to Http header + response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, "Bearer " + token); + return RestResultUtils.success("Bearer " + token); + } + catch (BadCredentialsException authentication) { + return RestResultUtils.failed(HttpStatus.UNAUTHORIZED.value(), null, "Login failed"); + } + } + + /** + * Update password. + * @param oldPassword old password + * @param newPassword new password + * @return Code 200 if update successfully, Code 401 if old password invalid, + * otherwise 500 + */ + @PutMapping("/password") + @Deprecated + public RestResult updatePassword(@RequestParam(value = "oldPassword") String oldPassword, + @RequestParam(value = "newPassword") String newPassword) { + 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)); + return RestResultUtils.success("Update password success"); + } + return RestResultUtils.failed(HttpStatus.UNAUTHORIZED.value(), "Old password is invalid"); + } + catch (Exception e) { + return RestResultUtils.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Update userpassword failed"); + } + } + + /** + * Fuzzy matching username. + * @param username username + * @return Matched username + */ + @GetMapping("/search") + @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE) + public List searchUsersLikeUsername(@RequestParam String username) { + return userDetailsService.findUserLikeUsername(username); + } - /** - * Fuzzy matching username. - * - * @param username username - * @return Matched username - */ - @GetMapping("/search") - @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "users", action = ActionTypes.WRITE) - public List searchUsersLikeUsername(@RequestParam String username) { - return userDetailsService.findUserLikeUsername(username); - } } diff --git a/pig-register/src/main/java/com/alibaba/nacos/enums/NamespaceTypeEnum.java b/pig-register/src/main/java/com/alibaba/nacos/enums/NamespaceTypeEnum.java index 9960af78..a82a39b2 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/enums/NamespaceTypeEnum.java +++ b/pig-register/src/main/java/com/alibaba/nacos/enums/NamespaceTypeEnum.java @@ -17,50 +17,50 @@ package com.alibaba.nacos.enums; /** - * the enum of namespace. - * 0 : Global configuration, 1 : Default private namespace ,2 : Custom namespace. + * 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; - } -} + /** + * 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; + } + +} diff --git a/pig-register/src/main/java/com/alibaba/nacos/filter/JwtAuthenticationTokenFilter.java b/pig-register/src/main/java/com/alibaba/nacos/filter/JwtAuthenticationTokenFilter.java index c92574ae..1f90c816 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/filter/JwtAuthenticationTokenFilter.java +++ b/pig-register/src/main/java/com/alibaba/nacos/filter/JwtAuthenticationTokenFilter.java @@ -36,41 +36,42 @@ import java.io.IOException; * @author wfnuser */ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { - - private static final String TOKEN_PREFIX = "Bearer "; - - private final JwtTokenManager tokenManager; - - public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) { - this.tokenManager = tokenManager; - } - - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) - throws IOException, ServletException { - - 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); - } - - /** - * 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(TOKEN_PREFIX.length()); - } - String jwt = request.getParameter(Constants.ACCESS_TOKEN); - if (StringUtils.isNotBlank(jwt)) { - return jwt; - } - return null; - } + + private static final String TOKEN_PREFIX = "Bearer "; + + private final JwtTokenManager tokenManager; + + public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) { + this.tokenManager = tokenManager; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) + throws IOException, ServletException { + + 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); + } + + /** + * 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(TOKEN_PREFIX.length()); + } + String jwt = request.getParameter(Constants.ACCESS_TOKEN); + if (StringUtils.isNotBlank(jwt)) { + return jwt; + } + return null; + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/model/Namespace.java b/pig-register/src/main/java/com/alibaba/nacos/model/Namespace.java index dd69b7b7..66882355 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/model/Namespace.java +++ b/pig-register/src/main/java/com/alibaba/nacos/model/Namespace.java @@ -22,74 +22,74 @@ package com.alibaba.nacos.model; * @author diamond */ public class Namespace { - - private String namespace; - - private String namespaceShowName; - - private int quota; - - private int configCount; - - /** - * see {@link com.alibaba.nacos.console.enums.NamespaceTypeEnum}. - */ - private int type; - - public String getNamespaceShowName() { - return namespaceShowName; - } - - public void setNamespaceShowName(String namespaceShowName) { - this.namespaceShowName = namespaceShowName; - } - - public String getNamespace() { - return namespace; - } - - public void setNamespace(String namespace) { - this.namespace = namespace; - } - - public Namespace() { - } - - public Namespace(String namespace, String namespaceShowName) { - this.namespace = namespace; - this.namespaceShowName = namespaceShowName; - } - - 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 int getQuota() { - return quota; - } - - public void setQuota(int quota) { - this.quota = quota; - } - - public int getConfigCount() { - return configCount; - } - - public void setConfigCount(int configCount) { - this.configCount = configCount; - } - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - + + private String namespace; + + private String namespaceShowName; + + private int quota; + + private int configCount; + + /** + * see {@link com.alibaba.nacos.console.enums.NamespaceTypeEnum}. + */ + private int type; + + public String getNamespaceShowName() { + return namespaceShowName; + } + + public void setNamespaceShowName(String namespaceShowName) { + this.namespaceShowName = namespaceShowName; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public Namespace() { + } + + public Namespace(String namespace, String namespaceShowName) { + this.namespace = namespace; + this.namespaceShowName = namespaceShowName; + } + + 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 int getQuota() { + return quota; + } + + public void setQuota(int quota) { + this.quota = quota; + } + + public int getConfigCount() { + return configCount; + } + + public void setConfigCount(int configCount) { + this.configCount = configCount; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/JwtTokenManager.java b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/JwtTokenManager.java index 19d1d026..c908b9bf 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/JwtTokenManager.java +++ b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/JwtTokenManager.java @@ -40,64 +40,60 @@ import java.util.List; */ @Component public class JwtTokenManager { - - private static final String AUTHORITIES_KEY = "auth"; - - @Autowired - private AuthConfigs authConfigs; - - /** - * Create token. - * - * @param authentication auth info - * @return token - */ - public String createToken(Authentication authentication) { - return createToken(authentication.getName()); - } - - /** - * Create token. - * - * @param userName auth info - * @return token - */ - public String createToken(String userName) { - - long now = System.currentTimeMillis(); - - Date validity; - validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L); - - Claims claims = Jwts.claims().setSubject(userName); - return Jwts.builder().setClaims(claims).setExpiration(validity) - .signWith(Keys.hmacShaKeyFor(authConfigs.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact(); - } - - /** - * Get auth Info. - * - * @param token token - * @return auth info - */ - public Authentication getAuthentication(String token) { - Claims claims = Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build() - .parseClaimsJws(token).getBody(); - - List authorities = AuthorityUtils - .commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); - - User principal = new User(claims.getSubject(), "", authorities); - return new UsernamePasswordAuthenticationToken(principal, "", authorities); - } - - /** - * validate token. - * - * @param token token - */ - public void validateToken(String token) { - Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build().parseClaimsJws(token); - } - + + private static final String AUTHORITIES_KEY = "auth"; + + @Autowired + private AuthConfigs authConfigs; + + /** + * Create token. + * @param authentication auth info + * @return token + */ + public String createToken(Authentication authentication) { + return createToken(authentication.getName()); + } + + /** + * Create token. + * @param userName auth info + * @return token + */ + public String createToken(String userName) { + + long now = System.currentTimeMillis(); + + Date validity; + validity = new Date(now + authConfigs.getTokenValidityInSeconds() * 1000L); + + Claims claims = Jwts.claims().setSubject(userName); + return Jwts.builder().setClaims(claims).setExpiration(validity) + .signWith(Keys.hmacShaKeyFor(authConfigs.getSecretKeyBytes()), SignatureAlgorithm.HS256).compact(); + } + + /** + * Get auth Info. + * @param token token + * @return auth info + */ + public Authentication getAuthentication(String token) { + Claims claims = Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build() + .parseClaimsJws(token).getBody(); + + List authorities = AuthorityUtils + .commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); + + User principal = new User(claims.getSubject(), "", authorities); + return new UsernamePasswordAuthenticationToken(principal, "", authorities); + } + + /** + * validate token. + * @param token token + */ + public void validateToken(String token) { + Jwts.parserBuilder().setSigningKey(authConfigs.getSecretKeyBytes()).build().parseClaimsJws(token); + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/LdapAuthenticationProvider.java b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/LdapAuthenticationProvider.java index 4471a46e..45e0e0b5 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/LdapAuthenticationProvider.java +++ b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/LdapAuthenticationProvider.java @@ -45,7 +45,6 @@ import java.util.List; import static com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE; - /** * LDAP auth provider. * @@ -53,114 +52,121 @@ import static com.alibaba.nacos.security.nacos.roles.NacosRoleServiceImpl.GLOBAL */ @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 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 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); - } - } - } + + 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 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 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); + } + } + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthConfig.java b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthConfig.java index 638d5145..0a0dcd1b 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthConfig.java +++ b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthConfig.java @@ -44,95 +44,97 @@ 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 SECURITY_IGNORE_URLS_SPILT_CHAR = ","; - - 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_PREFIX = "Bearer "; - - public static final String CONSOLE_RESOURCE_NAME_PREFIX = "console/"; - 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"; + public static final String AUTHORIZATION_HEADER = "Authorization"; + + public static final String SECURITY_IGNORE_URLS_SPILT_CHAR = ","; + + 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_PREFIX = "Bearer "; + + public static final String CONSOLE_RESOURCE_NAME_PREFIX = "console/"; + + 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 + private Environment env; + + @Autowired + private JwtTokenManager tokenProvider; + + @Autowired + private AuthConfigs authConfigs; + + @Autowired + private NacosUserDetailsServiceImpl userDetailsService; + + @Autowired + private LdapAuthenticationProvider ldapAuthenticationProvider; + + @Bean(name = BeanIds.AUTHENTICATION_MANAGER) + @Override + public AuthenticationManager authenticationManagerBean() throws Exception { + return super.authenticationManagerBean(); + } + + @Override + public void configure(WebSecurity web) { + + String ignoreUrls = null; + if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { + ignoreUrls = DEFAULT_ALL_PATH_PATTERN; + } + else if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { + ignoreUrls = DEFAULT_ALL_PATH_PATTERN; + } + if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { + ignoreUrls = env.getProperty(PROPERTY_IGNORE_URLS, DEFAULT_ALL_PATH_PATTERN); + } + if (StringUtils.isNotBlank(ignoreUrls)) { + for (String each : ignoreUrls.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) { + web.ignoring().antMatchers(each.trim()); + } + } + } + + @Override + protected void configure(AuthenticationManagerBuilder auth) throws Exception { + if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { + auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); + } + else if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { + auth.authenticationProvider(ldapAuthenticationProvider); + } + } + + @Override + protected void configure(HttpSecurity http) throws Exception { + + if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { + http.csrf().disable().cors()// We don't need CSRF for JWT based authentication + .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).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 + http.headers().cacheControl(); + + http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), + UsernamePasswordAuthenticationFilter.class); + } + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } - @Autowired - private Environment env; - - @Autowired - private JwtTokenManager tokenProvider; - - @Autowired - private AuthConfigs authConfigs; - - @Autowired - private NacosUserDetailsServiceImpl userDetailsService; - - @Autowired - private LdapAuthenticationProvider ldapAuthenticationProvider; - - @Bean(name = BeanIds.AUTHENTICATION_MANAGER) - @Override - public AuthenticationManager authenticationManagerBean() throws Exception { - return super.authenticationManagerBean(); - } - - @Override - public void configure(WebSecurity web) { - - String ignoreUrls = null; - if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { - ignoreUrls = DEFAULT_ALL_PATH_PATTERN; - } else if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { - ignoreUrls = DEFAULT_ALL_PATH_PATTERN; - } - if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { - ignoreUrls = env.getProperty(PROPERTY_IGNORE_URLS, DEFAULT_ALL_PATH_PATTERN); - } - if (StringUtils.isNotBlank(ignoreUrls)) { - for (String each : ignoreUrls.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) { - web.ignoring().antMatchers(each.trim()); - } - } - } - - @Override - protected void configure(AuthenticationManagerBuilder auth) throws Exception { - if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { - auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); - } else if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { - auth.authenticationProvider(ldapAuthenticationProvider); - } - } - - @Override - protected void configure(HttpSecurity http) throws Exception { - - if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { - http.csrf().disable().cors()// We don't need CSRF for JWT based authentication - .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .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 - http.headers().cacheControl(); - - http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), - UsernamePasswordAuthenticationFilter.class); - } - } - - @Bean - public PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } - } diff --git a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthManager.java b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthManager.java index 77f25865..14ae7ad5 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthManager.java +++ b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/NacosAuthManager.java @@ -48,157 +48,164 @@ import java.util.List; */ @Component public class NacosAuthManager implements AuthManager { - - private static final String TOKEN_PREFIX = "Bearer "; - - private static final String PARAM_USERNAME = "username"; - - private static final String PARAM_PASSWORD = "password"; - - @Autowired - private JwtTokenManager tokenManager; - - @Autowired - private AuthenticationManager authenticationManager; - - @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!"); - } - - 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 roleInfoList = roleService.getRoles(username); - if (roleInfoList != null) { - for (RoleInfo roleInfo : roleInfoList) { - if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) { - user.setGlobalAdmin(true); - break; - } - } - } - req.setAttribute(RequestUtil.NACOS_USER_KEY, 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 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 - 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!"); - } - } - - /** - * 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(PARAM_USERNAME); - 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); - } - - return bearerToken; - } - - private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException { - String finalName; - Authentication authenticate; - try { - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, - rawPassword); - authenticate = authenticationManager.authenticate(authenticationToken); - } catch (AuthenticationException e) { - throw new AccessException("unknown user!"); - } - - if (null == authenticate || StringUtils.isBlank(authenticate.getName())) { - finalName = userName; - } else { - finalName = authenticate.getName(); - } - - return tokenManager.createToken(finalName); - } + + private static final String TOKEN_PREFIX = "Bearer "; + + private static final String PARAM_USERNAME = "username"; + + private static final String PARAM_PASSWORD = "password"; + + @Autowired + private JwtTokenManager tokenManager; + + @Autowired + private AuthenticationManager authenticationManager; + + @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!"); + } + + 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 roleInfoList = roleService.getRoles(username); + if (roleInfoList != null) { + for (RoleInfo roleInfo : roleInfoList) { + if (roleInfo.getRole().equals(NacosRoleServiceImpl.GLOBAL_ADMIN_ROLE)) { + user.setGlobalAdmin(true); + break; + } + } + } + req.setAttribute(RequestUtil.NACOS_USER_KEY, 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 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 + 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!"); + } + } + + /** + * 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(PARAM_USERNAME); + 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); + } + + return bearerToken; + } + + private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException { + String finalName; + Authentication authenticate; + try { + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, + rawPassword); + authenticate = authenticationManager.authenticate(authenticationToken); + } + catch (AuthenticationException e) { + throw new AccessException("unknown user!"); + } + + if (null == authenticate || StringUtils.isBlank(authenticate.getName())) { + finalName = userName; + } + else { + finalName = authenticate.getName(); + } + + return tokenManager.createToken(finalName); + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/roles/NacosRoleServiceImpl.java b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/roles/NacosRoleServiceImpl.java index 8a3fd090..4b9102e5 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/roles/NacosRoleServiceImpl.java +++ b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/roles/NacosRoleServiceImpl.java @@ -49,200 +49,201 @@ import java.util.regex.Pattern; */ @Service public class NacosRoleServiceImpl { - - public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN"; - - private static final int DEFAULT_PAGE_NO = 1; - - @Autowired - private AuthConfigs authConfigs; - - @Autowired - private RolePersistService rolePersistService; - - @Autowired - private NacosUserDetailsServiceImpl userDetailsService; - - @Autowired - private PermissionPersistService permissionPersistService; - - private volatile Set roleSet = new ConcurrentHashSet<>(); - - private volatile Map> roleInfoMap = new ConcurrentHashMap<>(); - - private volatile Map> permissionInfoMap = new ConcurrentHashMap<>(); - - @Scheduled(initialDelay = 5000, fixedDelay = 15000) - private void reload() { - try { - Page roleInfoPage = rolePersistService - .getRolesByUserName(StringUtils.EMPTY, DEFAULT_PAGE_NO, Integer.MAX_VALUE); - if (roleInfoPage == null) { - return; - } - Set tmpRoleSet = new HashSet<>(16); - Map> 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> tmpPermissionInfoMap = new ConcurrentHashMap<>(16); - for (String role : tmpRoleSet) { - Page permissionInfoPage = permissionPersistService - .getPermissions(role, DEFAULT_PAGE_NO, 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); - } - } - - /** - * Determine if the user has permission of the resource. - * - *

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) { - //update password - if (NacosAuthConfig.UPDATE_PASSWORD_ENTRY_POINT.equals(permission.getResource())) { - return true; - } - List 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; - } - } - - // 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 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 getRoles(String username) { - List roleInfoList = roleInfoMap.get(username); - if (!authConfigs.isCachingEnabled()) { - Page roleInfoPage = getRolesFromDatabase(username, DEFAULT_PAGE_NO, Integer.MAX_VALUE); - if (roleInfoPage != null) { - roleInfoList = roleInfoPage.getPageItems(); - } - } - return roleInfoList; - } - - public Page getRolesFromDatabase(String userName, int pageNo, int pageSize) { - Page roles = rolePersistService.getRolesByUserName(userName, pageNo, pageSize); - if (roles == null) { - return new Page<>(); - } - return roles; - } - - public List getPermissions(String role) { - List permissionInfoList = permissionInfoMap.get(role); - if (!authConfigs.isCachingEnabled()) { - Page permissionInfoPage = getPermissionsFromDatabase(role, DEFAULT_PAGE_NO, Integer.MAX_VALUE); - if (permissionInfoPage != null) { - permissionInfoList = permissionInfoPage.getPageItems(); - } - } - return permissionInfoList; - } - - public Page getPermissionsByRoleFromDatabase(String role, int pageNo, int pageSize) { - return permissionPersistService.getPermissions(role, pageNo, pageSize); - } - - /** - * Add role. - * - * @param role role name - * @param username user name - */ - public void addRole(String role, String username) { - if (userDetailsService.getUserFromDatabase(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) { - rolePersistService.deleteRole(role); - roleSet.remove(role); - } - - public Page getPermissionsFromDatabase(String role, int pageNo, int pageSize) { - Page pageInfo = permissionPersistService.getPermissions(role, pageNo, pageSize); - if (pageInfo == null) { - return new Page<>(); - } - return pageInfo; - } - - /** - * Add permission. - * - * @param role role name - * @param resource resource - * @param action 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 List findRolesLikeRoleName(String role) { - return rolePersistService.findRolesLikeRoleName(role); - } + public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN"; + + private static final int DEFAULT_PAGE_NO = 1; + + @Autowired + private AuthConfigs authConfigs; + + @Autowired + private RolePersistService rolePersistService; + + @Autowired + private NacosUserDetailsServiceImpl userDetailsService; + + @Autowired + private PermissionPersistService permissionPersistService; + + private volatile Set roleSet = new ConcurrentHashSet<>(); + + private volatile Map> roleInfoMap = new ConcurrentHashMap<>(); + + private volatile Map> permissionInfoMap = new ConcurrentHashMap<>(); + + @Scheduled(initialDelay = 5000, fixedDelay = 15000) + private void reload() { + try { + Page roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, DEFAULT_PAGE_NO, + Integer.MAX_VALUE); + if (roleInfoPage == null) { + return; + } + Set tmpRoleSet = new HashSet<>(16); + Map> 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> tmpPermissionInfoMap = new ConcurrentHashMap<>(16); + for (String role : tmpRoleSet) { + Page permissionInfoPage = permissionPersistService.getPermissions(role, DEFAULT_PAGE_NO, + 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); + } + } + + /** + * Determine if the user has permission of the resource. + * + *

+ * 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) { + // update password + if (NacosAuthConfig.UPDATE_PASSWORD_ENTRY_POINT.equals(permission.getResource())) { + return true; + } + + List 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; + } + } + + // 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 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 getRoles(String username) { + List roleInfoList = roleInfoMap.get(username); + if (!authConfigs.isCachingEnabled()) { + Page roleInfoPage = getRolesFromDatabase(username, DEFAULT_PAGE_NO, Integer.MAX_VALUE); + if (roleInfoPage != null) { + roleInfoList = roleInfoPage.getPageItems(); + } + } + return roleInfoList; + } + + public Page getRolesFromDatabase(String userName, int pageNo, int pageSize) { + Page roles = rolePersistService.getRolesByUserName(userName, pageNo, pageSize); + if (roles == null) { + return new Page<>(); + } + return roles; + } + + public List getPermissions(String role) { + List permissionInfoList = permissionInfoMap.get(role); + if (!authConfigs.isCachingEnabled()) { + Page permissionInfoPage = getPermissionsFromDatabase(role, DEFAULT_PAGE_NO, + Integer.MAX_VALUE); + if (permissionInfoPage != null) { + permissionInfoList = permissionInfoPage.getPageItems(); + } + } + return permissionInfoList; + } + + public Page getPermissionsByRoleFromDatabase(String role, int pageNo, int pageSize) { + return permissionPersistService.getPermissions(role, pageNo, pageSize); + } + + /** + * Add role. + * @param role role name + * @param username user name + */ + public void addRole(String role, String username) { + if (userDetailsService.getUserFromDatabase(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) { + rolePersistService.deleteRole(role); + roleSet.remove(role); + } + + public Page getPermissionsFromDatabase(String role, int pageNo, int pageSize) { + Page pageInfo = permissionPersistService.getPermissions(role, pageNo, pageSize); + if (pageInfo == null) { + return new Page<>(); + } + return pageInfo; + } + + /** + * Add permission. + * @param role role name + * @param resource resource + * @param action 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 List findRolesLikeRoleName(String role) { + return rolePersistService.findRolesLikeRoleName(role); + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetails.java b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetails.java index fc90ff6e..cc75e038 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetails.java +++ b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetails.java @@ -29,46 +29,47 @@ import java.util.Collection; * @author wfnuser */ public class NacosUserDetails implements UserDetails { - - private final User user; - - public NacosUserDetails(User user) { - this.user = user; - } - - @Override - public Collection getAuthorities() { - // TODO: get authorities - return AuthorityUtils.commaSeparatedStringToAuthorityList(""); - } - - @Override - public String getPassword() { - return user.getPassword(); - } - - @Override - public String getUsername() { - return user.getUsername(); - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } - - @Override - public boolean isEnabled() { - return true; - } + + private final User user; + + public NacosUserDetails(User user) { + this.user = user; + } + + @Override + public Collection getAuthorities() { + // TODO: get authorities + return AuthorityUtils.commaSeparatedStringToAuthorityList(""); + } + + @Override + public String getPassword() { + return user.getPassword(); + } + + @Override + public String getUsername() { + return user.getUsername(); + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } + } diff --git a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetailsServiceImpl.java b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetailsServiceImpl.java index 674bd81b..c8c1acb1 100644 --- a/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetailsServiceImpl.java +++ b/pig-register/src/main/java/com/alibaba/nacos/security/nacos/users/NacosUserDetailsServiceImpl.java @@ -40,76 +40,78 @@ import java.util.concurrent.ConcurrentHashMap; */ @Service public class NacosUserDetailsServiceImpl implements UserDetailsService { - - private Map userMap = new ConcurrentHashMap<>(); - - @Autowired - private UserPersistService userPersistService; - - @Autowired - private AuthConfigs authConfigs; - - @Scheduled(initialDelay = 5000, fixedDelay = 15000) - private void reload() { - try { - Page users = getUsersFromDatabase(1, Integer.MAX_VALUE); - if (users == null) { - return; - } - - Map 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 { - - User user = userMap.get(username); - if (!authConfigs.isCachingEnabled()) { - user = userPersistService.findUserByUsername(username); - } - - if (user == null) { - throw new UsernameNotFoundException(username); - } - return new NacosUserDetails(user); - } - - public void updateUserPassword(String username, String password) { - userPersistService.updateUserPassword(username, password); - } - - public Page 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 getUserFromDatabase(String username) { - return userPersistService.findUserByUsername(username); - } - public List findUserLikeUsername(String username) { - return userPersistService.findUserLikeUsername(username); - } + private Map userMap = new ConcurrentHashMap<>(); + + @Autowired + private UserPersistService userPersistService; + + @Autowired + private AuthConfigs authConfigs; + + @Scheduled(initialDelay = 5000, fixedDelay = 15000) + private void reload() { + try { + Page users = getUsersFromDatabase(1, Integer.MAX_VALUE); + if (users == null) { + return; + } + + Map 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 { + + User user = userMap.get(username); + if (!authConfigs.isCachingEnabled()) { + user = userPersistService.findUserByUsername(username); + } + + if (user == null) { + throw new UsernameNotFoundException(username); + } + return new NacosUserDetails(user); + } + + public void updateUserPassword(String username, String password) { + userPersistService.updateUserPassword(username, password); + } + + public Page 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 getUserFromDatabase(String username) { + return userPersistService.findUserByUsername(username); + } + + public List findUserLikeUsername(String username) { + return userPersistService.findUserLikeUsername(username); + } + + public void createUser(String username, String password) { + userPersistService.createUser(username, password); + } + + public void deleteUser(String username) { + userPersistService.deleteUser(username); + } - public void createUser(String username, String password) { - userPersistService.createUser(username, password); - } - - public void deleteUser(String username) { - userPersistService.deleteUser(username); - } }