Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE #11957] Remove default password #11991

Merged
merged 4 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/src/main/java/com/alibaba/nacos/api/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public class Constants {

public static final String GLOBAL_ADMIN = "globalAdmin";

public static final String GLOBAL_TMP_ADMIN = "globalTmpAdmin";
godhth marked this conversation as resolved.
Show resolved Hide resolved

public static final String USERNAME = "username";

public static final String TOKEN_REFRESH_WINDOW = "tokenRefreshWindow";
Expand Down
10 changes: 10 additions & 0 deletions auth/src/main/java/com/alibaba/nacos/auth/config/AuthConfigs.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public class AuthConfigs extends Subscriber<ServerConfigChangeEvent> {
@Value("${" + Constants.Auth.NACOS_CORE_AUTH_ENABLE_USER_AGENT_AUTH_WHITE + ":false}")
private boolean enableUserAgentAuthWhite;

private boolean hasGlobalAdminRole;

private Map<String, Properties> authPluginProperties = new HashMap<>();

public AuthConfigs() {
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 0 additions & 4 deletions config/src/main/resources/META-INF/derby-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
3 changes: 0 additions & 3 deletions config/src/main/resources/META-INF/mysql-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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');
3 changes: 0 additions & 3 deletions console/src/main/resources/META-INF/derby-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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');


/******************************************/
Expand Down
4 changes: 0 additions & 4 deletions distribution/conf/derby-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
3 changes: 0 additions & 3 deletions distribution/conf/mysql-schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,13 @@ private NacosUser getNacosUser(String token) throws AccessException {
user.setUserName(username);
user.setToken(token);
List<RoleInfo> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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!");
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -122,7 +142,8 @@ public Object deleteUser(@RequestParam String username) {
List<RoleInfo> 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);
}
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -176,6 +180,15 @@ public List<RoleInfo> getRoles(String username) {
return roleInfoList;
}

public List<RoleInfo> getAllRoles() {
Page<RoleInfo> roleInfoPage = rolePersistService.getRolesByUserNameAndRoleName(StringUtils.EMPTY,
StringUtils.EMPTY, DEFAULT_PAGE_NO, Integer.MAX_VALUE);
if (roleInfoPage == null) {
return null;
}
return roleInfoPage.getPageItems();
}

public Page<RoleInfo> getRolesFromDatabase(String userName, String role, int pageNo, int pageSize) {
Page<RoleInfo> roles = rolePersistService.getRolesByUserNameAndRoleName(userName, role, pageNo, pageSize);
if (roles == null) {
Expand Down Expand Up @@ -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<RoleInfo> 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);
}
Expand Down Expand Up @@ -304,7 +374,39 @@ public Page<PermissionInfo> findPermissionsLike4Page(String role, int pageNo, in
*/
public boolean hasGlobalAdminRole(String userName) {
List<RoleInfo> 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<RoleInfo> 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<RoleInfo> 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()));
}

}
Loading
Loading