【auth】更新auth模块的登录流程,抽象两个密码相关的接口

pull/3/head
fengshuonan 2020-12-21 21:22:02 +08:00
parent 1754c21bc8
commit a5fc70e51b
6 changed files with 185 additions and 15 deletions

View File

@ -0,0 +1,31 @@
package cn.stylefeng.roses.kernel.auth.api.password;
/**
* api
*
* @author fengshuonan
* @date 2020/12/21 16:50
*/
public interface PasswordStoredEncryptApi {
/**
*
*
* @param originPassword
* @return
* @author fengshuonan
* @date 2020/12/21 16:52
*/
String encrypt(String originPassword);
/**
*
*
* @param encryptBefore
* @return true-false-
* @author fengshuonan
* @date 2020/12/21 17:09
*/
Boolean checkPassword(String encryptBefore, String encryptAfter);
}

View File

@ -0,0 +1,31 @@
package cn.stylefeng.roses.kernel.auth.api.password;
/**
* api
*
* @author fengshuonan
* @date 2020/12/21 16:50
*/
public interface PasswordTransferEncryptApi {
/**
*
*
* @param originPassword
* @return
* @author fengshuonan
* @date 2020/12/21 16:52
*/
String encrypt(String originPassword);
/**
*
*
* @param encryptedPassword
* @return
* @author fengshuonan
* @date 2020/12/21 16:51
*/
String decrypt(String encryptedPassword);
}

View File

