Use new code style for nacos-console module. (#3195)

This commit is contained in:
杨翊 SionYang 2020-06-29 13:55:42 +08:00 committed by GitHub
parent c9bf5f2f70
commit 0a65aa8976
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 537 additions and 491 deletions

View File

@ -21,9 +21,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.concurrent.*;
/** /**
* Nacos starter.
*
* @author nacos * @author nacos
*/ */
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos") @SpringBootApplication(scanBasePackages = "com.alibaba.nacos")

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.config;
package com.alibaba.nacos.console.config;
import com.alibaba.nacos.core.code.ControllerMethodsCache; import com.alibaba.nacos.core.code.ControllerMethodsCache;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -29,6 +29,8 @@ import org.springframework.web.filter.CorsFilter;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
/** /**
* Console config.
*
* @author yshen * @author yshen
* @author nkorange * @author nkorange
* @since 1.2.0 * @since 1.2.0
@ -41,6 +43,9 @@ public class ConsoleConfig {
@Autowired @Autowired
private ControllerMethodsCache methodsCache; private ControllerMethodsCache methodsCache;
/**
* Init.
*/
@PostConstruct @PostConstruct
public void init() { public void init() {
methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers"); methodsCache.initClassMethod("com.alibaba.nacos.naming.controllers");
@ -50,13 +55,13 @@ public class ConsoleConfig {
@Bean @Bean
public CorsFilter corsFilter() { public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration(); CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); config.setAllowCredentials(true);
config.addAllowedOrigin("*"); config.addAllowedOrigin("*");
config.addAllowedHeader("*"); config.addAllowedHeader("*");
config.setMaxAge(18000L); config.setMaxAge(18000L);
config.addAllowedMethod("*"); config.addAllowedMethod("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); source.registerCorsConfiguration("/**", config);
return new CorsFilter(source); return new CorsFilter(source);
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.controller; package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.config.server.service.repository.PersistService;
@ -28,15 +29,18 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
* Health Controller.
*
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a> * @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
*/ */
@RestController("consoleHealth") @RestController("consoleHealth")
@RequestMapping("/v1/console/health") @RequestMapping("/v1/console/health")
public class HealthController { public class HealthController {
private static final Logger logger = LoggerFactory.getLogger(HealthController.class); private static final Logger LOGGER = LoggerFactory.getLogger(HealthController.class);
private final PersistService persistService; private final PersistService persistService;
private final OperatorController apiCommands; private final OperatorController apiCommands;
@Autowired @Autowired
@ -46,7 +50,7 @@ public class HealthController {
} }
/** /**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted * 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 * @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states. * Nacos is in broken states.
@ -57,7 +61,7 @@ public class HealthController {
} }
/** /**
* Ready to receive the request or not * 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 * @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
* ready. * ready.
@ -88,7 +92,7 @@ public class HealthController {
persistService.configInfoCount(""); persistService.configInfoCount("");
return true; return true;
} catch (Exception e) { } catch (Exception e) {
logger.error("Config health check fail.", e); LOGGER.error("Config health check fail.", e);
} }
return false; return false;
} }
@ -98,7 +102,7 @@ public class HealthController {
apiCommands.metrics(request); apiCommands.metrics(request);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
logger.error("Naming health check fail.", e); LOGGER.error("Naming health check fail.", e);
} }
return false; return false;
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.controller; package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResult;
@ -25,7 +26,13 @@ import com.alibaba.nacos.core.auth.ActionTypes;
import com.alibaba.nacos.core.auth.Secured; import com.alibaba.nacos.core.auth.Secured;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -35,7 +42,7 @@ import java.util.UUID;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** /**
* namespace service * namespace service.
* *
* @author Nacos * @author Nacos
*/ */
@ -46,12 +53,12 @@ public class NamespaceController {
@Autowired @Autowired
private PersistService persistService; private PersistService persistService;
private Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+"); private final Pattern namespaceIdCheckPattern = Pattern.compile("^[\\w-]+");
private static final int NAMESPACE_ID_MAX_LENGTH = 128; private static final int NAMESPACE_ID_MAX_LENGTH = 128;
/** /**
* Get namespace list * Get namespace list.
* *
* @param request request * @param request request
* @param response response * @param response response
@ -77,7 +84,7 @@ public class NamespaceController {
} }
/** /**
* get namespace all info by namespace id * get namespace all info by namespace id.
* *
* @param request request * @param request request
* @param response response * @param response response
@ -89,18 +96,18 @@ public class NamespaceController {
@RequestParam("namespaceId") String namespaceId) { @RequestParam("namespaceId") String namespaceId) {
// TODO 获取用kp // TODO 获取用kp
if (StringUtils.isBlank(namespaceId)) { if (StringUtils.isBlank(namespaceId)) {
return new NamespaceAllInfo(namespaceId, "Public", 200, return new NamespaceAllInfo(namespaceId, "Public", 200, persistService.configInfoCount(""), 0,
persistService.configInfoCount(""), 0, "Public Namespace"); "Public Namespace");
} else { } else {
TenantInfo tenantInfo = persistService.findTenantByKp("1", namespaceId); TenantInfo tenantInfo = persistService.findTenantByKp("1", namespaceId);
int configCount = persistService.configInfoCount(namespaceId); int configCount = persistService.configInfoCount(namespaceId);
return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200, return new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200, configCount, 2,
configCount, 2, tenantInfo.getTenantDesc()); tenantInfo.getTenantDesc());
} }
} }
/** /**
* create namespace * create namespace.
* *
* @param request request * @param request request
* @param response response * @param response response
@ -111,11 +118,10 @@ public class NamespaceController {
@PostMapping @PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE) @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "namespaces", action = ActionTypes.WRITE)
public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response, public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("customNamespaceId") String namespaceId, @RequestParam("customNamespaceId") String namespaceId, @RequestParam("namespaceName") String namespaceName,
@RequestParam("namespaceName") String namespaceName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) { @RequestParam(value = "namespaceDesc", required = false) String namespaceDesc) {
// TODO 获取用kp // TODO 获取用kp
if(StringUtils.isBlank(namespaceId)){ if (StringUtils.isBlank(namespaceId)) {
namespaceId = UUID.randomUUID().toString(); namespaceId = UUID.randomUUID().toString();
} else { } else {
namespaceId = namespaceId.trim(); namespaceId = namespaceId.trim();
@ -125,7 +131,7 @@ public class NamespaceController {
if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) { if (namespaceId.length() > NAMESPACE_ID_MAX_LENGTH) {
return false; return false;
} }
if(persistService.tenantInfoCountByTenantId(namespaceId) > 0){ if (persistService.tenantInfoCountByTenantId(namespaceId) > 0) {
return false; return false;
} }
} }
@ -135,22 +141,21 @@ public class NamespaceController {
} }
/** /**
* @author klw(213539@qq.com) * check namespaceId exist.
* @Description: check namespaceId exist *
* @Date 2019/12/10 21:41 * @param namespaceId namespace id
* @param: namespaceId * @return true if exist, otherwise false
* @return java.lang.Boolean
*/ */
@GetMapping(params = "checkNamespaceIdExist=true") @GetMapping(params = "checkNamespaceIdExist=true")
public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId){ public Boolean checkNamespaceIdExist(@RequestParam("customNamespaceId") String namespaceId) {
if(StringUtils.isBlank(namespaceId)){ if (StringUtils.isBlank(namespaceId)) {
return false; return false;
} }
return (persistService.tenantInfoCountByTenantId(namespaceId) > 0); return (persistService.tenantInfoCountByTenantId(namespaceId) > 0);
} }
/** /**
* edit namespace * edit namespace.
* *
* @param namespace namespace * @param namespace namespace
* @param namespaceShowName namespace ShowName * @param namespaceShowName namespace ShowName
@ -168,7 +173,7 @@ public class NamespaceController {
} }
/** /**
* del namespace by id * del namespace by id.
* *
* @param request request * @param request request
* @param response response * @param response response

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.controller;
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.console.security.nacos.NacosAuthConfig; import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
@ -23,11 +23,15 @@ import com.alibaba.nacos.core.auth.ActionTypes;
import com.alibaba.nacos.core.auth.Secured; import com.alibaba.nacos.core.auth.Secured;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/** /**
* Permission operation controller * Permission operation controller.
* *
* @author nkorange * @author nkorange
* @since 1.2.0 * @since 1.2.0
@ -40,7 +44,7 @@ public class PermissionController {
private NacosRoleServiceImpl nacosRoleService; private NacosRoleServiceImpl nacosRoleService;
/** /**
* Query permissions of a role * Query permissions of a role.
* *
* @param role the role * @param role the role
* @param pageNo page index * @param pageNo page index
@ -55,7 +59,7 @@ public class PermissionController {
} }
/** /**
* Add a permission to a role * Add a permission to a role.
* *
* @param role the role * @param role the role
* @param resource the related resource * @param resource the related resource
@ -70,7 +74,7 @@ public class PermissionController {
} }
/** /**
* Delete a permission from a role * Delete a permission from a role.
* *
* @param role the role * @param role the role
* @param resource the related resource * @param resource the related resource
@ -79,7 +83,8 @@ public class PermissionController {
*/ */
@DeleteMapping @DeleteMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE) @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "permissions", action = ActionTypes.WRITE)
public Object deletePermission(@RequestParam String role, @RequestParam String resource, @RequestParam String action) { public Object deletePermission(@RequestParam String role, @RequestParam String resource,
@RequestParam String action) {
nacosRoleService.deletePermission(role, resource, action); nacosRoleService.deletePermission(role, resource, action);
return new RestResult<>(200, "delete permission ok!"); return new RestResult<>(200, "delete permission ok!");
} }

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.controller;
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.console.security.nacos.NacosAuthConfig; import com.alibaba.nacos.console.security.nacos.NacosAuthConfig;
@ -23,10 +23,15 @@ import com.alibaba.nacos.core.auth.ActionTypes;
import com.alibaba.nacos.core.auth.Secured; import com.alibaba.nacos.core.auth.Secured;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/** /**
* Role operation controller * Role operation controller.
* *
* @author nkorange * @author nkorange
* @since 1.2.0 * @since 1.2.0
@ -39,7 +44,7 @@ public class RoleController {
private NacosRoleServiceImpl roleService; private NacosRoleServiceImpl roleService;
/** /**
* Get roles list * Get roles list.
* *
* @param pageNo number index of page * @param pageNo number index of page
* @param pageSize page size * @param pageSize page size
@ -55,14 +60,12 @@ public class RoleController {
/** /**
* Add a role to a user * Add a role to a user
* <p>
* This method is used for 2 functions:
* 1. create a role and bind it to GLOBAL_ADMIN.
* 2. bind a role to an user.
* *
* @param role * <p>This method is used for 2 functions: 1. create a role and bind it to GLOBAL_ADMIN. 2. bind a role to an user.
* @param username *
* @return * @param role role name
* @param username username
* @return Code 200 and message 'add role ok!'
*/ */
@PostMapping @PostMapping
@Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE) @Secured(resource = NacosAuthConfig.CONSOLE_RESOURCE_NAME_PREFIX + "roles", action = ActionTypes.WRITE)
@ -72,7 +75,7 @@ public class RoleController {
} }
/** /**
* Delete a role. If no username is specified, all users under this role are deleted * Delete a role. If no username is specified, all users under this role are deleted.
* *
* @param role role * @param role role
* @param username username * @param username username

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.controller;
package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.utils.VersionUtils; import com.alibaba.nacos.common.utils.VersionUtils;
import com.alibaba.nacos.core.utils.ApplicationUtils; import com.alibaba.nacos.core.utils.ApplicationUtils;
@ -27,18 +27,24 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* @author xingxuechao * Server state controller.
* on:2019/2/27 11:17 AM *
* @author xingxuechao on:2019/2/27 11:17 AM
*/ */
@RestController @RestController
@RequestMapping("/v1/console/server") @RequestMapping("/v1/console/server")
public class ServerStateController { public class ServerStateController {
/**
* Get server state of current server.
*
* @return state json.
*/
@GetMapping("/state") @GetMapping("/state")
public ResponseEntity serverState() { public ResponseEntity serverState() {
Map<String,String> serverState = new HashMap<>(3); Map<String, String> serverState = new HashMap<>(3);
serverState.put("standalone_mode", ApplicationUtils.getStandaloneMode() ? serverState.put("standalone_mode", ApplicationUtils.getStandaloneMode() ? ApplicationUtils.STANDALONE_MODE_ALONE
ApplicationUtils.STANDALONE_MODE_ALONE : ApplicationUtils.STANDALONE_MODE_CLUSTER); : ApplicationUtils.STANDALONE_MODE_CLUSTER);
serverState.put("function_mode", ApplicationUtils.getFunctionMode()); serverState.put("function_mode", ApplicationUtils.getFunctionMode());
serverState.put("version", VersionUtils.version); serverState.put("version", VersionUtils.version);

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.controller; package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
@ -27,9 +28,12 @@ import com.alibaba.nacos.console.security.nacos.users.NacosUser;
import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
import com.alibaba.nacos.console.utils.JwtTokenUtils; import com.alibaba.nacos.console.utils.JwtTokenUtils;
import com.alibaba.nacos.console.utils.PasswordEncoderUtil; import com.alibaba.nacos.console.utils.PasswordEncoderUtil;
import com.alibaba.nacos.core.auth.*; import com.alibaba.nacos.core.auth.AccessException;
import com.alibaba.nacos.core.auth.ActionTypes;
import com.alibaba.nacos.core.auth.AuthConfigs;
import com.alibaba.nacos.core.auth.AuthSystemTypes;
import com.alibaba.nacos.core.auth.Secured;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
@ -37,14 +41,20 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.List; import java.util.List;
/** /**
* User related methods entry * User related methods entry.
* *
* @author wfnuser * @author wfnuser
* @author nkorange * @author nkorange
@ -72,7 +82,7 @@ public class UserController {
private NacosAuthManager authManager; private NacosAuthManager authManager;
/** /**
* Create a new user * Create a new user.
* *
* @param username username * @param username username
* @param password password * @param password password
@ -93,7 +103,7 @@ public class UserController {
} }
/** /**
* Delete an existed user * Delete an existed user.
* *
* @param username username of user * @param username username of user
* @return ok if deleted succeed, keep silent if user not exist * @return ok if deleted succeed, keep silent if user not exist
@ -115,7 +125,7 @@ public class UserController {
} }
/** /**
* Update an user * Update an user.
* *
* @param username username of user * @param username username of user
* @param newPassword new password of user * @param newPassword new password of user
@ -138,7 +148,7 @@ public class UserController {
} }
/** /**
* Get paged users * Get paged users.
* *
* @param pageNo number index of page * @param pageNo number index of page
* @param pageSize size of page * @param pageSize size of page
@ -153,8 +163,8 @@ public class UserController {
/** /**
* Login to Nacos * Login to Nacos
* <p> *
* This methods uses username and password to require a new token. * <p>This methods uses username and password to require a new token.
* *
* @param username username of user * @param username username of user
* @param password password * @param password password
@ -164,18 +174,16 @@ public class UserController {
* @throws AccessException if user info is incorrect * @throws AccessException if user info is incorrect
*/ */
@PostMapping("/login") @PostMapping("/login")
public Object login(@RequestParam String username, @RequestParam String password, public Object login(@RequestParam String username, @RequestParam String password, HttpServletResponse response,
HttpServletResponse response, HttpServletRequest request) throws AccessException { HttpServletRequest request) throws AccessException {
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
NacosUser user = (NacosUser) authManager.login(request); NacosUser user = (NacosUser) authManager.login(request);
response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, response.addHeader(NacosAuthConfig.AUTHORIZATION_HEADER, NacosAuthConfig.TOKEN_PREFIX + user.getToken());
NacosAuthConfig.TOKEN_PREFIX + user.getToken());
ObjectNode result = JacksonUtils.createEmptyJsonNode(); ObjectNode result = JacksonUtils.createEmptyJsonNode();
// JSONObject result = new JSONObject(); // JSONObject result = new JSONObject();
result.put(Constants.ACCESS_TOKEN, user.getToken()); result.put(Constants.ACCESS_TOKEN, user.getToken());
result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds()); result.put(Constants.TOKEN_TTL, authConfigs.getTokenValidityInSeconds());
result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin()); result.put(Constants.GLOBAL_ADMIN, user.isGlobalAdmin());
@ -183,7 +191,8 @@ public class UserController {
} }
// 通过用户名和密码创建一个 Authentication 认证对象实现类为 UsernamePasswordAuthenticationToken // 通过用户名和密码创建一个 Authentication 认证对象实现类为 UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,
password);
RestResult<String> rr = new RestResult<String>(); RestResult<String> rr = new RestResult<String>();
try { try {
@ -205,6 +214,13 @@ public class UserController {
} }
} }
/**
* 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") @PutMapping("/password")
@Deprecated @Deprecated
public RestResult<String> updatePassword(@RequestParam(value = "oldPassword") String oldPassword, public RestResult<String> updatePassword(@RequestParam(value = "oldPassword") String oldPassword,

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.exception; package com.alibaba.nacos.console.exception;
import com.alibaba.nacos.common.utils.ExceptionUtil; import com.alibaba.nacos.common.utils.ExceptionUtil;
@ -25,7 +26,7 @@ import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ExceptionHandler;
/** /**
* Exception handler for console module * Exception handler for console module.
* *
* @author nkorange * @author nkorange
* @since 1.2.0 * @since 1.2.0
@ -33,7 +34,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice @ControllerAdvice
public class ConsoleExceptionHandler { public class ConsoleExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(ConsoleExceptionHandler.class); private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleExceptionHandler.class);
@ExceptionHandler(AccessException.class) @ExceptionHandler(AccessException.class)
private ResponseEntity<String> handleAccessException(AccessException e) { private ResponseEntity<String> handleAccessException(AccessException e) {
@ -47,7 +48,7 @@ public class ConsoleExceptionHandler {
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
private ResponseEntity<String> handleException(Exception e) { private ResponseEntity<String> handleException(Exception e) {
logger.error("CONSOLE", e); LOGGER.error("CONSOLE", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ExceptionUtil.getAllExceptionMsg(e)); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ExceptionUtil.getAllExceptionMsg(e));
} }
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.filter; package com.alibaba.nacos.console.filter;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
@ -30,7 +31,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
/** /**
* jwt auth token filter * jwt auth token filter.
* *
* @author wfnuser * @author wfnuser
*/ */
@ -38,7 +39,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private static final String TOKEN_PREFIX = "Bearer "; private static final String TOKEN_PREFIX = "Bearer ";
private JwtTokenManager tokenManager; private final JwtTokenManager tokenManager;
public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) { public JwtAuthenticationTokenFilter(JwtTokenManager tokenManager) {
this.tokenManager = tokenManager; this.tokenManager = tokenManager;
@ -59,7 +60,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
} }
/** /**
* Get token from header * Get token from header.
*/ */
private String resolveToken(HttpServletRequest request) { private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER); String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);

