From 267a06b797e39a9b55ed2187567596ec104676fb Mon Sep 17 00:00:00 2001 From: godhth <1165559068@qq.com> Date: Sun, 21 Apr 2024 13:06:38 +0800 Subject: [PATCH 1/3] Remove default password --- .../alibaba/nacos/api/common/Constants.java | 2 + .../nacos/auth/config/AuthConfigs.java | 10 ++ .../main/resources/META-INF/derby-schema.sql | 4 - .../main/resources/META-INF/mysql-schema.sql | 3 - .../main/resources/META-INF/derby-schema.sql | 3 - distribution/conf/derby-schema.sql | 4 - distribution/conf/mysql-schema.sql | 3 - .../plugin/auth/impl/NacosAuthManager.java | 6 +- .../AbstractAuthenticationManager.java | 9 +- .../AuthenticationManagerDelegator.java | 5 + .../authenticate/IAuthenticationManager.java | 8 ++ .../auth/impl/constant/AuthConstants.java | 4 + .../auth/impl/controller/UserController.java | 27 ++++- .../auth/impl/roles/NacosRoleServiceImpl.java | 108 +++++++++++++++++- .../users/NacosUserDetailsServiceImpl.java | 25 +++- .../impl/utils/PasswordGeneratorUtil.java | 68 +++++++++++ .../impl/controller/UserControllerTest.java | 3 +- .../impl/utils/PasswordGeneratorUtilTest.java | 33 ++++++ .../src/test/resources/derby-schema.sql | 4 - 19 files changed, 299 insertions(+), 30 deletions(-) create mode 100644 plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtil.java create mode 100644 plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtilTest.java diff --git a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java index 0d9b6a1ac69..01323fa1a8d 100644 --- a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java +++ b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java @@ -85,6 +85,8 @@ public class Constants { public static final String GLOBAL_ADMIN = "globalAdmin"; + public static final String GLOBAL_TMP_ADMIN = "globalTmpAdmin"; + public static final String USERNAME = "username"; public static final String TOKEN_REFRESH_WINDOW = "tokenRefreshWindow"; diff --git a/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java b/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java index 28167a69ea9..35375143b7e 100644 --- a/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java +++ b/auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java @@ -78,6 +78,8 @@ public class AuthConfigs extends Subscriber { @Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE + ":false}") private boolean enableUserAgentAuthWhite; + private boolean hasGlobalAdminRole; + private Map authPluginProperties = new HashMap<>(); public AuthConfigs() { @@ -125,6 +127,14 @@ private void refreshPluginProperties() { } } + public boolean isHasGlobalAdminRole() { + return hasGlobalAdminRole; + } + + public void setHasGlobalAdminRole(boolean hasGlobalAdminRole) { + this.hasGlobalAdminRole = hasGlobalAdminRole; + } + public String getNacosAuthSystemType() { return nacosAuthSystemType; } diff --git a/config/src/main/resources/META-INF/derby-schema.sql b/config/src/main/resources/META-INF/derby-schema.sql index e664df8c711..601d38ab2e6 100644 --- a/config/src/main/resources/META-INF/derby-schema.sql +++ b/config/src/main/resources/META-INF/derby-schema.sql @@ -210,10 +210,6 @@ CREATE TABLE permissions ( constraint uk_role_permission UNIQUE (role,resource,action) ); -INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); - -INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); - /******************************************/ /* ipv6 support */ diff --git a/config/src/main/resources/META-INF/mysql-schema.sql b/config/src/main/resources/META-INF/mysql-schema.sql index e4c3e5d5c20..dded4ab9fc7 100644 --- a/config/src/main/resources/META-INF/mysql-schema.sql +++ b/config/src/main/resources/META-INF/mysql-schema.sql @@ -208,6 +208,3 @@ CREATE TABLE `permissions` ( UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE ); -INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); - -INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); diff --git a/console/src/main/resources/META-INF/derby-schema.sql b/console/src/main/resources/META-INF/derby-schema.sql index 0f8dbbe7077..be595491b89 100644 --- a/console/src/main/resources/META-INF/derby-schema.sql +++ b/console/src/main/resources/META-INF/derby-schema.sql @@ -210,9 +210,6 @@ CREATE TABLE permissions ( constraint uk_role_permission UNIQUE (role,resource,action) ); -INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); - -INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); /******************************************/ diff --git a/distribution/conf/derby-schema.sql b/distribution/conf/derby-schema.sql index 0f8dbbe7077..f4e93a3aab6 100644 --- a/distribution/conf/derby-schema.sql +++ b/distribution/conf/derby-schema.sql @@ -210,10 +210,6 @@ CREATE TABLE permissions ( constraint uk_role_permission UNIQUE (role,resource,action) ); -INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); - -INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); - /******************************************/ /* ipv6 support */ diff --git a/distribution/conf/mysql-schema.sql b/distribution/conf/mysql-schema.sql index e4c3e5d5c20..dded4ab9fc7 100644 --- a/distribution/conf/mysql-schema.sql +++ b/distribution/conf/mysql-schema.sql @@ -208,6 +208,3 @@ CREATE TABLE `permissions` ( UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE ); -INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); - -INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java index 8ecc5411464..41df61999c3 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java @@ -164,9 +164,13 @@ private NacosUser getNacosUser(String token) throws AccessException { user.setUserName(username); user.setToken(token); List roleInfoList = roleService.getRoles(username); + boolean hasGlobalAdminRole = roleService.hasGlobalAdminRole(); if (roleInfoList != null) { for (RoleInfo roleInfo : roleInfoList) { - if (roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) { + if (hasGlobalAdminRole && roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) { + user.setGlobalAdmin(true); + break; + } else if (roleInfo.getRole().equals(AuthConstants.GLOBAL_TMP_ADMIN_ROLE)) { user.setGlobalAdmin(true); break; } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java index 576d466d606..9cecc40d16f 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java @@ -57,7 +57,9 @@ public NacosUser authenticate(String username, String rawPassword) throws Access if (StringUtils.isBlank(username) || StringUtils.isBlank(rawPassword)) { throw new AccessException("user not found!"); } - + if (!roleService.hasGlobalAdminRole() && !roleService.hasTmpAdminRole(username)) { + throw new AccessException(AuthConstants.GLOBAL_ADMIN_ROLE + " role user not exist!"); + } NacosUserDetails nacosUserDetails = (NacosUserDetails) userDetailsService.loadUserByUsername(username); if (nacosUserDetails == null || !PasswordEncoderUtil.matches(rawPassword, nacosUserDetails.getPassword())) { throw new AccessException("user not found!"); @@ -129,4 +131,9 @@ public boolean hasGlobalAdminRole(NacosUser nacosUser) { nacosUser.setGlobalAdmin(hasGlobalAdminRole(nacosUser.getUserName())); return nacosUser.isGlobalAdmin(); } + + @Override + public boolean hasTmpAdminRole(String username) { + return roleService.hasTmpAdminRole(username); + } } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java index ab48d962c66..54d2488d520 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java @@ -76,6 +76,11 @@ public boolean hasGlobalAdminRole(NacosUser nacosUser) { return getManager().hasGlobalAdminRole(nacosUser); } + @Override + public boolean hasTmpAdminRole(String username) { + return getManager().hasTmpAdminRole(username); + } + private IAuthenticationManager getManager() { if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { return ldapAuthenticationManager.getIfAvailable(); diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java index f7135204478..4a2bc6206be 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java @@ -82,4 +82,12 @@ public interface IAuthenticationManager { * @return if the user has the administrator role. */ boolean hasGlobalAdminRole(NacosUser nacosUser); + + /** + * Whether the user has the tmp administrator role. + * + * @param username nacos user name + * @return if the user has the tmp administrator role. + */ + boolean hasTmpAdminRole(String username); } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java index e04be634406..fd79b722353 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java @@ -31,10 +31,14 @@ public class AuthConstants { public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN"; + public static final String GLOBAL_TMP_ADMIN_ROLE = "ROLE_TMP_ADMIN"; + public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String TOKEN_PREFIX = "Bearer "; + public static final String TMP_USER = "nacos"; + public static final String PARAM_USERNAME = "username"; public static final String PARAM_PASSWORD = "password"; diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java index 9f7c94b8eb9..aca3d43e564 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java @@ -109,6 +109,26 @@ public Object createUser(@RequestParam String username, @RequestParam String pas return RestResultUtils.success("create user ok!"); } + /** + * Create a tmp user only no admin user can use. + */ + @PostMapping("/createTmpUser") + public Object createTmpUser(@RequestParam(required = false) String username, @RequestParam(required = false) String password) { + if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { + if (roleService.hasGlobalAdminRole()) { + return RestResultUtils.failed("have admin user cannot use it"); + } + User tmpUser = userDetailsService.createTmpUser(username, password); + roleService.addTmpAdminRole(username); + ObjectNode result = JacksonUtils.createEmptyJsonNode(); + result.put(AuthConstants.PARAM_USERNAME, tmpUser.getUsername()); + result.put(AuthConstants.PARAM_PASSWORD, tmpUser.getPassword()); + return result; + } else { + return RestResultUtils.failed("not support"); + } + } + /** * Delete an existed user. * @@ -122,7 +142,8 @@ public Object deleteUser(@RequestParam String username) { List roleInfoList = roleService.getRoles(username); if (roleInfoList != null) { for (RoleInfo roleInfo : roleInfoList) { - if (roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) { + if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole()) + || AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())) { throw new IllegalArgumentException("cannot delete admin: " + username); } } @@ -170,7 +191,8 @@ public Object updateUser(@RequestParam String username, @RequestParam String new return RestResultUtils.success("update user ok!"); } - private boolean hasPermission(String username, HttpServletRequest request) throws HttpSessionRequiredException, AccessException { + private boolean hasPermission(String username, HttpServletRequest request) + throws HttpSessionRequiredException, AccessException { if (!authConfigs.isAuthEnabled()) { return true; } @@ -244,6 +266,7 @@ public Object login(@RequestParam String username, @RequestParam String password result.put(Constants.ACCESS_TOKEN, user.getToken()); result.put(Constants.TOKEN_TTL, jwtTokenManager.getTokenTtlInSeconds(user.getToken())); result.put(Constants.GLOBAL_ADMIN, iAuthenticationManager.hasGlobalAdminRole(user)); + result.put(Constants.GLOBAL_TMP_ADMIN, iAuthenticationManager.hasTmpAdminRole(username)); result.put(Constants.USERNAME, user.getUserName()); return result; } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java index 5207427a87a..518812bb3f3 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java @@ -130,9 +130,13 @@ public boolean hasPermission(NacosUser nacosUser, Permission permission) { return false; } + boolean hasGlobalAdminRole = hasGlobalAdminRole(); // Global admin pass: for (RoleInfo roleInfo : roleInfoList) { - if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) { + if (hasGlobalAdminRole && AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) { + nacosUser.setGlobalAdmin(true); + return true; + } else if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())) { nacosUser.setGlobalAdmin(true); return true; } @@ -176,6 +180,15 @@ public List getRoles(String username) { return roleInfoList; } + public List getAllRoles() { + Page roleInfoPage = rolePersistService.getRolesByUserNameAndRoleName(StringUtils.EMPTY, + StringUtils.EMPTY, DEFAULT_PAGE_NO, Integer.MAX_VALUE); + if (roleInfoPage == null) { + return null; + } + return roleInfoPage.getPageItems(); + } + public Page getRolesFromDatabase(String userName, String role, int pageNo, int pageSize) { Page roles = rolePersistService.getRolesByUserNameAndRoleName(userName, role, pageNo, pageSize); if (roles == null) { @@ -213,19 +226,76 @@ public void addRole(String role, String username) { if (userDetailsService.getUserFromDatabase(username) == null) { throw new IllegalArgumentException("user '" + username + "' not found!"); } + + if (hasTmpAdminRole(username)) { + throw new IllegalArgumentException("tmp user is not permitted to bind!"); + } + if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)) { + if (hasGlobalAdminRole()) { + throw new IllegalArgumentException( + "role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' is not permitted to create!"); + } else { + //delete tmp admin user + deleteTmpAdminUser(); + rolePersistService.addRole(role, username); + roleSet.add(role); + authConfigs.setHasGlobalAdminRole(true); + return; + } + + } else if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(role)) { throw new IllegalArgumentException( - "role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' is not permitted to create!"); + "role '" + AuthConstants.GLOBAL_TMP_ADMIN_ROLE + "' is not permitted to create!"); } + rolePersistService.addRole(role, username); roleSet.add(role); } + private void deleteTmpAdminUser() { + List roles = getAllRoles(); + roles.stream().filter(roleInfo -> AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())) + .forEach(tmpUser -> { + userDetailsService.deleteUser(tmpUser.getUsername()); + }); + rolePersistService.deleteRole(AuthConstants.GLOBAL_TMP_ADMIN_ROLE); + } + + /** + * Add tmp admin role. + * + * @param username user name + */ + public void addTmpAdminRole(String username) { + rolePersistService.addRole(AuthConstants.GLOBAL_TMP_ADMIN_ROLE, username); + roleSet.add(AuthConstants.GLOBAL_TMP_ADMIN_ROLE); + } + + /** + * delete user Role. + * + * @param role role + * @param userName userName + */ public void deleteRole(String role, String userName) { + if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(role)) { + throw new IllegalArgumentException( + "role '" + AuthConstants.GLOBAL_TMP_ADMIN_ROLE + "' is not permitted to delete!"); + } rolePersistService.deleteRole(role, userName); } + /** + * deleteRole. + * + * @param role role + */ public void deleteRole(String role) { + if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(role)) { + throw new IllegalArgumentException( + "role '" + AuthConstants.GLOBAL_TMP_ADMIN_ROLE + "' is not permitted to delete!"); + } rolePersistService.deleteRole(role); roleSet.remove(role); } @@ -304,7 +374,39 @@ public Page findPermissionsLike4Page(String role, int pageNo, in */ public boolean hasGlobalAdminRole(String userName) { List roles = getRoles(userName); + if (hasGlobalAdminRole()) { + return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())); + } else { + return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())); + } + } + + /** + * check if all user has at least one admin role. + * + * @return true if all user has at least one admin role. + */ + public boolean hasGlobalAdminRole() { + if (authConfigs.isHasGlobalAdminRole()) { + return true; + } + List roles = getAllRoles(); + boolean hasGlobalAdminRole = CollectionUtils.isNotEmpty(roles) && roles.stream() + .anyMatch(roleInfo -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())); + authConfigs.setHasGlobalAdminRole(hasGlobalAdminRole); + return hasGlobalAdminRole; + } + + /** + * check if user has Tmp admin role. + * + * @param userName user name + * @return true if user has Tmp admin role. + */ + public boolean hasTmpAdminRole(String userName) { + List roles = getRoles(userName); - return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())); + return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())); } + } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java index 2530cbf6c89..506f2297828 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java @@ -18,10 +18,13 @@ import com.alibaba.nacos.auth.config.AuthConfigs; import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants; import com.alibaba.nacos.plugin.auth.impl.persistence.UserPersistService; import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.plugin.auth.impl.persistence.User; import com.alibaba.nacos.core.utils.Loggers; +import com.alibaba.nacos.plugin.auth.impl.utils.PasswordEncoderUtil; +import com.alibaba.nacos.plugin.auth.impl.utils.PasswordGeneratorUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.core.userdetails.UserDetails; @@ -113,10 +116,30 @@ public void createUser(String username, String password) { userPersistService.createUser(username, password); } + /** + * createTmpUser. + * + * @param username username + * @return + */ + public User createTmpUser(String username, String password) { + if (StringUtils.isBlank(password)) { + password = PasswordGeneratorUtil.generateRandomPassword(); + } + if (StringUtils.isBlank(username)) { + username = AuthConstants.TMP_USER; + } + userPersistService.createUser(username, PasswordEncoderUtil.encode(password)); + User user = new User(); + user.setPassword(password); + user.setUsername(username); + return user; + } + public void deleteUser(String username) { userPersistService.deleteUser(username); } - + public Page findUsersLike4Page(String username, int pageNo, int pageSize) { return userPersistService.findUsersLike4Page(username, pageNo, pageSize); } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtil.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtil.java new file mode 100644 index 00000000000..f7283af758d --- /dev/null +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtil.java @@ -0,0 +1,68 @@ +/* + * Copyright 1999-2024 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.plugin.auth.impl.utils; + +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * RandomPasswordGenerator . + * + * @author : huangtianhui + */ +public class PasswordGeneratorUtil { + + private static final String LOWER_CASE = "abcdefghijklmnopqrstuvwxyz"; + + private static final String UPPER_CASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + private static final String DIGITS = "0123456789"; + + private static final String SPECIAL_CHARS = "!@#$%&"; + + private static final int PASSWORD_LENGTH = 8; + + /** + * generateRandomPassword. + * @return + */ + public static String generateRandomPassword() { + SecureRandom random = new SecureRandom(); + + List pwdChars = new ArrayList<>(); + + pwdChars.add(LOWER_CASE.charAt(random.nextInt(LOWER_CASE.length()))); + pwdChars.add(UPPER_CASE.charAt(random.nextInt(UPPER_CASE.length()))); + pwdChars.add(DIGITS.charAt(random.nextInt(DIGITS.length()))); + pwdChars.add(SPECIAL_CHARS.charAt(random.nextInt(SPECIAL_CHARS.length()))); + + // Fill the rest of the password with random characters from all categories + String allCharacters = LOWER_CASE + UPPER_CASE + DIGITS + SPECIAL_CHARS; + while (pwdChars.size() < PASSWORD_LENGTH) { + pwdChars.add(allCharacters.charAt(random.nextInt(allCharacters.length()))); + } + + // Shuffle to avoid predictable order + Collections.shuffle(pwdChars, random); + + // Build the final password string + return pwdChars.stream().map(String::valueOf).collect(Collectors.joining()); + } +} diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java index 28f2388a4e0..723a4ac3102 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java @@ -86,9 +86,10 @@ public void setUp() throws Exception { } @Test - public void testLoginWithAuthedUser() throws AccessException { + public void testLoginWithNoAuthedUser() throws AccessException { when(authenticationManager.authenticate(request)).thenReturn(user); when(authenticationManager.hasGlobalAdminRole(user)).thenReturn(true); + when(authenticationManager.hasTmpAdminRole(anyString())).thenReturn(true); when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name()); when(tokenManagerDelegate.getTokenTtlInSeconds(anyString())).thenReturn(18000L); Object actual = userController.login("nacos", "nacos", response, request); diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtilTest.java b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtilTest.java new file mode 100644 index 00000000000..dee12f94c9f --- /dev/null +++ b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/utils/PasswordGeneratorUtilTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2024 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.plugin.auth.impl.utils; + +import org.junit.Assert; +import org.junit.Test; + +public class PasswordGeneratorUtilTest { + + /** + * generatePwd test. + */ + @Test + public void generatePwd() { + String pwd = PasswordGeneratorUtil.generateRandomPassword(); + Assert.assertEquals(8, pwd.length()); + } + +} diff --git a/test/config-test/src/test/resources/derby-schema.sql b/test/config-test/src/test/resources/derby-schema.sql index 0f8dbbe7077..f4e93a3aab6 100644 --- a/test/config-test/src/test/resources/derby-schema.sql +++ b/test/config-test/src/test/resources/derby-schema.sql @@ -210,10 +210,6 @@ CREATE TABLE permissions ( constraint uk_role_permission UNIQUE (role,resource,action) ); -INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); - -INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); - /******************************************/ /* ipv6 support */ From 4130aae8a0b8308070a5e058af8cd6247ec7f2c4 Mon Sep 17 00:00:00 2001 From: godhth <1165559068@qq.com> Date: Tue, 23 Apr 2024 20:10:20 +0800 Subject: [PATCH 2/3] admin role check fix --- .../authenticate/AbstractAuthenticationManager.java | 10 ++++++---- .../authenticate/AuthenticationManagerDelegator.java | 5 +++++ .../auth/impl/authenticate/IAuthenticationManager.java | 7 +++++++ .../plugin/auth/impl/controller/UserController.java | 6 +++++- .../auth/impl/controller/UserControllerTest.java | 5 +++-- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java index 9cecc40d16f..207ec823388 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java @@ -57,9 +57,6 @@ public NacosUser authenticate(String username, String rawPassword) throws Access if (StringUtils.isBlank(username) || StringUtils.isBlank(rawPassword)) { throw new AccessException("user not found!"); } - if (!roleService.hasGlobalAdminRole() && !roleService.hasTmpAdminRole(username)) { - throw new AccessException(AuthConstants.GLOBAL_ADMIN_ROLE + " role user not exist!"); - } NacosUserDetails nacosUserDetails = (NacosUserDetails) userDetailsService.loadUserByUsername(username); if (nacosUserDetails == null || !PasswordEncoderUtil.matches(rawPassword, nacosUserDetails.getPassword())) { throw new AccessException("user not found!"); @@ -123,6 +120,11 @@ public boolean hasGlobalAdminRole(String username) { return roleService.hasGlobalAdminRole(username); } + @Override + public boolean hasGlobalAdminRole() { + return roleService.hasGlobalAdminRole(); + } + @Override public boolean hasGlobalAdminRole(NacosUser nacosUser) { if (nacosUser.isGlobalAdmin()) { @@ -134,6 +136,6 @@ public boolean hasGlobalAdminRole(NacosUser nacosUser) { @Override public boolean hasTmpAdminRole(String username) { - return roleService.hasTmpAdminRole(username); + return StringUtils.isNotBlank(username) && roleService.hasTmpAdminRole(username); } } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java index 54d2488d520..c412849c415 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java @@ -71,6 +71,11 @@ public boolean hasGlobalAdminRole(String username) { return getManager().hasGlobalAdminRole(username); } + @Override + public boolean hasGlobalAdminRole() { + return getManager().hasGlobalAdminRole(); + } + @Override public boolean hasGlobalAdminRole(NacosUser nacosUser) { return getManager().hasGlobalAdminRole(nacosUser); diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java index 4a2bc6206be..d38a719248d 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java @@ -75,6 +75,13 @@ public interface IAuthenticationManager { */ boolean hasGlobalAdminRole(String username); + /** + * Whether the user exist the administrator role. + * + * @return if the user exist the administrator role. + */ + boolean hasGlobalAdminRole(); + /** * Whether the user has the administrator role. * diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java index aca3d43e564..6853a5f7c1c 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java @@ -113,7 +113,8 @@ public Object createUser(@RequestParam String username, @RequestParam String pas * Create a tmp user only no admin user can use. */ @PostMapping("/createTmpUser") - public Object createTmpUser(@RequestParam(required = false) String username, @RequestParam(required = false) String password) { + public Object createTmpUser(@RequestParam(required = false) String username, + @RequestParam(required = false) String password) { if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { if (roleService.hasGlobalAdminRole()) { return RestResultUtils.failed("have admin user cannot use it"); @@ -258,6 +259,9 @@ public Object login(@RequestParam String username, @RequestParam String password if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType()) || AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { + if (!iAuthenticationManager.hasGlobalAdminRole() && !iAuthenticationManager.hasTmpAdminRole(username)) { + return RestResultUtils.failed(AuthConstants.GLOBAL_ADMIN_ROLE + " role user not exist!"); + } NacosUser user = iAuthenticationManager.authenticate(request); response.addHeader(AuthConstants.AUTHORIZATION_HEADER, AuthConstants.TOKEN_PREFIX + user.getToken()); diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java index 723a4ac3102..a7fd2dd607b 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java @@ -86,10 +86,11 @@ public void setUp() throws Exception { } @Test - public void testLoginWithNoAuthedUser() throws AccessException { + public void testLoginWithAuthedUser() throws AccessException { when(authenticationManager.authenticate(request)).thenReturn(user); when(authenticationManager.hasGlobalAdminRole(user)).thenReturn(true); - when(authenticationManager.hasTmpAdminRole(anyString())).thenReturn(true); + when(authenticationManager.hasTmpAdminRole(anyString())).thenReturn(false); + when(authenticationManager.hasGlobalAdminRole()).thenReturn(true); when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name()); when(tokenManagerDelegate.getTokenTtlInSeconds(anyString())).thenReturn(18000L); Object actual = userController.login("nacos", "nacos", response, request); From 88aea06e4c3e97af42198863626185d93dfe8f7c Mon Sep 17 00:00:00 2001 From: godhth <1165559068@qq.com> Date: Thu, 25 Apr 2024 11:48:59 +0800 Subject: [PATCH 3/3] remove tmp admin --- .../alibaba/nacos/api/common/Constants.java | 2 - .../plugin/auth/impl/NacosAuthManager.java | 6 +- .../AbstractAuthenticationManager.java | 5 -- .../AuthenticationManagerDelegator.java | 5 -- .../authenticate/IAuthenticationManager.java | 8 -- .../auth/impl/constant/AuthConstants.java | 4 +- .../auth/impl/controller/UserController.java | 33 ++++---- .../auth/impl/roles/NacosRoleServiceImpl.java | 78 ++++--------------- .../users/NacosUserDetailsServiceImpl.java | 24 +----- .../impl/controller/UserControllerTest.java | 4 +- 10 files changed, 41 insertions(+), 128 deletions(-) diff --git a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java index 01323fa1a8d..0d9b6a1ac69 100644 --- a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java +++ b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java @@ -85,8 +85,6 @@ public class Constants { public static final String GLOBAL_ADMIN = "globalAdmin"; - public static final String GLOBAL_TMP_ADMIN = "globalTmpAdmin"; - public static final String USERNAME = "username"; public static final String TOKEN_REFRESH_WINDOW = "tokenRefreshWindow"; diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java index 41df61999c3..8ecc5411464 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/NacosAuthManager.java @@ -164,13 +164,9 @@ private NacosUser getNacosUser(String token) throws AccessException { user.setUserName(username); user.setToken(token); List roleInfoList = roleService.getRoles(username); - boolean hasGlobalAdminRole = roleService.hasGlobalAdminRole(); if (roleInfoList != null) { for (RoleInfo roleInfo : roleInfoList) { - if (hasGlobalAdminRole && roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) { - user.setGlobalAdmin(true); - break; - } else if (roleInfo.getRole().equals(AuthConstants.GLOBAL_TMP_ADMIN_ROLE)) { + if (roleInfo.getRole().equals(AuthConstants.GLOBAL_ADMIN_ROLE)) { user.setGlobalAdmin(true); break; } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java index 207ec823388..beeb183de65 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AbstractAuthenticationManager.java @@ -133,9 +133,4 @@ public boolean hasGlobalAdminRole(NacosUser nacosUser) { nacosUser.setGlobalAdmin(hasGlobalAdminRole(nacosUser.getUserName())); return nacosUser.isGlobalAdmin(); } - - @Override - public boolean hasTmpAdminRole(String username) { - return StringUtils.isNotBlank(username) && roleService.hasTmpAdminRole(username); - } } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java index c412849c415..e9c1e0f2034 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/AuthenticationManagerDelegator.java @@ -81,11 +81,6 @@ public boolean hasGlobalAdminRole(NacosUser nacosUser) { return getManager().hasGlobalAdminRole(nacosUser); } - @Override - public boolean hasTmpAdminRole(String username) { - return getManager().hasTmpAdminRole(username); - } - private IAuthenticationManager getManager() { if (AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { return ldapAuthenticationManager.getIfAvailable(); diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java index d38a719248d..8c4abbca76d 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/authenticate/IAuthenticationManager.java @@ -89,12 +89,4 @@ public interface IAuthenticationManager { * @return if the user has the administrator role. */ boolean hasGlobalAdminRole(NacosUser nacosUser); - - /** - * Whether the user has the tmp administrator role. - * - * @param username nacos user name - * @return if the user has the tmp administrator role. - */ - boolean hasTmpAdminRole(String username); } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java index fd79b722353..90664d65e24 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/constant/AuthConstants.java @@ -31,13 +31,11 @@ public class AuthConstants { public static final String GLOBAL_ADMIN_ROLE = "ROLE_ADMIN"; - public static final String GLOBAL_TMP_ADMIN_ROLE = "ROLE_TMP_ADMIN"; - public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String TOKEN_PREFIX = "Bearer "; - public static final String TMP_USER = "nacos"; + public static final String DEFAULT_USER = "nacos"; public static final String PARAM_USERNAME = "username"; diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java index 6853a5f7c1c..a4e60f7c5e3 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/controller/UserController.java @@ -22,6 +22,7 @@ import com.alibaba.nacos.common.model.RestResult; import com.alibaba.nacos.common.model.RestResultUtils; import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.plugin.auth.api.IdentityContext; import com.alibaba.nacos.plugin.auth.constant.ActionTypes; @@ -36,6 +37,7 @@ import com.alibaba.nacos.plugin.auth.impl.users.NacosUser; import com.alibaba.nacos.plugin.auth.impl.users.NacosUserDetailsServiceImpl; import com.alibaba.nacos.plugin.auth.impl.utils.PasswordEncoderUtil; +import com.alibaba.nacos.plugin.auth.impl.utils.PasswordGeneratorUtil; import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -110,20 +112,26 @@ public Object createUser(@RequestParam String username, @RequestParam String pas } /** - * Create a tmp user only no admin user can use. + * Create a admin user only not exist admin user can use. */ - @PostMapping("/createTmpUser") - public Object createTmpUser(@RequestParam(required = false) String username, + @PostMapping("/admin") + public Object createAdminUser(@RequestParam(required = false) String username, @RequestParam(required = false) String password) { if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { if (roleService.hasGlobalAdminRole()) { return RestResultUtils.failed("have admin user cannot use it"); } - User tmpUser = userDetailsService.createTmpUser(username, password); - roleService.addTmpAdminRole(username); + if (StringUtils.isBlank(password)) { + password = PasswordGeneratorUtil.generateRandomPassword(); + } + if (StringUtils.isBlank(username)) { + username = AuthConstants.DEFAULT_USER; + } + userDetailsService.createUser(username, PasswordEncoderUtil.encode(password)); + roleService.addAdminRole(username); ObjectNode result = JacksonUtils.createEmptyJsonNode(); - result.put(AuthConstants.PARAM_USERNAME, tmpUser.getUsername()); - result.put(AuthConstants.PARAM_PASSWORD, tmpUser.getPassword()); + result.put(AuthConstants.PARAM_USERNAME, username); + result.put(AuthConstants.PARAM_PASSWORD, password); return result; } else { return RestResultUtils.failed("not support"); @@ -143,8 +151,7 @@ public Object deleteUser(@RequestParam String username) { List roleInfoList = roleService.getRoles(username); if (roleInfoList != null) { for (RoleInfo roleInfo : roleInfoList) { - if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole()) - || AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())) { + if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) { throw new IllegalArgumentException("cannot delete admin: " + username); } } @@ -255,12 +262,13 @@ public Page fuzzySearchUser(@RequestParam int pageNo, @RequestParam int pa */ @PostMapping("/login") public Object login(@RequestParam String username, @RequestParam String password, HttpServletResponse response, - HttpServletRequest request) throws AccessException { + HttpServletRequest request) throws AccessException, IOException { if (AuthSystemTypes.NACOS.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType()) || AuthSystemTypes.LDAP.name().equalsIgnoreCase(authConfigs.getNacosAuthSystemType())) { - if (!iAuthenticationManager.hasGlobalAdminRole() && !iAuthenticationManager.hasTmpAdminRole(username)) { - return RestResultUtils.failed(AuthConstants.GLOBAL_ADMIN_ROLE + " role user not exist!"); + if (!iAuthenticationManager.hasGlobalAdminRole()) { + response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED, "admin role user not exist"); + return null; } NacosUser user = iAuthenticationManager.authenticate(request); @@ -270,7 +278,6 @@ public Object login(@RequestParam String username, @RequestParam String password result.put(Constants.ACCESS_TOKEN, user.getToken()); result.put(Constants.TOKEN_TTL, jwtTokenManager.getTokenTtlInSeconds(user.getToken())); result.put(Constants.GLOBAL_ADMIN, iAuthenticationManager.hasGlobalAdminRole(user)); - result.put(Constants.GLOBAL_TMP_ADMIN, iAuthenticationManager.hasTmpAdminRole(username)); result.put(Constants.USERNAME, user.getUserName()); return result; } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java index 518812bb3f3..ffd28b1e1c2 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/roles/NacosRoleServiceImpl.java @@ -130,13 +130,9 @@ public boolean hasPermission(NacosUser nacosUser, Permission permission) { return false; } - boolean hasGlobalAdminRole = hasGlobalAdminRole(); // Global admin pass: for (RoleInfo roleInfo : roleInfoList) { - if (hasGlobalAdminRole && AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) { - nacosUser.setGlobalAdmin(true); - return true; - } else if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())) { + if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())) { nacosUser.setGlobalAdmin(true); return true; } @@ -227,49 +223,30 @@ public void addRole(String role, String username) { throw new IllegalArgumentException("user '" + username + "' not found!"); } - if (hasTmpAdminRole(username)) { - throw new IllegalArgumentException("tmp user is not permitted to bind!"); - } - if (AuthConstants.GLOBAL_ADMIN_ROLE.equals(role)) { - if (hasGlobalAdminRole()) { - throw new IllegalArgumentException( - "role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' is not permitted to create!"); - } else { - //delete tmp admin user - deleteTmpAdminUser(); - rolePersistService.addRole(role, username); - roleSet.add(role); - authConfigs.setHasGlobalAdminRole(true); - return; - } - - } else if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(role)) { throw new IllegalArgumentException( - "role '" + AuthConstants.GLOBAL_TMP_ADMIN_ROLE + "' is not permitted to create!"); + "role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' is not permitted to create!"); } - rolePersistService.addRole(role, username); roleSet.add(role); } - private void deleteTmpAdminUser() { - List roles = getAllRoles(); - roles.stream().filter(roleInfo -> AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())) - .forEach(tmpUser -> { - userDetailsService.deleteUser(tmpUser.getUsername()); - }); - rolePersistService.deleteRole(AuthConstants.GLOBAL_TMP_ADMIN_ROLE); - } - /** - * Add tmp admin role. + * Add role. * * @param username user name */ - public void addTmpAdminRole(String username) { - rolePersistService.addRole(AuthConstants.GLOBAL_TMP_ADMIN_ROLE, username); - roleSet.add(AuthConstants.GLOBAL_TMP_ADMIN_ROLE); + public void addAdminRole(String username) { + if (userDetailsService.getUserFromDatabase(username) == null) { + throw new IllegalArgumentException("user '" + username + "' not found!"); + } + if (hasGlobalAdminRole()) { + throw new IllegalArgumentException("role '" + AuthConstants.GLOBAL_ADMIN_ROLE + "' already exist !"); + } + + rolePersistService.addRole(AuthConstants.GLOBAL_ADMIN_ROLE, username); + roleSet.add(AuthConstants.GLOBAL_ADMIN_ROLE); + authConfigs.setHasGlobalAdminRole(true); } /** @@ -279,10 +256,6 @@ public void addTmpAdminRole(String username) { * @param userName userName */ public void deleteRole(String role, String userName) { - if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(role)) { - throw new IllegalArgumentException( - "role '" + AuthConstants.GLOBAL_TMP_ADMIN_ROLE + "' is not permitted to delete!"); - } rolePersistService.deleteRole(role, userName); } @@ -292,10 +265,6 @@ public void deleteRole(String role, String userName) { * @param role role */ public void deleteRole(String role) { - if (AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(role)) { - throw new IllegalArgumentException( - "role '" + AuthConstants.GLOBAL_TMP_ADMIN_ROLE + "' is not permitted to delete!"); - } rolePersistService.deleteRole(role); roleSet.remove(role); } @@ -374,11 +343,8 @@ public Page findPermissionsLike4Page(String role, int pageNo, in */ public boolean hasGlobalAdminRole(String userName) { List roles = getRoles(userName); - if (hasGlobalAdminRole()) { - return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())); - } else { - return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())); - } + + return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_ADMIN_ROLE.equals(roleInfo.getRole())); } /** @@ -397,16 +363,4 @@ public boolean hasGlobalAdminRole() { return hasGlobalAdminRole; } - /** - * check if user has Tmp admin role. - * - * @param userName user name - * @return true if user has Tmp admin role. - */ - public boolean hasTmpAdminRole(String userName) { - List roles = getRoles(userName); - - return roles.stream().anyMatch(roleInfo -> AuthConstants.GLOBAL_TMP_ADMIN_ROLE.equals(roleInfo.getRole())); - } - } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java index 506f2297828..e0280a37b9c 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/users/NacosUserDetailsServiceImpl.java @@ -18,13 +18,11 @@ import com.alibaba.nacos.auth.config.AuthConfigs; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.plugin.auth.impl.constant.AuthConstants; + import com.alibaba.nacos.plugin.auth.impl.persistence.UserPersistService; import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.plugin.auth.impl.persistence.User; import com.alibaba.nacos.core.utils.Loggers; -import com.alibaba.nacos.plugin.auth.impl.utils.PasswordEncoderUtil; -import com.alibaba.nacos.plugin.auth.impl.utils.PasswordGeneratorUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.core.userdetails.UserDetails; @@ -116,26 +114,6 @@ public void createUser(String username, String password) { userPersistService.createUser(username, password); } - /** - * createTmpUser. - * - * @param username username - * @return - */ - public User createTmpUser(String username, String password) { - if (StringUtils.isBlank(password)) { - password = PasswordGeneratorUtil.generateRandomPassword(); - } - if (StringUtils.isBlank(username)) { - username = AuthConstants.TMP_USER; - } - userPersistService.createUser(username, PasswordEncoderUtil.encode(password)); - User user = new User(); - user.setPassword(password); - user.setUsername(username); - return user; - } - public void deleteUser(String username) { userPersistService.deleteUser(username); } diff --git a/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java index a7fd2dd607b..74417f67dc8 100644 --- a/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java +++ b/plugin-default-impl/nacos-default-auth-plugin/src/test/java/com/alibaba/nacos/plugin/auth/impl/controller/UserControllerTest.java @@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -86,10 +87,9 @@ public void setUp() throws Exception { } @Test - public void testLoginWithAuthedUser() throws AccessException { + public void testLoginWithAuthedUser() throws AccessException, IOException { when(authenticationManager.authenticate(request)).thenReturn(user); when(authenticationManager.hasGlobalAdminRole(user)).thenReturn(true); - when(authenticationManager.hasTmpAdminRole(anyString())).thenReturn(false); when(authenticationManager.hasGlobalAdminRole()).thenReturn(true); when(authConfigs.getNacosAuthSystemType()).thenReturn(AuthSystemTypes.NACOS.name()); when(tokenManagerDelegate.getTokenTtlInSeconds(anyString())).thenReturn(18000L);