@ -1,14 +1,14 @@
package cn.stylefeng.roses.kernel.auth.auth;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi;
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordStoredEncryptApi;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordTransferEncryptApi;
import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginRequest;
import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse;
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
@ -16,7 +16,6 @@ import cn.stylefeng.roses.kernel.jwt.api.context.JwtContext;
import cn.stylefeng.roses.kernel.jwt.api.exception.JwtException;
import cn.stylefeng.roses.kernel.jwt.api.pojo.payload.DefaultJwtPayload;
import cn.stylefeng.roses.kernel.rule.util.HttpServletUtil;
import cn.stylefeng.roses.kernel.system.ResourceServiceApi;
import cn.stylefeng.roses.kernel.system.UserServiceApi;
import cn.stylefeng.roses.kernel.system.enums.UserStatusEnum;
import cn.stylefeng.roses.kernel.system.pojo.user.UserLoginInfoDTO;
@ -46,7 +45,10 @@ public class AuthServiceImpl implements AuthServiceApi {
private SessionManagerApi sessionManagerApi;
@Resource
private ResourceServiceApi resourceServiceApi;
private PasswordStoredEncryptApi passwordStoredEncryptApi;
@Resource
private PasswordTransferEncryptApi passwordTransferEncryptApi;
@Override
public LoginResponse login(LoginRequest loginRequest) {
@ -138,46 +140,49 @@ public class AuthServiceImpl implements AuthServiceApi {
}
}
// 2.获取用户密码的加密值和用户的状态
// 2. 解密密码的密文
String decryptPassword = passwordTransferEncryptApi.decrypt(loginRequest.getPassword());
// 3. 获取用户密码的加密值和用户的状态
UserLoginInfoDTO userValidateInfo = userServiceApi.getUserLoginInfo(loginRequest.getAccount());
// 3.校验用户密码是否正确(BCrypt算法)
// 4. 校验用户密码是否正确(BCrypt算法)
if (validatePassword) {
if (ObjectUtil.isEmpty(userValidateInfo.getUserPasswordHexed()) || !BCrypt.checkpw(loginRequest.getPassword(), userValidateInfo.getUserPasswordHexed())) {
Boolean checkResult = passwordStoredEncryptApi.checkPassword(decryptPassword, userValidateInfo.getUserPasswordHexed());
if (!checkResult) {
throw new AuthException(AuthExceptionEnum.USERNAME_PASSWORD_ERROR);
}
}
// 4.校验用户是否异常(不是正常状态)
// 5. 校验用户是否异常(不是正常状态)
if (!UserStatusEnum.ENABLE.getCode().equals(userValidateInfo.getUserStatus())) {
String userTip = StrUtil.format(AuthExceptionEnum.USER_STATUS_ERROR.getErrorCode(), UserStatusEnum.getCodeMessage(userValidateInfo.getUserStatus()));
throw new AuthException(AuthExceptionEnum.USER_STATUS_ERROR.getErrorCode(), userTip);
}
// 5.获取LoginUser用于用户的缓存
// 6. 获取LoginUser用于用户的缓存
LoginUser loginUser = userValidateInfo.getLoginUser();
// 6.生成用户的token
// 7. 生成用户的token
DefaultJwtPayload defaultJwtPayload = new DefaultJwtPayload(loginUser.getUserId(), loginUser.getAccount(), loginRequest.getRememberMe());
String jwtToken = JwtContext.me().generateTokenDefaultPayload(defaultJwtPayload);
synchronized (SESSION_OPERATE_LOCK) {
// 7.缓存用户信息,创建会话
// 8. 缓存用户信息,创建会话
sessionManagerApi.createSession(jwtToken, loginUser);
// 8.如果开启了单账号单端在线,则踢掉已经上线的该用户
// 9. 如果开启了单账号单端在线,则踢掉已经上线的该用户
if (AuthConfigExpander.getSingleAccountLoginFlag()) {
sessionManagerApi.removeSessionExcludeToken(jwtToken);
}
}
// 9.更新用户登录时间和ip
// 10. 更新用户登录时间和ip
String ip = HttpServletUtil.getRequestClientIp(HttpServletUtil.getRequest());
userServiceApi.updateUserLoginInfo(loginUser.getUserId(), new Date(), ip);
// 10.组装返回结果
// 11. 组装返回结果
return new LoginResponse(loginUser, jwtToken);
}

View File

@ -0,0 +1,29 @@
package cn.stylefeng.roses.kernel.auth.password;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordStoredEncryptApi;
/**
* BCrypt
*
* @author fengshuonan
* @date 2020/12/21 17:02
*/
public class BcryptPasswordStoredEncrypt implements PasswordStoredEncryptApi {
@Override
public String encrypt(String originPassword) {
if (StrUtil.isBlank(originPassword)) {
return null;
}
return BCrypt.hashpw(originPassword, BCrypt.gensalt());
}
@Override
public Boolean checkPassword(String encryptBefore, String encryptAfter) {
return BCrypt.checkpw(encryptBefore, encryptAfter);
}
}

View File

@ -0,0 +1,46 @@
package cn.stylefeng.roses.kernel.auth.password;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordTransferEncryptApi;
/**
* RSA
*
* @author fengshuonan
* @date 2020/12/21 17:02
*/
public class RsaPasswordTransferEncrypt implements PasswordTransferEncryptApi {
/**
* rsa
*/
private final String publicKey;
/**
* RSA
*/
private final String privateKey;
public RsaPasswordTransferEncrypt(String publicKey, String privateKey) {
this.publicKey = publicKey;
this.privateKey = privateKey;
}
@Override
public String encrypt(String originPassword) {
if (StrUtil.isBlank(originPassword)) {
return null;
}
RSA rsa = new RSA(privateKey, publicKey);
return rsa.encryptBase64(originPassword, KeyType.PublicKey);
}
@Override
public String decrypt(String encryptedPassword) {
RSA rsa = new RSA(privateKey, publicKey);
return rsa.decryptStr(encryptedPassword, KeyType.PrivateKey);
}
}

View File

@ -3,6 +3,10 @@ package cn.stylefeng.roses.kernel.auth.starter;
import cn.hutool.cache.CacheUtil;
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordStoredEncryptApi;
import cn.stylefeng.roses.kernel.auth.api.password.PasswordTransferEncryptApi;
import cn.stylefeng.roses.kernel.auth.password.BcryptPasswordStoredEncrypt;
import cn.stylefeng.roses.kernel.auth.password.RsaPasswordTransferEncrypt;
import cn.stylefeng.roses.kernel.auth.session.MemoryCacheSessionManager;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
@ -17,6 +21,30 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class GunsAuthAutoConfiguration {
/**
* Bcrypt
*
* @author fengshuonan
* @date 2020/12/21 17:45
*/
@Bean
public PasswordStoredEncryptApi passwordStoredEncryptApi() {
return new BcryptPasswordStoredEncrypt();
}
/**
* Bcrypt
*
* @author fengshuonan
* @date 2020/12/21 17:45
*/
@Bean
public PasswordTransferEncryptApi passwordTransferEncryptApi() {
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCytSVn3ff7eBJckAFYwgJjqE9Zq2uAL4g+hkfQqGALdT8NJKALFxNzeSD/xTBLAJrtALWbN1dvyktoVNPAuuzCZO1BxYZNaAU3IKFaj73OSPzca5SGY0ibMw0KvEPkC3sZQeqBqx+VqYAqan90BeG/r9p36Eb0wrshj5XmsFeo6QIDAQAB";
String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALK1JWfd9/t4ElyQAVjCAmOoT1mra4AviD6GR9CoYAt1Pw0koAsXE3N5IP/FMEsAmu0AtZs3V2/KS2hU08C67MJk7UHFhk1oBTcgoVqPvc5I/NxrlIZjSJszDQq8Q+QLexlB6oGrH5WpgCpqf3QF4b+v2nfoRvTCuyGPleawV6jpAgMBAAECgYBS9fUfetQcUWl0vwVhBu/FA+WSYxnMsEQ3gm7kVsX/i7Zxi4cgnt3QxXKkSg5ZQzaov6OPIuncY7UOAhMrbZtq/Hh8atdTVC/Ng/X9Bomodplq/+KTe/vIfWW5rlQAnMNFVaidxhCVRlRHNusapmj2vYwsiyI9kXUJNHryxtFC4QJBANtQuh3dtd79t3MVaC3TUD/EsGBe9TB3Eykbgv0muannC2Oq8Ci4vIp0NSA+FNCoB8ctgfKJUdBS8RLVnYyu3RcCQQDQmY+AuAXEpO9SgcYeRnQSOU2OSuC1wLt1MRVpPTdvE3bfRnkVxMrK0n3YilQWkQzfkERSG4kRFLIw605xPWn/AkEAiw3vQ9p8Yyu5MiXDjTKrchMyxZfPnHATXQANmJcCJ0DQDtymMxuWp66wtIXIStgPPnGTMAVzM0Qzh/6bS0Tf9wJAWj+1yFjVlghNyoJ+9qZAnYnRNhjLM5dZAxDjVI65pwLi0SKqTHLB0hJThBYE32aODUNba7KiEJPFrEiBvZh2fQJARbboHuHT0PqD1UTJGgodHlaw48kreBU+twext/9/jIqvwmFF88BmQgssHGW/tn4E6Qy3+rCCNWreEReY0gATYw==";
return new RsaPasswordTransferEncrypt(publicKey, privateKey);
}
/**
* session便
* <p>