Shiro 实现免密码登录策略 微信扫码登录 第三方登录问题
Shiro 实现免密码登录策略 微信扫码登录 第三方登录问题
一、情景描述
在做微信扫码登录时候,流程是,根据获取的 微信unionId,查找到用户,且用户状态为可用时,即可实现登录;由于使用shiro为安全控制中心,查询出来的用户密码为加密的,且不可逆;所以要做一个Shiro免密登录策略。
二、代码实现
1、Shiro 登录流程
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken passwordToken = new UsernamePasswordToken();
passwordToken.setUsername("");
passwordToken.setPassword("");
subject.login(passwordToken);
2、创建 UsernamePasswordToken 继承 org.apache.shiro.authc.UsernamePasswordToken 增加属性 unpass ,设置为是否免密码登录
public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {
private static final long serialVersionUID = 1L;
private String captcha;
private boolean mobileLogin;
private String requestFlag;
private boolean unpass=false; // 是否免密码登录
// ignore gettet / setter
}
3、创建 WechatHashedCredentialsMatcher 继承 org.apache.shiro.authc.credential.HashedCredentialsMatcher ,重写 doCredentialsMatch 方法
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
/**
* description: 微信扫码登录的--- 免密码登录
* @version v1.0
* @author w
* @date 2020年12月2日下午5:09:15
**/
public class WechatHashedCredentialsMatcher extends HashedCredentialsMatcher {
public WechatHashedCredentialsMatcher() {
super();
}
public WechatHashedCredentialsMatcher(String hashAlgorithmName) {
super(hashAlgorithmName);
}
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken)token;
if(usernamePasswordToken.getUnpass()) {
// 免密码登录
return true;
}
return super.doCredentialsMatch(token, info);
}
}
4、创建 SystemAuthorizingRealm 类继承 org.apache.shiro.realm.AuthorizingRealm , 增加 initCredentialsMatcher 方法 ,重写配置 matcher
@Service
public class SystemAuthorizingRealm extends AuthorizingRealm {
/**
* 设定密码校验的Hash算法与迭代次数
*/
@PostConstruct
public void initCredentialsMatcher() {
// HashedCredentialsMatcher matcher = new HashedCredentialsMatcher(SystemService.HASH_ALGORITHM);
WechatHashedCredentialsMatcher matcher = new WechatHashedCredentialsMatcher(SystemService.HASH_ALGORITHM);
matcher.setHashIterations(SystemService.HASH_INTERATIONS);
setCredentialsMatcher(matcher);
}
}
5、免密登录 , 设置 unpass = true
usernamePasswordToken.setUnpass(true); // 免密码登录验证
三、总结
1、要理解Shiro的执行流程,获取 subject , 创建Token , 提交给 subject.login()方法进行登录认证。
2、本文中的Shiro xml配置部分略,具体的可以参考Jeesite项目。
参考资料: @PostConstruct注解