mirror of https://gitee.com/stylefeng/roses
【7.6.0】【sys】【permission】从新整理登录逻辑,封装其他的登录过程方法
parent
bb2af77c1c
commit
d6c53289ca
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue