fix:角色授权修改

This commit is contained in:
waner
2026-04-25 17:38:57 +08:00
parent 7bc364f367
commit 291c7cfc8a
28 changed files with 520 additions and 2240 deletions
@@ -58,18 +58,18 @@ public class AuthAdminController {
return ApiResponse.success();
}
@PostMapping("/roles/{roleCode}/full-accounts/{uid}/change-password")
@Operation(summary = "管理员修改 FULL 账户口令", description = "管理员为目标角色指定 UKey 席位账号设置新口令。")
@PostMapping("/roles/{roleCode}/accounts/{uid}/change-password")
@Operation(summary = "管理员修改角色席位口令", description = "管理员为目标角色指定席位账号设置新口令。")
@ReplayProtected
// @RequireInternalAuth(role = RoleCode.SUPER_ADMIN, authLevel = AuthLevel.FULL)
@AuditedOperation(module = ModuleCode.AUTH, action = ActionType.UPDATE, summary = "管理员修改 FULL 账户口令")
public ApiResponse<Void> changeFullAccountPassword(
@RequireInternalAuth(role = RoleCode.SUPER_ADMIN, authLevel = AuthLevel.FULL)
@AuditedOperation(module = ModuleCode.AUTH, action = ActionType.UPDATE, summary = "管理员修改角色席位口令")
public ApiResponse<Void> changeAccountPassword(
@PathVariable("roleCode") String roleCode,
@PathVariable("uid") Integer uid,
@Valid @RequestBody AdminChangePasswordRequest request,
HttpServletRequest httpRequest
) {
authAdminService.changeFullAccountPassword(
authAdminService.changeAccountPassword(
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE),
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_AUTH_LEVEL),
roleCode,
@@ -80,28 +80,6 @@ public class AuthAdminController {
return ApiResponse.success();
}
@PostMapping("/roles/{roleCode}/limited-accounts/{username}/change-password")
@Operation(summary = "管理员修改 LIMITED 账户口令", description = "管理员为目标角色指定独立用户账号设置新口令。")
@ReplayProtected
// @RequireInternalAuth(role = RoleCode.SUPER_ADMIN, authLevel = AuthLevel.FULL)
@AuditedOperation(module = ModuleCode.AUTH, action = ActionType.UPDATE, summary = "管理员修改 LIMITED 账户口令")
public ApiResponse<Void> changeLimitedAccountPassword(
@PathVariable("roleCode") String roleCode,
@PathVariable("username") String username,
@Valid @RequestBody AdminChangePasswordRequest request,
HttpServletRequest httpRequest
) {
authAdminService.changeLimitedAccountPassword(
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_ROLE_CODE),
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_AUTH_LEVEL),
roleCode,
username,
request.getOldPassword(),
request.getNewPassword()
);
return ApiResponse.success();
}
@PostMapping("/super-admin/ukeys/issue-sign")
@Operation(summary = "签发并绑定超级管理员 UKey", description = "系统初始化后登记超级管理员 UKey,不要求已有登录态。")
public ApiResponse<UKeySignResult> issueSuperAdminUkeyBindingSign(
@@ -65,16 +65,16 @@ public class AuthController {
return ApiResponse.success();
}
@PostMapping("/full-accounts/{uid}/change-password")
@Operation(summary = "修改当前 FULL 账户口令", description = "基于当前 FULL 会话校验并更新指定席位账户口令。")
@AuditedOperation(module = ModuleCode.AUTH, action = ActionType.UPDATE, summary = "修改当前 FULL 账户口令")
@PostMapping("/accounts/{uid}/change-password")
@Operation(summary = "修改当前登录席位口令", description = "基于当前会话校验并更新指定角色席位口令。")
@AuditedOperation(module = ModuleCode.AUTH, action = ActionType.UPDATE, summary = "修改当前登录席位口令")
@ReplayProtected
public ApiResponse<Void> changeFullAccountPassword(
public ApiResponse<Void> changeAccountPassword(
@PathVariable("uid") Integer uid,
@Valid @RequestBody ChangePasswordRequest request,
HttpServletRequest httpRequest
) {
authService.changeFullAccountPassword(
authService.changeAccountPassword(
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_SESSION_TOKEN),
uid,
request.getCurrentPassword(),
@@ -82,22 +82,4 @@ public class AuthController {
);
return ApiResponse.success();
}
@PostMapping("/limited-accounts/{username}/change-password")
@Operation(summary = "修改当前 LIMITED 账户口令", description = "基于当前 LIMITED 会话校验并更新指定受限账户口令。")
@AuditedOperation(module = ModuleCode.AUTH, action = ActionType.UPDATE, summary = "修改当前 LIMITED 账户口令")
@ReplayProtected
public ApiResponse<Void> changeLimitedAccountPassword(
@PathVariable("username") String username,
@Valid @RequestBody ChangePasswordRequest request,
HttpServletRequest httpRequest
) {
authService.changeLimitedAccountPassword(
(String) httpRequest.getAttribute(InternalApiAuthInterceptor.ATTR_SESSION_TOKEN),
username,
request.getCurrentPassword(),
request.getNewPassword()
);
return ApiResponse.success();
}
}
@@ -13,9 +13,16 @@ public class AuthSessionPrincipal {
return principal;
}
public static AuthSessionPrincipal limited(String username) {
public static AuthSessionPrincipal full(Integer uid, String username) {
AuthSessionPrincipal principal = full(uid);
principal.setUsername(username);
return principal;
}
public static AuthSessionPrincipal limited(Integer uid, String username) {
AuthSessionPrincipal principal = new AuthSessionPrincipal();
principal.setType("LIMITED");
principal.setUid(uid);
principal.setUsername(username);
return principal;
}
@@ -2,24 +2,25 @@ package com.cisd.tms.modules.auth.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
@Schema(description = "角色口令校验账号")
public class PasswordLoginAccountRequest {
@NotBlank(message = "username is required")
@Schema(description = "账号名", example = "super-admin-01")
private String username;
@NotNull(message = "uid is required")
@Schema(description = "角色固定席位编号", example = "1")
private Integer uid;
@NotBlank(message = "password is required")
@Schema(description = "账号口令", example = "12345678")
private String password;
public String getUsername() {
return username;
public Integer getUid() {
return uid;
}
public void setUsername(String username) {
this.username = username;
public void setUid(Integer uid) {
this.uid = uid;
}
public String getPassword() {
@@ -1,118 +0,0 @@
package com.cisd.tms.modules.auth.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cisd.tms.infrastructure.persistence.entity.BaseEntity;
import java.time.LocalDateTime;
@TableName("tms_auth_user_account")
public class AuthUserAccountEntity extends BaseEntity {
private String username;
private String displayName;
private String roleCode;
private String passwordHash;
private String passwordSalt;
private String status;
private Boolean needChangePassword;
private LocalDateTime passwordChangedAt;
private Integer failedCount;
private LocalDateTime lockedUntil;
private LocalDateTime lastLoginAt;
private LocalDateTime lastActiveAt;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getRoleCode() {
return roleCode;
}
public void setRoleCode(String roleCode) {
this.roleCode = roleCode;
}
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
public String getPasswordSalt() {
return passwordSalt;
}
public void setPasswordSalt(String passwordSalt) {
this.passwordSalt = passwordSalt;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Boolean getNeedChangePassword() {
return needChangePassword;
}
public void setNeedChangePassword(Boolean needChangePassword) {
this.needChangePassword = needChangePassword;
}
public LocalDateTime getPasswordChangedAt() {
return passwordChangedAt;
}
public void setPasswordChangedAt(LocalDateTime passwordChangedAt) {
this.passwordChangedAt = passwordChangedAt;
}
public Integer getFailedCount() {
return failedCount;
}
public void setFailedCount(Integer failedCount) {
this.failedCount = failedCount;
}
public LocalDateTime getLockedUntil() {
return lockedUntil;
}
public void setLockedUntil(LocalDateTime lockedUntil) {
this.lockedUntil = lockedUntil;
}
public LocalDateTime getLastLoginAt() {
return lastLoginAt;
}
public void setLastLoginAt(LocalDateTime lastLoginAt) {
this.lastLoginAt = lastLoginAt;
}
public LocalDateTime getLastActiveAt() {
return lastActiveAt;
}
public void setLastActiveAt(LocalDateTime lastActiveAt) {
this.lastActiveAt = lastActiveAt;
}
}
@@ -1,36 +0,0 @@
package com.cisd.tms.modules.auth.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.cisd.tms.infrastructure.persistence.entity.BaseEntity;
@TableName("tms_auth_user")
public class AuthUserEntity extends BaseEntity {
private String username;
private String displayName;
private String role;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
}
@@ -1,7 +1,7 @@
package com.cisd.tms.modules.auth.enums;
public enum RoleCode {
SUPER_ADMIN("SUPER_ADMIN", "超级管理员", 2),
SUPER_ADMIN("SUPER_ADMIN", "系统管理员", 2),
KEY_ADMIN("KEY_ADMIN", "密钥管理员", 1),
AUDIT_ADMIN("AUDIT_ADMIN", "审计管理员", 1),
OPS_ADMIN("OPS_ADMIN", "运维管理员", 1);
@@ -1,15 +0,0 @@
package com.cisd.tms.modules.auth.mapper;
import com.cisd.tms.infrastructure.persistence.mapper.BaseMapperX;
import com.cisd.tms.modules.auth.entity.AuthUserAccountEntity;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface AuthUserAccountMapper extends BaseMapperX<AuthUserAccountEntity> {
AuthUserAccountEntity selectByUsername(@Param("username") String username);
List<AuthUserAccountEntity> selectByRoleCode(@Param("roleCode") String roleCode);
}
@@ -1,12 +0,0 @@
package com.cisd.tms.modules.auth.mapper;
import com.cisd.tms.infrastructure.persistence.mapper.BaseMapperX;
import com.cisd.tms.modules.auth.entity.AuthUserEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface AuthUserMapper extends BaseMapperX<AuthUserEntity> {
AuthUserEntity selectByUsername(@Param("username") String username);
}
@@ -1,16 +0,0 @@
package com.cisd.tms.modules.auth.repository;
import com.cisd.tms.modules.auth.entity.AuthUserAccountEntity;
import java.util.List;
import java.util.Optional;
public interface AuthUserAccountRepository {
Optional<AuthUserAccountEntity> findByUsername(String username);
List<AuthUserAccountEntity> findByRoleCode(String roleCode);
void save(AuthUserAccountEntity entity);
void update(AuthUserAccountEntity entity);
}
@@ -1,9 +0,0 @@
package com.cisd.tms.modules.auth.repository;
import com.cisd.tms.modules.auth.entity.AuthUserEntity;
import java.util.Optional;
public interface AuthUserRepository {
Optional<AuthUserEntity> findByUsername(String username);
}
@@ -1,38 +0,0 @@
package com.cisd.tms.modules.auth.repository.impl;
import com.cisd.tms.modules.auth.entity.AuthUserAccountEntity;
import com.cisd.tms.modules.auth.mapper.AuthUserAccountMapper;
import com.cisd.tms.modules.auth.repository.AuthUserAccountRepository;
import java.util.List;
import java.util.Optional;
import org.springframework.stereotype.Repository;
@Repository
public class AuthUserAccountRepositoryImpl implements AuthUserAccountRepository {
private final AuthUserAccountMapper authUserAccountMapper;
public AuthUserAccountRepositoryImpl(AuthUserAccountMapper authUserAccountMapper) {
this.authUserAccountMapper = authUserAccountMapper;
}
@Override
public Optional<AuthUserAccountEntity> findByUsername(String username) {
return Optional.ofNullable(authUserAccountMapper.selectByUsername(username));
}
@Override
public List<AuthUserAccountEntity> findByRoleCode(String roleCode) {
return authUserAccountMapper.selectByRoleCode(roleCode);
}
@Override
public void save(AuthUserAccountEntity entity) {
authUserAccountMapper.insert(entity);
}
@Override
public void update(AuthUserAccountEntity entity) {
authUserAccountMapper.updateById(entity);
}
}
@@ -1,22 +0,0 @@
package com.cisd.tms.modules.auth.repository.impl;
import com.cisd.tms.modules.auth.entity.AuthUserEntity;
import com.cisd.tms.modules.auth.mapper.AuthUserMapper;
import com.cisd.tms.modules.auth.repository.AuthUserRepository;
import java.util.Optional;
import org.springframework.stereotype.Repository;
@Repository
public class AuthUserRepositoryImpl implements AuthUserRepository {
private final AuthUserMapper authUserMapper;
public AuthUserRepositoryImpl(AuthUserMapper authUserMapper) {
this.authUserMapper = authUserMapper;
}
@Override
public Optional<AuthUserEntity> findByUsername(String username) {
return Optional.ofNullable(authUserMapper.selectByUsername(username));
}
}
@@ -9,7 +9,7 @@ public interface AuthAdminService {
void resetPassword(String operatorRoleCode, String operatorAuthLevel, String targetRoleCode);
void changeFullAccountPassword(
void changeAccountPassword(
String operatorRoleCode,
String operatorAuthLevel,
String targetRoleCode,
@@ -18,15 +18,6 @@ public interface AuthAdminService {
String newPassword
);
void changeLimitedAccountPassword(
String operatorRoleCode,
String operatorAuthLevel,
String targetRoleCode,
String username,
String oldPassword,
String newPassword
);
UKeySignResult issueUkeyBindingSign(
String operatorRoleCode,
String operatorAuthLevel,
@@ -27,7 +27,5 @@ public interface AuthService {
void logout(String sessionToken);
void changeFullAccountPassword(String sessionToken, Integer uid, String currentPassword, String newPassword);
void changeLimitedAccountPassword(String sessionToken, String username, String currentPassword, String newPassword);
void changeAccountPassword(String sessionToken, Integer uid, String currentPassword, String newPassword);
}
@@ -4,13 +4,11 @@ import com.cisd.tms.common.enums.ErrorCode;
import com.cisd.tms.common.exception.BizException;
import com.cisd.tms.common.util.TraceIdUtil;
import com.cisd.tms.modules.auth.entity.AuthFullAccountEntity;
import com.cisd.tms.modules.auth.entity.AuthUserAccountEntity;
import com.cisd.tms.modules.auth.entity.RoleAccountEntity;
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
import com.cisd.tms.modules.auth.enums.RoleAccountStatus;
import com.cisd.tms.modules.auth.enums.RoleCode;
import com.cisd.tms.modules.auth.repository.AuthFullAccountRepository;
import com.cisd.tms.modules.auth.repository.AuthUserAccountRepository;
import com.cisd.tms.modules.auth.repository.RoleAccountRepository;
import com.cisd.tms.modules.auth.repository.RoleUkeyBindingRepository;
import com.cisd.tms.modules.auth.service.AuthAdminService;
@@ -40,7 +38,6 @@ public class AuthAdminServiceImpl implements AuthAdminService {
private final RoleAccountRepository roleAccountRepository;
private final AuthFullAccountRepository authFullAccountRepository;
private final AuthUserAccountRepository authUserAccountRepository;
private final RoleUkeyBindingRepository roleUkeyBindingRepository;
private final PasswordHasher passwordHasher;
private final LmkService lmkService;
@@ -68,19 +65,6 @@ public class AuthAdminServiceImpl implements AuthAdminService {
authFullAccountRepository.update(account);
}
List<AuthUserAccountEntity> accounts = authUserAccountRepository.findByRoleCode(targetRoleCode);
if (accounts.isEmpty()) {
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "target role user accounts not found");
}
for (AuthUserAccountEntity account : accounts) {
account.setStatus(RoleAccountStatus.ACTIVE.name());
account.setNeedChangePassword(Boolean.TRUE);
account.setFailedCount(0);
account.setLockedUntil(null);
account.setLastActiveAt(null);
account.setLastLoginAt(null);
authUserAccountRepository.update(account);
}
}
@Override
@@ -108,27 +92,10 @@ public class AuthAdminServiceImpl implements AuthAdminService {
authFullAccountRepository.update(account);
}
List<AuthUserAccountEntity> accounts = authUserAccountRepository.findByRoleCode(targetRoleCode);
if (accounts.isEmpty()) {
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "target role user accounts not found");
}
for (AuthUserAccountEntity account : accounts) {
String newSalt = passwordSaltGenerator.nextSalt();
account.setPasswordSalt(newSalt);
account.setPasswordHash(passwordHasher.hash(DEFAULT_PASSWORD, newSalt));
account.setStatus(RoleAccountStatus.ACTIVE.name());
account.setNeedChangePassword(Boolean.TRUE);
account.setPasswordChangedAt(current);
account.setFailedCount(0);
account.setLockedUntil(null);
account.setLastActiveAt(null);
account.setLastLoginAt(null);
authUserAccountRepository.update(account);
}
}
@Override
public void changeFullAccountPassword(
public void changeAccountPassword(
String operatorRoleCode,
String operatorAuthLevel,
String targetRoleCode,
@@ -151,29 +118,6 @@ public class AuthAdminServiceImpl implements AuthAdminService {
authFullAccountRepository.update(account);
}
@Override
public void changeLimitedAccountPassword(
String operatorRoleCode,
String operatorAuthLevel,
String targetRoleCode,
String username,
String oldPassword,
String newPassword
) {
PasswordComplexityValidator.validate(newPassword);
loadRole(targetRoleCode);
AuthUserAccountEntity account = authUserAccountRepository.findByUsername(username)
.orElseThrow(() -> new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "target role user account not found"));
if (!targetRoleCode.equals(account.getRoleCode())) {
throw new BizException(ErrorCode.VALIDATE_FAILED.getCode(), "target role user account not found");
}
if (!passwordHasher.matches(oldPassword, account.getPasswordSalt(), account.getPasswordHash())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "old password is incorrect");
}
applyAdminPasswordChange(account, newPassword);
authUserAccountRepository.update(account);
}
private void bindUkey(
String targetRoleCode,
Integer uid,
@@ -277,19 +221,6 @@ public class AuthAdminServiceImpl implements AuthAdminService {
}
}
private void applyAdminPasswordChange(AuthUserAccountEntity account, String newPassword) {
String newSalt = passwordSaltGenerator.nextSalt();
account.setPasswordSalt(newSalt);
account.setPasswordHash(passwordHasher.hash(newPassword, newSalt));
account.setNeedChangePassword(Boolean.TRUE);
account.setPasswordChangedAt(now());
account.setFailedCount(0);
account.setLockedUntil(null);
if (RoleAccountStatus.LOCKED.name().equals(account.getStatus())) {
account.setStatus(RoleAccountStatus.ACTIVE.name());
}
}
private RoleAccountEntity loadRole(String roleCode) {
resolveRoleCode(roleCode);
return roleAccountRepository.findByRoleCode(roleCode)
@@ -16,8 +16,6 @@ import com.cisd.tms.modules.auth.dto.UkeyLoginRandomResponse;
import com.cisd.tms.modules.auth.dto.UkeyLoginRequest;
import com.cisd.tms.modules.auth.entity.AuthFullAccountEntity;
import com.cisd.tms.modules.auth.entity.AuthSessionEntity;
import com.cisd.tms.modules.auth.entity.AuthUserAccountEntity;
import com.cisd.tms.modules.auth.entity.AuthUserEntity;
import com.cisd.tms.modules.auth.entity.RoleAccountEntity;
import com.cisd.tms.modules.auth.entity.RoleUkeyBindingEntity;
import com.cisd.tms.modules.auth.enums.AuthLevel;
@@ -26,8 +24,6 @@ import com.cisd.tms.modules.auth.enums.RoleAccountStatus;
import com.cisd.tms.modules.auth.enums.RoleCode;
import com.cisd.tms.modules.auth.repository.AuthFullAccountRepository;
import com.cisd.tms.modules.auth.repository.AuthSessionRepository;
import com.cisd.tms.modules.auth.repository.AuthUserAccountRepository;
import com.cisd.tms.modules.auth.repository.AuthUserRepository;
import com.cisd.tms.modules.auth.repository.RoleAccountRepository;
import com.cisd.tms.modules.auth.repository.RoleUkeyBindingRepository;
import com.cisd.tms.modules.auth.service.AuthPolicyService;
@@ -69,8 +65,6 @@ public class AuthServiceImpl implements AuthService {
private static final int PASSWORD_EXPIRE_DAYS = 30;
private final RoleAccountRepository roleAccountRepository;
private final AuthUserRepository authUserRepository;
private final AuthUserAccountRepository authUserAccountRepository;
private final AuthFullAccountRepository authFullAccountRepository;
private final AuthSessionRepository authSessionRepository;
private final RoleUkeyBindingRepository roleUkeyBindingRepository;
@@ -92,19 +86,17 @@ public class AuthServiceImpl implements AuthService {
validateRoleStatus(roleAccount);
AuthMethod authMethod = resolveAuthMethod(request.getUkeySerials());
List<AuthUserAccountEntity> validatedAccounts = new ArrayList<>();
List<AuthFullAccountEntity> validatedFullAccounts = new ArrayList<>();
List<AuthFullAccountEntity> validatedAccounts;
if (AuthMethod.PASSWORD == authMethod) {
validatedAccounts = validateRoleAccounts(roleAccount, request.getAccounts());
resetValidatedAccounts(validatedAccounts);
} else {
validatedFullAccounts = validateFullAccounts(roleAccount, request.getFullAccounts());
resetValidatedFullAccounts(validatedFullAccounts);
validatedAccounts = validateFullAccounts(roleAccount, request.getFullAccounts());
}
resetValidatedAccounts(validatedAccounts);
AuthLevel authLevel = resolveAuthLevel(roleAccount, request.getUkeySerials());
List<AuthSessionPrincipal> authenticatedPrincipals = AuthMethod.PASSWORD == authMethod
? normalizeAuthenticatedUsers(validatedAccounts)
: normalizeAuthenticatedFullAccounts(validatedFullAccounts);
? normalizeAuthenticatedAccounts(validatedAccounts, AuthLevel.LIMITED)
: normalizeAuthenticatedAccounts(validatedAccounts, AuthLevel.FULL);
expireConcurrentSessions(roleAccount.getRoleCode(), authLevel, authenticatedPrincipals);
AuthSessionEntity session = buildSession(
roleAccount.getRoleCode(),
@@ -120,9 +112,7 @@ public class AuthServiceImpl implements AuthService {
response.setToken(session.getSessionToken());
response.setExpiresAt(OffsetDateTime.of(session.getExpiresAt(), ZoneOffset.UTC).toString());
response.setNeedChangePassword(
AuthMethod.PASSWORD == authMethod
? needsPasswordChangeForLimitedAccounts(validatedAccounts)
: needsPasswordChangeForFullAccounts(validatedFullAccounts)
needsPasswordChangeForAccounts(validatedAccounts)
);
return response;
}
@@ -189,36 +179,19 @@ public class AuthServiceImpl implements AuthService {
@Override
public CurrentUserResponse me(String username, String sessionToken) {
String normalized = username == null || username.isBlank() ? "admin" : username;
RoleAccountEntity roleAccount = roleAccountRepository.findByRoleCode(normalized).orElse(null);
if (roleAccount != null) {
CurrentUserResponse response = new CurrentUserResponse();
response.setUsername(roleAccount.getRoleCode());
response.setDisplayName(roleAccount.getDisplayName());
response.setRole(roleAccount.getRoleCode());
AuthSessionEntity session = sessionToken == null ? null : authSessionRepository.findBySessionToken(sessionToken).orElse(null);
if (session != null) {
response.setAuthLevel(session.getAuthLevel());
response.setNeedChangePassword(needsPasswordChange(session));
} else {
response.setNeedChangePassword(Boolean.FALSE);
}
return response;
}
AuthUserEntity entity = authUserRepository.findByUsername(normalized).orElse(null);
RoleAccountEntity roleAccount = roleAccountRepository.findByRoleCode(normalized)
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "role account not found"));
CurrentUserResponse response = new CurrentUserResponse();
if (entity == null) {
response.setUsername(normalized);
response.setDisplayName("TMS Administrator");
response.setRole("ADMIN");
response.setUsername(roleAccount.getRoleCode());
response.setDisplayName(roleAccount.getDisplayName());
response.setRole(roleAccount.getRoleCode());
AuthSessionEntity session = sessionToken == null ? null : authSessionRepository.findBySessionToken(sessionToken).orElse(null);
if (session != null) {
response.setAuthLevel(session.getAuthLevel());
response.setNeedChangePassword(needsPasswordChange(session));
} else {
response.setNeedChangePassword(Boolean.FALSE);
return response;
}
response.setUsername(entity.getUsername());
response.setDisplayName(entity.getDisplayName());
response.setRole(entity.getRole());
response.setNeedChangePassword(Boolean.FALSE);
return response;
}
@@ -231,17 +204,14 @@ public class AuthServiceImpl implements AuthService {
}
@Override
public void changeFullAccountPassword(String sessionToken, Integer uid, String currentPassword, String newPassword) {
public void changeAccountPassword(String sessionToken, Integer uid, String currentPassword, String newPassword) {
PasswordComplexityValidator.validate(newPassword);
AuthSessionEntity session = requireActiveSession(sessionToken);
if (!AuthLevel.FULL.name().equals(session.getAuthLevel())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "full session is required");
}
if (uid == null || !containsAuthenticatedFullUid(session, uid)) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "full account is not authenticated in current session");
if (uid == null || !containsAuthenticatedUid(session, uid)) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "account is not authenticated in current session");
}
AuthFullAccountEntity fullAccount = authFullAccountRepository.findByRoleCodeAndUid(session.getRoleCode(), uid)
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "full account not found"));
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "account not found"));
validateFullAccountStatus(fullAccount);
if (!passwordHasher.matches(currentPassword, fullAccount.getPasswordSalt(), fullAccount.getPasswordHash())) {
onFullPasswordFailed(fullAccount);
@@ -265,49 +235,13 @@ public class AuthServiceImpl implements AuthService {
authSessionRepository.update(session);
}
@Override
public void changeLimitedAccountPassword(String sessionToken, String username, String currentPassword, String newPassword) {
PasswordComplexityValidator.validate(newPassword);
AuthSessionEntity session = requireActiveSession(sessionToken);
if (!AuthLevel.LIMITED.name().equals(session.getAuthLevel())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "limited session is required");
}
if (username == null || username.isBlank() || !containsAuthenticatedLimitedUsername(session, username)) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "limited account is not authenticated in current session");
}
AuthUserAccountEntity userAccount = authUserAccountRepository.findByUsername(username)
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "user account not found"));
validateUserAccountRole(session.getRoleCode(), userAccount);
validateUserAccountStatus(userAccount);
if (!passwordHasher.matches(currentPassword, userAccount.getPasswordSalt(), userAccount.getPasswordHash())) {
onPasswordFailed(userAccount);
}
String salt = passwordSaltGenerator.nextSalt();
LocalDateTime current = now();
userAccount.setPasswordSalt(salt);
userAccount.setPasswordHash(passwordHasher.hash(newPassword, salt));
userAccount.setFailedCount(0);
userAccount.setLockedUntil(null);
userAccount.setStatus(RoleAccountStatus.ACTIVE.name());
userAccount.setNeedChangePassword(Boolean.FALSE);
userAccount.setPasswordChangedAt(current);
userAccount.setLastLoginAt(current);
userAccount.setLastActiveAt(current);
authUserAccountRepository.update(userAccount);
session.setLastActiveAt(current);
session.setExpiresAt(current.plusMinutes(IDLE_TIMEOUT_MINUTES));
authSessionRepository.update(session);
}
private void validateRoleStatus(RoleAccountEntity roleAccount) {
if (!RoleAccountStatus.ACTIVE.name().equals(roleAccount.getStatus())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "role is not enabled");
}
}
private List<AuthUserAccountEntity> validateRoleAccounts(
private List<AuthFullAccountEntity> validateRoleAccounts(
RoleAccountEntity roleAccount,
List<PasswordLoginAccountRequest> accounts
) {
@@ -319,54 +253,25 @@ public class AuthServiceImpl implements AuthService {
);
}
Set<String> uniqueUsernames = new LinkedHashSet<>();
List<AuthUserAccountEntity> validatedAccounts = new ArrayList<>();
Set<Integer> uniqueUids = new LinkedHashSet<>();
List<AuthFullAccountEntity> validatedAccounts = new ArrayList<>();
for (PasswordLoginAccountRequest account : accounts) {
if (!uniqueUsernames.add(account.getUsername())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "duplicate account username submitted");
Integer uid = account.getUid();
if (uid == null || !uniqueUids.add(uid)) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "duplicate account uid submitted");
}
AuthUserAccountEntity userAccount = authUserAccountRepository.findByUsername(account.getUsername())
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "user account not found"));
validateUserAccountRole(roleAccount.getRoleCode(), userAccount);
validateUserAccountStatus(userAccount);
if (!passwordHasher.matches(account.getPassword(), userAccount.getPasswordSalt(), userAccount.getPasswordHash())) {
onPasswordFailed(userAccount);
AuthFullAccountEntity roleAccountSeat = authFullAccountRepository
.findByRoleCodeAndUid(roleAccount.getRoleCode(), uid)
.orElseThrow(() -> new BizException(ErrorCode.UNAUTHORIZED.getCode(), "account not found"));
validateFullAccountStatus(roleAccountSeat);
if (!passwordHasher.matches(account.getPassword(), roleAccountSeat.getPasswordSalt(), roleAccountSeat.getPasswordHash())) {
onFullPasswordFailed(roleAccountSeat);
}
validatedAccounts.add(userAccount);
validatedAccounts.add(roleAccountSeat);
}
return validatedAccounts;
}
private void validateUserAccountRole(String expectedRoleCode, AuthUserAccountEntity userAccount) {
if (!expectedRoleCode.equals(userAccount.getRoleCode())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "user account does not belong to target role");
}
}
private void validateUserAccountStatus(AuthUserAccountEntity userAccount) {
if (RoleAccountStatus.UNENABLED.name().equals(userAccount.getStatus())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "user account is not enabled");
}
if (RoleAccountStatus.LOCKED.name().equals(userAccount.getStatus())
&& (userAccount.getLockedUntil() == null || userAccount.getLockedUntil().isAfter(now()))) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "user account is locked");
}
}
private void onPasswordFailed(AuthUserAccountEntity userAccount) {
int failedCount = userAccount.getFailedCount() == null ? 0 : userAccount.getFailedCount();
failedCount++;
userAccount.setFailedCount(failedCount);
if (failedCount >= MAX_FAILED_ATTEMPTS) {
userAccount.setStatus(RoleAccountStatus.LOCKED.name());
userAccount.setLockedUntil(now().plusMinutes(IDLE_TIMEOUT_MINUTES));
authUserAccountRepository.update(userAccount);
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "user account is locked");
}
authUserAccountRepository.update(userAccount);
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "password is incorrect");
}
private void validateFullAccountStatus(AuthFullAccountEntity fullAccount) {
if (RoleAccountStatus.UNENABLED.name().equals(fullAccount.getStatus())) {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "full account is not enabled");
@@ -391,19 +296,7 @@ public class AuthServiceImpl implements AuthService {
throw new BizException(ErrorCode.UNAUTHORIZED.getCode(), "password is incorrect");
}
private void resetValidatedAccounts(List<AuthUserAccountEntity> validatedAccounts) {
LocalDateTime current = now();
for (AuthUserAccountEntity account : validatedAccounts) {
account.setFailedCount(0);
account.setLockedUntil(null);
account.setStatus(RoleAccountStatus.ACTIVE.name());
account.setLastLoginAt(current);
account.setLastActiveAt(current);
authUserAccountRepository.update(account);
}
}
private void resetValidatedFullAccounts(List<AuthFullAccountEntity> validatedAccounts) {
private void resetValidatedAccounts(List<AuthFullAccountEntity> validatedAccounts) {
LocalDateTime current = now();
for (AuthFullAccountEntity account : validatedAccounts) {
account.setFailedCount(0);
@@ -587,25 +480,18 @@ public class AuthServiceImpl implements AuthService {
}
}
private List<AuthSessionPrincipal> normalizeAuthenticatedUsers(List<AuthUserAccountEntity> validatedAccounts) {
private List<AuthSessionPrincipal> normalizeAuthenticatedAccounts(
List<AuthFullAccountEntity> validatedAccounts,
AuthLevel authLevel
) {
if (validatedAccounts == null || validatedAccounts.isEmpty()) {
return null;
}
return validatedAccounts.stream()
.map(AuthUserAccountEntity::getUsername)
.sorted()
.map(AuthSessionPrincipal::limited)
.toList();
}
private List<AuthSessionPrincipal> normalizeAuthenticatedFullAccounts(List<AuthFullAccountEntity> validatedAccounts) {
if (validatedAccounts == null || validatedAccounts.isEmpty()) {
return null;
}
return validatedAccounts.stream()
.map(AuthFullAccountEntity::getUid)
.sorted()
.map(AuthSessionPrincipal::full)
.sorted(java.util.Comparator.comparing(AuthFullAccountEntity::getUid))
.map(account -> AuthLevel.FULL == authLevel
? AuthSessionPrincipal.full(account.getUid(), account.getAccountName())
: AuthSessionPrincipal.limited(account.getUid(), account.getAccountName()))
.toList();
}
@@ -636,7 +522,11 @@ public class AuthServiceImpl implements AuthService {
if (value.startsWith("FULL:")) {
principals.add(AuthSessionPrincipal.full(Integer.parseInt(value.substring("FULL:".length()))));
} else {
principals.add(AuthSessionPrincipal.limited(value));
AuthFullAccountEntity account = authFullAccountRepository.findByRoleCode(session.getRoleCode()).stream()
.filter(item -> value.equals(item.getAccountName()))
.findFirst()
.orElse(null);
principals.add(AuthSessionPrincipal.limited(account == null ? null : account.getUid(), value));
}
}
return principals;
@@ -650,25 +540,16 @@ public class AuthServiceImpl implements AuthService {
}
}
private boolean containsAuthenticatedFullUid(AuthSessionEntity session, Integer uid) {
private boolean containsAuthenticatedUid(AuthSessionEntity session, Integer uid) {
return authenticatedPrincipals(session).stream()
.anyMatch(principal -> "FULL".equals(principal.getType()) && uid.equals(principal.getUid()));
}
private boolean containsAuthenticatedLimitedUsername(AuthSessionEntity session, String username) {
return authenticatedPrincipals(session).stream()
.anyMatch(principal -> "LIMITED".equals(principal.getType()) && username.equals(principal.getUsername()));
.anyMatch(principal -> uid.equals(principal.getUid()));
}
private LocalDateTime now() {
return LocalDateTime.ofInstant(clock.instant(), ZoneOffset.UTC);
}
private boolean needsPasswordChangeForLimitedAccounts(List<AuthUserAccountEntity> accounts) {
return accounts != null && accounts.stream().anyMatch(this::needsPasswordChange);
}
private boolean needsPasswordChangeForFullAccounts(List<AuthFullAccountEntity> accounts) {
private boolean needsPasswordChangeForAccounts(List<AuthFullAccountEntity> accounts) {
return accounts != null && accounts.stream().anyMatch(this::needsPasswordChange);
}
@@ -680,18 +561,10 @@ public class AuthServiceImpl implements AuthService {
if (principals.isEmpty()) {
return false;
}
if (AuthLevel.FULL.name().equals(session.getAuthLevel())) {
List<AuthFullAccountEntity> accounts = authFullAccountRepository.findByRoleCode(session.getRoleCode());
return accounts.stream()
.filter(account -> principals.stream()
.anyMatch(principal -> "FULL".equals(principal.getType()) && account.getUid().equals(principal.getUid())))
.anyMatch(this::needsPasswordChange);
}
List<AuthUserAccountEntity> accounts = authUserAccountRepository.findByRoleCode(session.getRoleCode());
List<AuthFullAccountEntity> accounts = authFullAccountRepository.findByRoleCode(session.getRoleCode());
return accounts.stream()
.filter(account -> principals.stream()
.anyMatch(principal -> "LIMITED".equals(principal.getType())
&& account.getUsername().equals(principal.getUsername())))
.anyMatch(principal -> account.getUid().equals(principal.getUid())))
.anyMatch(this::needsPasswordChange);
}
@@ -700,11 +573,6 @@ public class AuthServiceImpl implements AuthService {
|| isPasswordExpired(account.getPasswordChangedAt());
}
private boolean needsPasswordChange(AuthUserAccountEntity account) {
return Boolean.TRUE.equals(account.getNeedChangePassword())
|| isPasswordExpired(account.getPasswordChangedAt());
}
private boolean isPasswordExpired(LocalDateTime passwordChangedAt) {
return passwordChangedAt == null || !passwordChangedAt.isAfter(now().minusDays(PASSWORD_EXPIRE_DAYS));
}
@@ -37,6 +37,9 @@ public class PcieCompatUkeyVerifier implements CompatUkeyVerifier {
private static final String PROVIDER = "BC";
private static final String SIGNATURE_ALGORITHM = "SM3withSM2";
private static final String SM2_CURVE = "sm2p256v1";
private static final int GM0018_ECCREF_PUBLIC_KEY_LENGTH = 132;
private static final int GM0018_ECCREF_COMPONENT_LENGTH = 64;
private static final int SM2_COORDINATE_LENGTH = 32;
static {
if (Security.getProvider(PROVIDER) == null) {
@@ -65,6 +68,9 @@ public class PcieCompatUkeyVerifier implements CompatUkeyVerifier {
public void verifyLoginSignature(String pubKey, String loginSignData, String loginSign) {
try {
PublicKey publicKey = parsePublicKey(pubKey);
if (loginSignData == null || loginSignData.isBlank()) {
throw new IllegalArgumentException("login sign data is required");
}
byte[] signatureBytes = decodeSignature(loginSign);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
signature.initVerify(publicKey);
@@ -96,7 +102,7 @@ public class PcieCompatUkeyVerifier implements CompatUkeyVerifier {
try {
return KeyFactory.getInstance("EC", PROVIDER).generatePublic(new X509EncodedKeySpec(decoded));
} catch (Exception ignored) {
return parseUncompressedPointPublicKey(decoded);
return parseUncompressedPointPublicKey(toPointBytes(decoded));
}
}
@@ -110,12 +116,40 @@ public class PcieCompatUkeyVerifier implements CompatUkeyVerifier {
}
}
private PublicKey parseUncompressedPointPublicKey(byte[] keyBytes) throws Exception {
byte[] pointBytes = keyBytes;
private byte[] toPointBytes(byte[] keyBytes) {
if (keyBytes.length == GM0018_ECCREF_PUBLIC_KEY_LENGTH) {
return gm0018EccRefToPointBytes(keyBytes);
}
return keyBytes;
}
private byte[] gm0018EccRefToPointBytes(byte[] keyBytes) {
int bitsLittleEndian = (keyBytes[0] & 0xff)
| ((keyBytes[1] & 0xff) << 8)
| ((keyBytes[2] & 0xff) << 16)
| ((keyBytes[3] & 0xff) << 24);
int bitsBigEndian = ((keyBytes[0] & 0xff) << 24)
| ((keyBytes[1] & 0xff) << 16)
| ((keyBytes[2] & 0xff) << 8)
| (keyBytes[3] & 0xff);
if (bitsLittleEndian != 256 && bitsBigEndian != 256) {
throw new IllegalArgumentException("login public key is invalid");
}
byte[] pointBytes = new byte[65];
pointBytes[0] = 0x04;
System.arraycopy(keyBytes, 4 + GM0018_ECCREF_COMPONENT_LENGTH - SM2_COORDINATE_LENGTH,
pointBytes, 1, SM2_COORDINATE_LENGTH);
System.arraycopy(keyBytes, 4 + GM0018_ECCREF_COMPONENT_LENGTH * 2 - SM2_COORDINATE_LENGTH,
pointBytes, 1 + SM2_COORDINATE_LENGTH, SM2_COORDINATE_LENGTH);
return pointBytes;
}
private PublicKey parseUncompressedPointPublicKey(byte[] pointBytes) throws Exception {
if (pointBytes.length == 64) {
byte[] rawPointBytes = pointBytes;
pointBytes = new byte[65];
pointBytes[0] = 0x04;
System.arraycopy(keyBytes, 0, pointBytes, 1, keyBytes.length);
System.arraycopy(rawPointBytes, 0, pointBytes, 1, rawPointBytes.length);
}
if (pointBytes.length != 65 || pointBytes[0] != 0x04) {
throw new IllegalArgumentException("login public key is invalid");
@@ -129,16 +163,31 @@ public class PcieCompatUkeyVerifier implements CompatUkeyVerifier {
}
private byte[] decodeSignature(String value) {
if (value == null || value.isBlank()) {
throw new IllegalArgumentException("login signature is required");
}
byte[] decoded = decodeHexOrBase64(normalize(value), "login signature is invalid");
if (isDerSignature(decoded)) {
return decoded;
}
if (decoded.length == GM0018_ECCREF_COMPONENT_LENGTH * 2) {
return rawRsToDer(gm0018SignatureToRawRs(decoded));
}
if (decoded.length == 64) {
return rawRsToDer(decoded);
}
throw new IllegalArgumentException("login signature is invalid");
}
private byte[] gm0018SignatureToRawRs(byte[] signatureBytes) {
byte[] rawSignature = new byte[64];
System.arraycopy(signatureBytes, GM0018_ECCREF_COMPONENT_LENGTH - SM2_COORDINATE_LENGTH,
rawSignature, 0, SM2_COORDINATE_LENGTH);
System.arraycopy(signatureBytes, GM0018_ECCREF_COMPONENT_LENGTH * 2 - SM2_COORDINATE_LENGTH,
rawSignature, SM2_COORDINATE_LENGTH, SM2_COORDINATE_LENGTH);
return rawSignature;
}
private boolean isDerSignature(byte[] signatureBytes) {
try (ASN1InputStream inputStream = new ASN1InputStream(signatureBytes)) {
ASN1Primitive primitive = inputStream.readObject();
@@ -142,7 +142,7 @@ public class OperationAuditAspect {
return "";
}
return request.getAccounts().stream()
.map(account -> account.getUsername() == null ? "" : account.getUsername().trim())
.map(account -> account.getUid() == null ? "" : "uid=" + account.getUid())
.filter(value -> !value.isBlank())
.collect(Collectors.joining(","));
}
@@ -139,16 +139,6 @@ CREATE TABLE IF NOT EXISTS tms_resource_task_step (
-- 认证与设备基础表
-- -----------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS tms_auth_user (
id BIGINT PRIMARY KEY,
username VARCHAR(64) NOT NULL,
display_name VARCHAR(128) NOT NULL,
role VARCHAR(64) NOT NULL,
create_time DATETIME(3) NOT NULL,
update_time DATETIME(3) NOT NULL,
UNIQUE KEY uk_tms_auth_user_username (username)
);
CREATE TABLE IF NOT EXISTS tms_device_node (
id BIGINT PRIMARY KEY,
node_id VARCHAR(64) NOT NULL,
@@ -267,26 +257,6 @@ CREATE TABLE IF NOT EXISTS tms_role_ukey_binding (
KEY idx_tms_role_ukey_binding_role_status (role_code, status)
);
CREATE TABLE IF NOT EXISTS tms_auth_user_account (
id BIGINT PRIMARY KEY,
username VARCHAR(64) NOT NULL,
display_name VARCHAR(128) NOT NULL,
role_code VARCHAR(64) NOT NULL,
password_hash VARCHAR(256) NOT NULL,
password_salt VARCHAR(128) NOT NULL,
status VARCHAR(32) NOT NULL,
need_change_password TINYINT(1) NOT NULL DEFAULT 1,
password_changed_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
failed_count INT NOT NULL DEFAULT 0,
locked_until DATETIME(3) NULL,
last_login_at DATETIME(3) NULL,
last_active_at DATETIME(3) NULL,
create_time DATETIME(3) NOT NULL,
update_time DATETIME(3) NOT NULL,
UNIQUE KEY uk_tms_auth_user_account_username (username),
KEY idx_tms_auth_user_account_role_code (role_code)
);
CREATE TABLE IF NOT EXISTS tms_auth_full_account (
id BIGINT PRIMARY KEY,
role_code VARCHAR(64) NOT NULL,
@@ -439,110 +409,6 @@ VALUES
CURRENT_TIMESTAMP(3)
);
INSERT IGNORE INTO tms_auth_user_account (
id,
username,
display_name,
role_code,
password_hash,
password_salt,
status,
need_change_password,
password_changed_at,
failed_count,
locked_until,
last_login_at,
last_active_at,
create_time,
update_time
)
VALUES
(
12001,
'super-admin-01',
'超级管理员账号一',
'SUPER_ADMIN',
'Viuew8WE+qziUZwGGU0x25cUpzsTF+QvQFU0uhb+yVA=',
'init-super-admin-salt-20260325',
'ACTIVE',
1,
CURRENT_TIMESTAMP(3),
0,
NULL,
NULL,
NULL,
CURRENT_TIMESTAMP(3),
CURRENT_TIMESTAMP(3)
),
(
12002,
'super-admin-02',
'超级管理员账号二',
'SUPER_ADMIN',
'Viuew8WE+qziUZwGGU0x25cUpzsTF+QvQFU0uhb+yVA=',
'init-super-admin-salt-20260325',
'ACTIVE',
1,
CURRENT_TIMESTAMP(3),
0,
NULL,
NULL,
NULL,
CURRENT_TIMESTAMP(3),
CURRENT_TIMESTAMP(3)
),
(
12003,
'key-admin-01',
'密钥管理员账号',
'KEY_ADMIN',
'/xqmDy3A/q9X5p7XWznIPSBabQ6bxTLAPgtHQ6Be33c=',
'init-key-admin-salt-20260325',
'ACTIVE',
1,
CURRENT_TIMESTAMP(3),
0,
NULL,
NULL,
NULL,
CURRENT_TIMESTAMP(3),
CURRENT_TIMESTAMP(3)
),
(
12004,
'audit-admin-01',
'审计管理员账号',
'AUDIT_ADMIN',
'j/J1LKyUOzVEJfbbHe2dwKBKNdabRk502olk/LWIwhg=',
'init-audit-admin-salt-20260325',
'ACTIVE',
1,
CURRENT_TIMESTAMP(3),
0,
NULL,
NULL,
NULL,
CURRENT_TIMESTAMP(3),
CURRENT_TIMESTAMP(3)
),
(
12005,
'ops-admin-01',
'运维管理员账号',
'OPS_ADMIN',
'2e9F4aCgsDb+AuD1LrBEqEg8yjy3ODo27UHtx06vj/A=',
'init-ops-admin-salt-20260325',
'ACTIVE',
1,
CURRENT_TIMESTAMP(3),
0,
NULL,
NULL,
NULL,
CURRENT_TIMESTAMP(3),
CURRENT_TIMESTAMP(3)
);
INSERT IGNORE INTO tms_auth_full_account (
id,
role_code,
@@ -1,66 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cisd.tms.modules.auth.mapper.AuthUserAccountMapper">
<resultMap id="AuthUserAccountResultMap" type="com.cisd.tms.modules.auth.entity.AuthUserAccountEntity">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="displayName" column="display_name"/>
<result property="roleCode" column="role_code"/>
<result property="passwordHash" column="password_hash"/>
<result property="passwordSalt" column="password_salt"/>
<result property="status" column="status"/>
<result property="needChangePassword" column="need_change_password"/>
<result property="passwordChangedAt" column="password_changed_at"/>
<result property="failedCount" column="failed_count"/>
<result property="lockedUntil" column="locked_until"/>
<result property="lastLoginAt" column="last_login_at"/>
<result property="lastActiveAt" column="last_active_at"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectByUsername" parameterType="string" resultMap="AuthUserAccountResultMap">
SELECT id,
username,
display_name,
role_code,
password_hash,
password_salt,
status,
need_change_password,
password_changed_at,
failed_count,
locked_until,
last_login_at,
last_active_at,
create_time,
update_time
FROM tms_auth_user_account
WHERE username = #{username}
LIMIT 1
</select>
<select id="selectByRoleCode" parameterType="string" resultMap="AuthUserAccountResultMap">
SELECT id,
username,
display_name,
role_code,
password_hash,
password_salt,
status,
need_change_password,
password_changed_at,
failed_count,
locked_until,
last_login_at,
last_active_at,
create_time,
update_time
FROM tms_auth_user_account
WHERE role_code = #{roleCode}
ORDER BY username ASC
</select>
</mapper>
@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cisd.tms.modules.auth.mapper.AuthUserMapper">
<resultMap id="AuthUserResultMap" type="com.cisd.tms.modules.auth.entity.AuthUserEntity">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="displayName" column="display_name"/>
<result property="role" column="role"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
</resultMap>
<select id="selectByUsername" parameterType="string" resultMap="AuthUserResultMap">
SELECT id, username, display_name, role, create_time, update_time
FROM tms_auth_user
WHERE username = #{username}
LIMIT 1
</select>
</mapper>