【7.6.0】【sys】【permission】从新整理登录逻辑,封装其他的登录过程方法

pull/57/head
fengshuonan 2023-06-20 23:20:23 +08:00
parent bb2af77c1c
commit d6c53289ca
1 changed files with 109 additions and 76 deletions

View File

@ -91,54 +91,25 @@ public class LoginService {
*/
public LoginResponse loginAction(LoginRequest loginRequest, Boolean validatePassword, String caToken) {
// 校验当前系统是否初始化资源完成,如果资源还没有初始化,提示用户请等一下再登录
if (!InitScanFlagHolder.getFlag()) {
throw new ScannerException(ScannerExceptionEnum.SYSTEM_RESOURCE_URL_NOT_INIT);
}
// 1.参数为空校验
this.validateEmptyParams(loginRequest, validatePassword);
validateEmptyParams(loginRequest, validatePassword);
// 1.2 判断账号是否密码重试次数过多被冻结
Integer loginErrorCount = loginErrorCountCacheApi.get(loginRequest.getAccount());
if (loginErrorCount != null && loginErrorCount >= LoginCacheConstants.MAX_ERROR_LOGIN_COUNT) {
throw new AuthException(AuthExceptionEnum.LOGIN_LOCKED);
}
Integer loginErrorCount = validatePasswordRetryTimes(loginRequest);
// 1.3 暂存多租户编码v7.3.2增加,方便缓存调用过程中获取多租户的前缀)
RequestTenantCodeHolder.setTenantCode(loginRequest.getTenantCode());
// 2. 如果开启了验证码校验,则验证当前请求的验证码是否正确
if (SecurityConfigExpander.getCaptchaOpen()) {
String verKey = loginRequest.getVerKey();
String verCode = loginRequest.getVerCode();
if (StrUtil.isEmpty(verKey) || StrUtil.isEmpty(verCode)) {
throw new AuthException(ValidatorExceptionEnum.CAPTCHA_EMPTY);
}
if (!captchaApi.validateCaptcha(verKey, verCode)) {
throw new AuthException(ValidatorExceptionEnum.CAPTCHA_ERROR);
}
}
// 2.1 验证拖拽验证码
if (SecurityConfigExpander.getDragCaptchaOpen()) {
String verKey = loginRequest.getVerKey();
String verXLocationValue = loginRequest.getVerCode();
if (StrUtil.isEmpty(verKey) || StrUtil.isEmpty(verXLocationValue)) {
throw new AuthException(ValidatorExceptionEnum.CAPTCHA_EMPTY);
}
if (!dragCaptchaApi.validateCaptcha(verKey, Convert.toInt(verXLocationValue))) {
throw new AuthException(ValidatorExceptionEnum.DRAG_CAPTCHA_ERROR);
}
}
// 2.2 校验当前系统是否初始化资源完成,如果资源还没有初始化,提示用户请等一下再登录
if (!InitScanFlagHolder.getFlag()) {
throw new ScannerException(ScannerExceptionEnum.SYSTEM_RESOURCE_URL_NOT_INIT);
}
validateCaptcha(loginRequest);
// 3. 解密密码的密文需要sys_config相关配置打开
if (loginRequest.getPassword() != null && AuthConfigExpander.getPasswordRsaValidateFlag()) {
String decryptPassword = passwordTransferEncryptApi.decrypt(loginRequest.getPassword());
loginRequest.setPassword(decryptPassword);
}
decryptRequestPassword(loginRequest);
// 4. 如果开启了单点登录并且CaToken没有值走单点登录获取loginCode
if (ssoProperties.getOpenFlag() && StrUtil.isEmpty(caToken)) {
@ -171,23 +142,23 @@ public class LoginService {
// 8. 生成用户的token
DefaultJwtPayload defaultJwtPayload = new DefaultJwtPayload(userValidateInfo.getUserId(), loginRequest.getAccount(),
loginRequest.getRememberMe(), caToken, loginRequest.getTenantCode());
String jwtToken = AuthJwtContext.me().generateTokenDefaultPayload(defaultJwtPayload);
String userLoginToken = AuthJwtContext.me().generateTokenDefaultPayload(defaultJwtPayload);
// 9. 创建loginUser对象
LoginUser loginUser = new LoginUser(userValidateInfo.getUserId(), jwtToken);
LoginUser loginUser = new LoginUser(userValidateInfo.getUserId(), userLoginToken);
synchronized (loginRequest.getAccount().intern()) {
// 10. 缓存用户信息,创建会话
sessionManagerApi.createSession(jwtToken, loginUser);
sessionManagerApi.createSession(userLoginToken, loginUser);
// 11. 如果开启了单账号单端在线,则踢掉已经上线的该用户
if (AuthConfigExpander.getSingleAccountLoginFlag()) {
sessionManagerApi.removeSessionExcludeToken(jwtToken);
sessionManagerApi.removeSessionExcludeToken(userLoginToken);
}
}
// 演示环境,跳过记录日志
// 演示环境,跳过记录日志,非演示环境则记录登录日志
if (!DemoConfigExpander.getDemoEnvFlag()) {
// 12. 更新用户登录时间和ip
String ip = HttpServletUtil.getRequestClientIp(HttpServletUtil.getRequest());
@ -201,7 +172,67 @@ public class LoginService {
loginErrorCountCacheApi.remove(loginRequest.getAccount());
// 14. 组装返回结果
return new LoginResponse(loginUser.getUserId(), jwtToken);
return new LoginResponse(loginUser.getUserId(), userLoginToken);
}
/**
*
*
* @author fengshuonan
* @since 2023/6/20 23:15
*/
private void decryptRequestPassword(LoginRequest loginRequest) {
if (loginRequest.getPassword() != null && AuthConfigExpander.getPasswordRsaValidateFlag()) {
String decryptPassword = passwordTransferEncryptApi.decrypt(loginRequest.getPassword());
loginRequest.setPassword(decryptPassword);
}
}
/**
*
*
* @author fengshuonan
* @since 2023/6/20 23:13
*/
private void validateCaptcha(LoginRequest loginRequest) {
if (SecurityConfigExpander.getCaptchaOpen()) {
String verKey = loginRequest.getVerKey();
String verCode = loginRequest.getVerCode();
if (StrUtil.isEmpty(verKey) || StrUtil.isEmpty(verCode)) {
throw new AuthException(ValidatorExceptionEnum.CAPTCHA_EMPTY);
}
if (!captchaApi.validateCaptcha(verKey, verCode)) {
throw new AuthException(ValidatorExceptionEnum.CAPTCHA_ERROR);
}
}
// 2.1 验证拖拽验证码
if (SecurityConfigExpander.getDragCaptchaOpen()) {
String verKey = loginRequest.getVerKey();
String verXLocationValue = loginRequest.getVerCode();
if (StrUtil.isEmpty(verKey) || StrUtil.isEmpty(verXLocationValue)) {
throw new AuthException(ValidatorExceptionEnum.CAPTCHA_EMPTY);
}
if (!dragCaptchaApi.validateCaptcha(verKey, Convert.toInt(verXLocationValue))) {
throw new AuthException(ValidatorExceptionEnum.DRAG_CAPTCHA_ERROR);
}
}
}
/**
* 5
*
* @author fengshuonan
* @since 2023/6/20 23:13
*/
private Integer validatePasswordRetryTimes(LoginRequest loginRequest) {
Integer loginErrorCount = loginErrorCountCacheApi.get(loginRequest.getAccount());
if (loginErrorCount != null && loginErrorCount >= LoginCacheConstants.MAX_ERROR_LOGIN_COUNT) {
throw new AuthException(AuthExceptionEnum.LOGIN_LOCKED);
}
return loginErrorCount;
}
/**
@ -271,45 +302,47 @@ public class LoginService {
private void validateUserPassword(Boolean validatePassword, Integer loginErrorCount, LoginRequest loginRequest,
UserValidateDTO userValidateInfo) {
// 如果不需要校验登录密码,则直接返回
if (!validatePassword) {
return;
}
// 如果本次登录需要校验密码
if (validatePassword) {
Boolean checkResult = passwordStoredEncryptApi.checkPassword(loginRequest.getPassword(),
userValidateInfo.getUserPasswordHexed());
Boolean checkResult = passwordStoredEncryptApi.checkPassword(loginRequest.getPassword(), userValidateInfo.getUserPasswordHexed());
// 校验用户表密码是否正确,如果正确则直接返回
if (checkResult) {
return;
}
// 校验用户表密码是否正确,如果正确则直接返回
if (checkResult) {
return;
}
// 如果密码不正确则校验用户是否有临时秘钥
TempSecretApi tempSecretApi = null;
try {
tempSecretApi = SpringUtil.getBean(TempSecretApi.class);
if (tempSecretApi != null) {
String userTempSecretKey = tempSecretApi.getUserTempSecretKey(userValidateInfo.getUserId());
// 如果用户有临时秘钥,则校验秘钥是否正确
if (StrUtil.isNotBlank(userTempSecretKey)) {
Boolean checkTempKeyResult = passwordStoredEncryptApi.checkPassword(loginRequest.getPassword(), userTempSecretKey);
if (checkTempKeyResult) {
return;
}
// 如果密码不正确则校验用户是否有临时秘钥
TempSecretApi tempSecretApi = null;
try {
tempSecretApi = SpringUtil.getBean(TempSecretApi.class);
if (tempSecretApi != null) {
String userTempSecretKey = tempSecretApi.getUserTempSecretKey(userValidateInfo.getUserId());
// 如果用户有临时秘钥,则校验秘钥是否正确
if (StrUtil.isNotBlank(userTempSecretKey)) {
Boolean checkTempKeyResult = passwordStoredEncryptApi.checkPassword(loginRequest.getPassword(), userTempSecretKey);
if (checkTempKeyResult) {
return;
}
}
} catch (Exception ignored) {
}
// 临时秘钥校验完成,返回前端用户密码错误
if (loginErrorCount == null) {
loginErrorCount = 0;
}
// 演示环境不记录error次数
if (!DemoConfigExpander.getDemoEnvFlag()) {
loginErrorCountCacheApi.put(loginRequest.getAccount(), loginErrorCount + 1);
}
throw new AuthException(AuthExceptionEnum.USERNAME_PASSWORD_ERROR);
} catch (Exception ignored) {
}
// 临时秘钥校验完成,返回前端用户密码错误
if (loginErrorCount == null) {
loginErrorCount = 0;
}
// 演示环境不记录error次数
if (!DemoConfigExpander.getDemoEnvFlag()) {
loginErrorCountCacheApi.put(loginRequest.getAccount(), loginErrorCount + 1);
}
throw new AuthException(AuthExceptionEnum.USERNAME_PASSWORD_ERROR);
}
}