View File

@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.model; package com.alibaba.nacos.console.model;
/** /**
* Namespace * Namespace.
* *
* @author diamond * @author diamond
*/ */
@ -29,8 +30,9 @@ public class Namespace {
private int quota; private int quota;
private int configCount; private int configCount;
/** /**
* 0 : Global configuration 1 : Default private namespace 2 : Custom namespace * 0 : Global configuration 1 : Default private namespace 2 : Custom namespace.
*/ */
private int type; private int type;

View File

@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.model; package com.alibaba.nacos.console.model;
/** /**
* all namespace info * all namespace info.
* *
* @author Nacos * @author Nacos
*/ */

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos; package com.alibaba.nacos.console.security.nacos;
import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
@ -25,7 +26,7 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* auth provider * auth provider.
* *
* @author wfnuser * @author wfnuser
*/ */

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos; package com.alibaba.nacos.console.security.nacos;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -27,20 +28,19 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
/** /**
* jwt auth fail point * jwt auth fail point.
* *
* @author wfnuser * @author wfnuser
*/ */
@Component @Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class); private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
@Override @Override
public void commence(HttpServletRequest request, public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
HttpServletResponse response, throws IOException, ServletException {
AuthenticationException e) throws IOException, ServletException { LOGGER.error("Responding with unauthorized error. Message:{}, url:{}", e.getMessage(), request.getRequestURI());
logger.error("Responding with unauthorized error. Message:{}, url:{}", e.getMessage(), request.getRequestURI());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized"); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
} }
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos; package com.alibaba.nacos.console.security.nacos;
import com.alibaba.nacos.core.auth.AuthConfigs; import com.alibaba.nacos.core.auth.AuthConfigs;
@ -27,12 +28,11 @@ import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
/** /**
* JWT token manager * JWT token manager.
* *
* @author wfnuser * @author wfnuser
* @author nkorange * @author nkorange
@ -46,7 +46,7 @@ public class JwtTokenManager {
private AuthConfigs authConfigs; private AuthConfigs authConfigs;
/** /**
* Create token * Create token.
* *
* @param authentication auth info * @param authentication auth info
* @return token * @return token
@ -55,6 +55,12 @@ public class JwtTokenManager {
return createToken(authentication.getName()); return createToken(authentication.getName());
} }
/**
* Create token.
*
* @param userName auth info
* @return token
*/
public String createToken(String userName) { public String createToken(String userName) {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
@ -64,39 +70,31 @@ public class JwtTokenManager {
Claims claims = Jwts.claims().setSubject(userName); Claims claims = Jwts.claims().setSubject(userName);
return Jwts.builder() return Jwts.builder().setClaims(claims).setExpiration(validity)
.setClaims(claims) .signWith(SignatureAlgorithm.HS256, authConfigs.getSecretKey()).compact();
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, authConfigs.getSecretKey())
.compact();
} }
/** /**
* Get auth Info * Get auth Info.
* *
* @param token token * @param token token
* @return auth info * @return auth info
*/ */
public Authentication getAuthentication(String token) { public Authentication getAuthentication(String token) {
/**
* parse the payload of token
*/
Claims claims = Jwts.parser()
.setSigningKey(authConfigs.getSecretKey())
.parseClaimsJws(token)
.getBody();
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); Claims claims = Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token).getBody();
List<GrantedAuthority> authorities = AuthorityUtils
.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
User principal = new User(claims.getSubject(), "", authorities); User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities); return new UsernamePasswordAuthenticationToken(principal, "", authorities);
} }
/** /**
* validate token * validate token.
* *
* @param token token * @param token token
* @return whether valid
*/ */
public void validateToken(String token) { public void validateToken(String token) {
Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token); Jwts.parser().setSigningKey(authConfigs.getSecretKey()).parseClaimsJws(token);

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos;
package com.alibaba.nacos.console.security.nacos;
import com.alibaba.nacos.console.filter.JwtAuthenticationTokenFilter; import com.alibaba.nacos.console.filter.JwtAuthenticationTokenFilter;
import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.console.security.nacos.users.NacosUserDetailsServiceImpl;
@ -23,7 +23,6 @@ import com.alibaba.nacos.core.auth.AuthSystemTypes;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds; import org.springframework.security.config.BeanIds;
@ -39,7 +38,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
import org.springframework.web.cors.CorsUtils; import org.springframework.web.cors.CorsUtils;
/** /**
* Spring security config * Spring security config.
* *
* @author Nacos * @author Nacos
*/ */
@ -79,22 +78,18 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
@Override @Override
public void configure(WebSecurity web) { public void configure(WebSecurity web) {
String ignoreURLs = null; String ignoreUrls = null;
//
if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) {
ignoreURLs = "/**"; ignoreUrls = "/**";
} }
//
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**"); ignoreUrls = env.getProperty("nacos.security.ignore.urls", "/**");
} }
if (StringUtils.isNotBlank(ignoreUrls)) {
if (StringUtils.isNotBlank(ignoreURLs)) { for (String each : ignoreUrls.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) { web.ignoring().antMatchers(each.trim());
web.ignoring().antMatchers(ignoreURL.trim());
} }
} }
} }
@Override @Override
@ -108,30 +103,22 @@ public class NacosAuthConfig extends WebSecurityConfigurerAdapter {
if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) { if (StringUtils.isBlank(authConfigs.getNacosAuthSystemType())) {
http http
.csrf().disable() .csrf().disable().cors() // We don't need CSRF for JWT based authentication
.cors() // We don't need CSRF for JWT based authentication
.and() .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and() .and().authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.authorizeRequests()
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
.antMatchers(LOGIN_ENTRY_POINT).permitAll() .antMatchers(LOGIN_ENTRY_POINT).permitAll()
.and() .and().authorizeRequests().antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.authorizeRequests()
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated()
.and() .and().exceptionHandling().authenticationEntryPoint(new JwtAuthenticationEntryPoint());
.exceptionHandling()
.authenticationEntryPoint(new JwtAuthenticationEntryPoint());
// disable cache // disable cache
http.headers().cacheControl(); http.headers().cacheControl();
http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider),
UsernamePasswordAuthenticationFilter.class);
} }
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos; package com.alibaba.nacos.console.security.nacos;
import com.alibaba.nacos.api.common.Constants; import com.alibaba.nacos.api.common.Constants;
@ -38,7 +39,7 @@ import javax.servlet.http.HttpServletRequest;
import java.util.List; import java.util.List;
/** /**
* Builtin access control entry of Nacos * Builtin access control entry of Nacos.
* *
* @author nkorange * @author nkorange
* @since 1.2.0 * @since 1.2.0
@ -105,7 +106,7 @@ public class NacosAuthManager implements AuthManager {
} }
/** /**
* Get token from header * Get token from header.
*/ */
private String resolveToken(HttpServletRequest request) throws AccessException { private String resolveToken(HttpServletRequest request) throws AccessException {
String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER); String bearerToken = request.getHeader(NacosAuthConfig.AUTHORIZATION_HEADER);
@ -125,7 +126,8 @@ public class NacosAuthManager implements AuthManager {
private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException { private String resolveTokenFromUser(String userName, String rawPassword) throws AccessException {
try { try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName, rawPassword); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userName,
rawPassword);
authenticationManager.authenticate(authenticationToken); authenticationManager.authenticate(authenticationToken);
} catch (AuthenticationException e) { } catch (AuthenticationException e) {
throw new AccessException("unknown user!"); throw new AccessException("unknown user!");

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos.roles;
package com.alibaba.nacos.console.security.nacos.roles;
import com.alibaba.nacos.config.server.auth.PermissionInfo; import com.alibaba.nacos.config.server.auth.PermissionInfo;
import com.alibaba.nacos.config.server.auth.PermissionPersistService; import com.alibaba.nacos.config.server.auth.PermissionPersistService;
@ -33,8 +33,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct; import java.util.ArrayList;
import java.util.*; import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -61,16 +64,17 @@ public class NacosRoleServiceImpl {
@Autowired @Autowired
private PermissionPersistService permissionPersistService; private PermissionPersistService permissionPersistService;
private Set<String> roleSet = new ConcurrentHashSet<>(); private final Set<String> roleSet = new ConcurrentHashSet<>();
private Map<String, List<RoleInfo>> roleInfoMap = new ConcurrentHashMap<>(); private final Map<String, List<RoleInfo>> roleInfoMap = new ConcurrentHashMap<>();
private Map<String, List<PermissionInfo>> permissionInfoMap = new ConcurrentHashMap<>(); private final Map<String, List<PermissionInfo>> permissionInfoMap = new ConcurrentHashMap<>();
@Scheduled(initialDelay = 5000, fixedDelay = 15000) @Scheduled(initialDelay = 5000, fixedDelay = 15000)
private void reload() { private void reload() {
try { try {
Page<RoleInfo> roleInfoPage = rolePersistService.getRolesByUserName(StringUtils.EMPTY, 1, Integer.MAX_VALUE); Page<RoleInfo> roleInfoPage = rolePersistService
.getRolesByUserName(StringUtils.EMPTY, 1, Integer.MAX_VALUE);
if (roleInfoPage == null) { if (roleInfoPage == null) {
return; return;
} }
@ -86,7 +90,8 @@ public class NacosRoleServiceImpl {
Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16); Map<String, List<PermissionInfo>> tmpPermissionInfoMap = new ConcurrentHashMap<>(16);
for (String role : tmpRoleSet) { for (String role : tmpRoleSet) {
Page<PermissionInfo> permissionInfoPage = permissionPersistService.getPermissions(role, 1, Integer.MAX_VALUE); Page<PermissionInfo> permissionInfoPage = permissionPersistService
.getPermissions(role, 1, Integer.MAX_VALUE);
tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems()); tmpPermissionInfoMap.put(role, permissionInfoPage.getPageItems());
} }
@ -100,9 +105,9 @@ public class NacosRoleServiceImpl {
/** /**
* Determine if the user has permission of the resource. * Determine if the user has permission of the resource.
* <p> *
* Note if the user has many roles, this method returns true if any one role of the user has the * <p>Note if the user has many roles, this method returns true if any one role of the user has the desired
* desired permission. * permission.
* *
* @param username user info * @param username user info
* @param permission permission to auth * @param permission permission to auth
@ -136,8 +141,8 @@ public class NacosRoleServiceImpl {
for (PermissionInfo permissionInfo : permissionInfoList) { for (PermissionInfo permissionInfo : permissionInfoList) {
String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*"); String permissionResource = permissionInfo.getResource().replaceAll("\\*", ".*");
String permissionAction = permissionInfo.getAction(); String permissionAction = permissionInfo.getAction();
if (permissionAction.contains(permission.getAction()) && if (permissionAction.contains(permission.getAction()) && Pattern
Pattern.matches(permissionResource, permission.getResource())) { .matches(permissionResource, permission.getResource())) {
return true; return true;
} }
} }
@ -179,6 +184,12 @@ public class NacosRoleServiceImpl {
return permissionPersistService.getPermissions(role, pageNo, pageSize); return permissionPersistService.getPermissions(role, pageNo, pageSize);
} }
/**
* Add role.
*
* @param role role name
* @param username user name
*/
public void addRole(String role, String username) { public void addRole(String role, String username) {
if (userDetailsService.getUserFromDatabase(username) == null) { if (userDetailsService.getUserFromDatabase(username) == null) {
throw new IllegalArgumentException("user '" + username + "' not found!"); throw new IllegalArgumentException("user '" + username + "' not found!");
@ -207,6 +218,13 @@ public class NacosRoleServiceImpl {
return pageInfo; return pageInfo;
} }
/**
* Add permission.
*
* @param role role name
* @param resource resource
* @param action action
*/
public void addPermission(String role, String resource, String action) { public void addPermission(String role, String resource, String action) {
if (!roleSet.contains(role)) { if (!roleSet.contains(role)) {
throw new IllegalArgumentException("role " + role + " not found!"); throw new IllegalArgumentException("role " + role + " not found!");

View File

@ -19,6 +19,8 @@ package com.alibaba.nacos.console.security.nacos.users;
import com.alibaba.nacos.core.auth.User; import com.alibaba.nacos.core.auth.User;
/** /**
* Nacos User.
*
* @author nkorange * @author nkorange
* @since 1.2.0 * @since 1.2.0
*/ */
@ -46,9 +48,6 @@ public class NacosUser extends User {
@Override @Override
public String toString() { public String toString() {
return "NacosUser{" + return "NacosUser{" + "token='" + token + '\'' + ", globalAdmin=" + globalAdmin + '}';
"token='" + token + '\'' +
", globalAdmin=" + globalAdmin +
'}';
} }
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos.users; package com.alibaba.nacos.console.security.nacos.users;
import com.alibaba.nacos.config.server.model.User; import com.alibaba.nacos.config.server.model.User;
@ -23,13 +24,13 @@ import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection; import java.util.Collection;
/** /**
* custem user * custom user.
* *
* @author wfnuser * @author wfnuser
*/ */
public class NacosUserDetails implements UserDetails { public class NacosUserDetails implements UserDetails {
private User user; private final User user;
public NacosUserDetails(User user) { public NacosUserDetails(User user) {
this.user = user; this.user = user;

View File

@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.security.nacos.users;
package com.alibaba.nacos.console.security.nacos.users;
import com.alibaba.nacos.config.server.auth.UserPersistService; import com.alibaba.nacos.config.server.auth.UserPersistService;
import com.alibaba.nacos.config.server.model.Page; import com.alibaba.nacos.config.server.model.Page;
@ -28,12 +28,11 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* Custem user service * Custem user service.
* *
* @author wfnuser * @author wfnuser
* @author nkorange * @author nkorange

View File

@ -13,9 +13,16 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.utils; package com.alibaba.nacos.console.utils;
import io.jsonwebtoken.*; import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.security.Keys; import io.jsonwebtoken.security.Keys;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -34,7 +41,7 @@ import java.util.List;
/** /**
* Jwt token tool * Jwt token tool.
* *
* @author wfnuser * @author wfnuser
*/ */
@ -46,31 +53,34 @@ public class JwtTokenUtils {
private static final String AUTHORITIES_KEY = "auth"; private static final String AUTHORITIES_KEY = "auth";
/** /**
* minimum SHA_256 secretKey string length * minimum SHA_256 secretKey string length.
*/ */
private static final int SHA_256_SECRET_CHAR_SIZE = 256 / 8; private static final int SHA_256_SECRET_CHAR_SIZE = 256 / 8;
/** /**
* default SHA_256 secretKey flag * default SHA_256 secretKey flag.
*/ */
private static final String DEFAULT_SECRET_FLAG = "default"; private static final String DEFAULT_SECRET_FLAG = "default";
/** /**
* custom SHA_256 secretKey from config property * custom SHA_256 secretKey from config property.
*/ */
@Value("${nacos.security.token.secret-key:default}") @Value("${nacos.security.token.secret-key:default}")
private String customSecretKeyStr; private String customSecretKeyStr;
/** /**
* secret key * secret key.
*/ */
private SecretKey secretKey; private SecretKey secretKey;
/** /**
* Token validity time(ms) * Token validity time(ms).
*/ */
private long tokenValidityInMilliseconds; private long tokenValidityInMilliseconds;
/**
* Init.
*/
@PostConstruct @PostConstruct
public void init() { public void init() {
//use default secretKey for SHA-256 //use default secretKey for SHA-256
@ -83,11 +93,11 @@ public class JwtTokenUtils {
if (left > 0) { if (left > 0) {
//character for padding //character for padding
StringBuilder stringBuilder = new StringBuilder(customSecretKeyStr); StringBuilder stringBuilder = new StringBuilder(customSecretKeyStr);
for (int i = 0 ;i < left ; i ++){ for (int i = 0; i < left; i++) {
stringBuilder.append(i%10); stringBuilder.append(i % 10);
} }
this.secretKey = Keys.hmacShaKeyFor(stringBuilder.toString().getBytes()); this.secretKey = Keys.hmacShaKeyFor(stringBuilder.toString().getBytes());
}else { } else {
this.secretKey = Keys.hmacShaKeyFor(customSecretKeyStr.getBytes()); this.secretKey = Keys.hmacShaKeyFor(customSecretKeyStr.getBytes());
} }
} }
@ -95,57 +105,40 @@ public class JwtTokenUtils {
} }
/** /**
* Create token * Create token.
* *
* @param authentication auth info * @param authentication auth info
* @return token * @return token
*/ */
public String createToken(Authentication authentication) { public String createToken(Authentication authentication) {
/**
* Current time
*/
long now = System.currentTimeMillis();
/**
* Validity date
*/
Date validity;
validity = new Date(now + this.tokenValidityInMilliseconds);
/** long now = System.currentTimeMillis();
* create token
*/ Date validity = new Date(now + this.tokenValidityInMilliseconds);
return Jwts.builder()
.setSubject(authentication.getName()) return Jwts.builder().setSubject(authentication.getName()).claim(AUTHORITIES_KEY, "").setExpiration(validity)
.claim(AUTHORITIES_KEY, "") .signWith(secretKey, SignatureAlgorithm.HS256).compact();
.setExpiration(validity)
.signWith(secretKey, SignatureAlgorithm.HS256)
.compact();
} }
/** /**
* Get auth Info * Get auth Info.
* *
* @param token token * @param token token
* @return auth info * @return auth info
*/ */
public Authentication getAuthentication(String token) { public Authentication getAuthentication(String token) {
/**
* parse the payload of token
*/
Claims claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY)); Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
List<GrantedAuthority> authorities = AuthorityUtils
.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
User principal = new User(claims.getSubject(), "", authorities); User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities); return new UsernamePasswordAuthenticationToken(principal, "", authorities);
} }
/** /**
* validate token * validate token.
* *
* @param token token * @param token token
* @return whether valid * @return whether valid

View File

@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.utils; package com.alibaba.nacos.console.utils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/** /**
* Password encoder tool * Password encoder tool.
* *
* @author nacos * @author nacos
*/ */

View File

@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.alibaba.nacos.console.controller; package com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.config.server.service.repository.PersistService; import com.alibaba.nacos.config.server.service.repository.PersistService;
import com.alibaba.nacos.naming.controllers.OperatorController; import com.alibaba.nacos.naming.controllers.OperatorController;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -40,9 +40,6 @@ import javax.servlet.http.HttpServletRequest;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
/**
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
*/
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MockServletContext.class) @ContextConfiguration(classes = MockServletContext.class)
@WebAppConfiguration @WebAppConfiguration
@ -81,18 +78,18 @@ public class HealthControllerTest {
Assert.assertEquals(200, mockmvc.perform(builder).andReturn().getResponse().getStatus()); Assert.assertEquals(200, mockmvc.perform(builder).andReturn().getResponse().getStatus());
// Config and Naming are not in readiness // Config and Naming are not in readiness
Mockito.when(persistService.configInfoCount(any(String.class))).thenThrow( Mockito.when(persistService.configInfoCount(any(String.class)))
new RuntimeException("HealthControllerTest.testReadiness")); .thenThrow(new RuntimeException("HealthControllerTest.testReadiness"));
Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenThrow( Mockito.when(apiCommands.metrics(any(HttpServletRequest.class)))
new RuntimeException("HealthControllerTest.testReadiness")); .thenThrow(new RuntimeException("HealthControllerTest.testReadiness"));
builder = MockMvcRequestBuilders.get(url); builder = MockMvcRequestBuilders.get(url);
MockHttpServletResponse response = mockmvc.perform(builder).andReturn().getResponse(); MockHttpServletResponse response = mockmvc.perform(builder).andReturn().getResponse();
Assert.assertEquals(500, response.getStatus()); Assert.assertEquals(500, response.getStatus());
Assert.assertEquals("Config and Naming are not in readiness", response.getContentAsString()); Assert.assertEquals("Config and Naming are not in readiness", response.getContentAsString());
// Config is not in readiness // Config is not in readiness
Mockito.when(persistService.configInfoCount(any(String.class))).thenThrow( Mockito.when(persistService.configInfoCount(any(String.class)))
new RuntimeException("HealthControllerTest.testReadiness")); .thenThrow(new RuntimeException("HealthControllerTest.testReadiness"));
Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenReturn(JacksonUtils.createEmptyJsonNode()); Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenReturn(JacksonUtils.createEmptyJsonNode());
response = mockmvc.perform(builder).andReturn().getResponse(); response = mockmvc.perform(builder).andReturn().getResponse();
Assert.assertEquals(500, response.getStatus()); Assert.assertEquals(500, response.getStatus());
@ -100,8 +97,8 @@ public class HealthControllerTest {
// Naming is not in readiness // Naming is not in readiness
Mockito.when(persistService.configInfoCount(any(String.class))).thenReturn(0); Mockito.when(persistService.configInfoCount(any(String.class))).thenReturn(0);
Mockito.when(apiCommands.metrics(any(HttpServletRequest.class))).thenThrow( Mockito.when(apiCommands.metrics(any(HttpServletRequest.class)))
new RuntimeException("HealthControllerTest.testReadiness")); .thenThrow(new RuntimeException("HealthControllerTest.testReadiness"));
builder = MockMvcRequestBuilders.get(url); builder = MockMvcRequestBuilders.get(url);
response = mockmvc.perform(builder).andReturn().getResponse(); response = mockmvc.perform(builder).andReturn().getResponse();
Assert.assertEquals(500, response.getStatus()); Assert.assertEquals(500, response.getStatus());

View File

@ -22,18 +22,19 @@ import com.alibaba.nacos.core.auth.AccessException;
import com.alibaba.nacos.core.auth.AuthConfigs; import com.alibaba.nacos.core.auth.AuthConfigs;
import com.alibaba.nacos.core.auth.AuthSystemTypes; import com.alibaba.nacos.core.auth.AuthSystemTypes;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.Field;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.*; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)