15 changed files with 68 additions and 559 deletions
@ -1,68 +0,0 @@ |
|||
package com.dreamchaser.depository_manage.security.bean; |
|||
|
|||
import com.dreamchaser.depository_manage.entity.User; |
|||
import com.dreamchaser.depository_manage.exception.MyException; |
|||
import com.dreamchaser.depository_manage.security.pool.AuthenticationTokenPool; |
|||
import com.dreamchaser.depository_manage.service.UserService; |
|||
import com.dreamchaser.depository_manage.utils.Md5; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
/** |
|||
* 内置多种登录方式,和shiro中的realm类似 |
|||
*/ |
|||
@Component |
|||
public class LoginRealms { |
|||
@Autowired |
|||
private UserService userService; |
|||
|
|||
/** |
|||
* 认证,如果认证成功则返回凭证,否则返回null |
|||
* @param userToken 未认证的令牌 |
|||
* @return 如果认证成功则返回凭证,否则返回null |
|||
*/ |
|||
public String authenticate(UserToken userToken){ |
|||
if (userToken.getCredentials()!=null){ |
|||
//对密码加密
|
|||
userToken.setCredentials(Md5.crypt(userToken.getCredentials())); |
|||
} |
|||
if (userToken.getLoginType().equals(LoginType.EMAIl_PASSWORD)){ |
|||
return handle(userToken,emailLogin(userToken)); |
|||
} |
|||
//else if (其他登录方式...)
|
|||
//如果无匹配的认证方式则视为验证失败
|
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 邮箱登录方式 |
|||
* @param userToken 令牌 |
|||
* @return 认证成功返回SimpleUser |
|||
*/ |
|||
private User emailLogin(UserToken userToken){ |
|||
return userService.findUserById(userToken.getPrincipal()); |
|||
} |
|||
|
|||
/** |
|||
* 根据传入的user是否为null(是否认证通过)来对令牌做剩下的操作(将user刻入令牌,并将该令牌放入令牌池中) |
|||
* @param userToken 经过验证后的令牌 |
|||
* @return token 根据令牌生成的凭证 ,如果认证未成功则返回null |
|||
*/ |
|||
private String handle(UserToken userToken,User user){ |
|||
if (user==null){ |
|||
//说明账户不存在
|
|||
throw new MyException(409,"该用户不存在,请注册后再登录!"); |
|||
} |
|||
//判断密码是否正确
|
|||
if (user.getPwd().equals(userToken.getCredentials())){ |
|||
//将UserP信息刻入令牌
|
|||
userToken.setUser(userService.singlePack(user)); |
|||
//获取token凭证
|
|||
String token=Md5.crypt(userToken.getPrincipal()+userToken.getInstant()); |
|||
//将令牌放入认证令牌池
|
|||
// AuthenticationTokenPool.addToken(token,userToken);
|
|||
return token; |
|||
} |
|||
return null; |
|||
} |
|||
} |
|||
@ -1,66 +0,0 @@ |
|||
package com.dreamchaser.depository_manage.security.bean; |
|||
|
|||
/** |
|||
* 登录方式枚举类 |
|||
* @author 金昊霖 |
|||
*/ |
|||
|
|||
public enum LoginType { |
|||
/** |
|||
* 通用 |
|||
*/ |
|||
COMMON("common_realm"), |
|||
/** |
|||
* 用户密码登录 |
|||
*/ |
|||
EMAIl_PASSWORD("user_password_realm"), |
|||
/** |
|||
* 手机验证码登录 |
|||
*/ |
|||
USER_PHONE("user_phone_realm"), |
|||
/** |
|||
* 第三方登录(微信登录) |
|||
*/ |
|||
WECHAT_LOGIN("wechat_login_realm"), |
|||
/** |
|||
* 第三方登录(qq登录) |
|||
*/ |
|||
QQ_LOGIN("qq_login_realm"); |
|||
|
|||
|
|||
private String type; |
|||
|
|||
LoginType(String type) { |
|||
this.type = type; |
|||
} |
|||
|
|||
public String getType() { |
|||
return type; |
|||
} |
|||
|
|||
/** |
|||
* 根据简单的字符串返回对应的LoginType |
|||
* @param s 简单的字符串 |
|||
* @return 对应的LoginType |
|||
*/ |
|||
public static LoginType getType(String s){ |
|||
switch (s) { |
|||
case "email": |
|||
return EMAIl_PASSWORD; |
|||
case "qq": |
|||
return QQ_LOGIN; |
|||
case "wechat": |
|||
return WECHAT_LOGIN; |
|||
case "phone": |
|||
return USER_PHONE; |
|||
default: |
|||
return null; |
|||
} |
|||
|
|||
} |
|||
|
|||
@Override |
|||
public String toString() { |
|||
return this.type; |
|||
} |
|||
} |
|||
@ -1,88 +0,0 @@ |
|||
package com.dreamchaser.depository_manage.security.bean; |
|||
|
|||
|
|||
import com.dreamchaser.depository_manage.entity.User; |
|||
import com.dreamchaser.depository_manage.pojo.UserP; |
|||
import lombok.Data; |
|||
|
|||
import java.time.Instant; |
|||
|
|||
|
|||
/** |
|||
* 登录令牌,默认有效期为7天 |
|||
* @author 金昊霖 |
|||
*/ |
|||
@Data |
|||
public class UserToken{ |
|||
|
|||
final long DEFAULT_TERM=60*60*24*7; |
|||
/** |
|||
* 登录方式 |
|||
*/ |
|||
private LoginType loginType; |
|||
/** |
|||
* 微信、qq的code,邮箱,或者用户名之类的 |
|||
*/ |
|||
private String principal; |
|||
|
|||
/** |
|||
* 相当于密码(一般是加密过的) |
|||
*/ |
|||
private String credentials; |
|||
|
|||
/** |
|||
* 放入的时间 |
|||
*/ |
|||
private Instant instant; |
|||
|
|||
/** |
|||
* 有效期(单位:秒) |
|||
*/ |
|||
private long term; |
|||
|
|||
/** |
|||
* 可以放一些不敏感的信息,以便下次访问时可以直接取出,如果user属性太多可以另外写个类,比如SimpleUser, |
|||
* 存放一些经常需要用到的信息。 |
|||
*/ |
|||
private UserP User; |
|||
|
|||
/** |
|||
* 根据时间判断是否有效 |
|||
* @return 有效则返回true,否则返回false |
|||
*/ |
|||
public boolean isValid(){ |
|||
return Instant.now().getEpochSecond()-instant.getEpochSecond()<=term; |
|||
} |
|||
|
|||
public UserToken(LoginType loginType, String principal, String credentials, Instant instant, long term, UserP user) { |
|||
this.loginType = loginType; |
|||
this.principal = principal; |
|||
this.credentials = credentials; |
|||
this.instant = instant; |
|||
this.term = term; |
|||
this.User = user; |
|||
} |
|||
|
|||
public UserToken(LoginType loginType, String principal, String credentials, Instant instant, long term) { |
|||
this.loginType = loginType; |
|||
this.principal = principal; |
|||
this.credentials = credentials; |
|||
this.instant = instant; |
|||
this.term = term; |
|||
} |
|||
|
|||
public UserToken(LoginType loginType, String principal, String credentials) { |
|||
this.loginType = loginType; |
|||
this.principal = principal; |
|||
this.credentials = credentials; |
|||
this.instant = Instant.now(); |
|||
this.term=DEFAULT_TERM; |
|||
} |
|||
|
|||
public UserToken(LoginType loginType, String principal) { |
|||
this.loginType = loginType; |
|||
this.principal = principal; |
|||
this.instant=Instant.now(); |
|||
this.term=DEFAULT_TERM; |
|||
} |
|||
} |
|||
@ -1,74 +0,0 @@ |
|||
package com.dreamchaser.depository_manage.security.bean; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.time.Instant; |
|||
import java.util.Random; |
|||
|
|||
/** |
|||
* 验证码,默认有效期为五分钟 |
|||
* @author 金昊霖 |
|||
*/ |
|||
@Data |
|||
public class VerificationCode { |
|||
/** |
|||
* 默认持续时间 |
|||
*/ |
|||
private final long DEFAULT_TERM=60*5; |
|||
/** |
|||
* 验证码 |
|||
*/ |
|||
private String code; |
|||
/** |
|||
* 创建时刻 |
|||
*/ |
|||
private Instant instant; |
|||
/** |
|||
* 有效期 |
|||
*/ |
|||
private long term; |
|||
|
|||
/** |
|||
* 根据时间判断是否有效 |
|||
* @return boolean值 |
|||
*/ |
|||
public boolean isValid(){ |
|||
return Instant.now().getEpochSecond()-instant.getEpochSecond()<=term; |
|||
} |
|||
|
|||
public VerificationCode(Instant instant, long term) { |
|||
//生成随机验证码code
|
|||
generateCode(); |
|||
this.instant = instant; |
|||
this.term = term; |
|||
} |
|||
|
|||
|
|||
public VerificationCode(Instant instant) { |
|||
//生成随机验证码code
|
|||
generateCode(); |
|||
this.instant = instant; |
|||
this.term=DEFAULT_TERM; |
|||
} |
|||
|
|||
public VerificationCode() { |
|||
//生成随机验证码code
|
|||
generateCode(); |
|||
this.instant=Instant.now(); |
|||
this.term=DEFAULT_TERM; |
|||
} |
|||
|
|||
private void generateCode(){ |
|||
StringBuilder codeNum = new StringBuilder(); |
|||
int [] numbers = {0,1,2,3,4,5,6,7,8,9}; |
|||
Random random = new Random(); |
|||
for (int i = 0; i < 5; i++) { |
|||
//目的是产生足够随机的数,避免产生的数字重复率高的问题
|
|||
int next = random.nextInt(10000); |
|||
codeNum.append(numbers[next % 10]); |
|||
} |
|||
this.code= codeNum.toString(); |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -1,54 +0,0 @@ |
|||
package com.dreamchaser.depository_manage.security.pool; |
|||
|
|||
import com.dreamchaser.depository_manage.security.bean.VerificationCode; |
|||
|
|||
import java.util.Map; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
|
|||
/** |
|||
* 验证码等待池 |
|||
* @author 金昊霖 |
|||
*/ |
|||
public class VerificationCodePool { |
|||
private static Map<String, VerificationCode> pool=new ConcurrentHashMap<>(10); |
|||
|
|||
/** |
|||
* 增加一条验证码 |
|||
* @param principal 主要内容,如邮箱,电话号码等 |
|||
* @param verificationCode 验证码 |
|||
*/ |
|||
public static void addCode(String principal,VerificationCode verificationCode){ |
|||
pool.put(principal, verificationCode); |
|||
} |
|||
|
|||
/** |
|||
* 根据principal主要信息获取未过期的验证码,如果没有未过期的令牌则返回null |
|||
* @param principal 主要内容,如邮箱,电话号码等 |
|||
* @return verificationCode 未过期的验证码或者null |
|||
*/ |
|||
public static VerificationCode getCode(String principal){ |
|||
VerificationCode verificationCode=pool.get(principal); |
|||
|
|||
//如果没有相应验证码则直接返回null
|
|||
if (verificationCode==null){ |
|||
return null; |
|||
} |
|||
|
|||
//判断令牌是否过期
|
|||
if (verificationCode.isValid()){ |
|||
return verificationCode; |
|||
}else{ |
|||
//清除过期验证码
|
|||
pool.remove(principal); |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 根据主要信息principal删除对应的验证码 |
|||
* @param principal 主要信息 |
|||
*/ |
|||
public static void removeCode(String principal){ |
|||
pool.remove(principal); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue