Shiro登录认证逻辑----shiro免登录

要解决的业务问题

    第三方平台跳转至集成了shiro的平台时,仅通过用户名就可以实现登录集成了shiro的平台,可以理解为免登录Shiro系统。

因此要实现这样的操作,必须了解shiro的登录认证流程是如何的。

ps:以下展示的代码均为测试例子,大家可根据自己项目找到对应的逻辑处理的地方。前7步为逻辑分析,若是想看最终修改地方,则直接查看第8步即可

shiro的认证流程

1、生成token

将登陆的用户名密码等信息封装成一个UsernamePasswordToken实体类得到token信息。(此处可以通过集成org.apache.shiro.authc.UsernamePasswordToken类封装一些额外信息,但是最重要的就是用户名和密码。)

 UsernamePasswordToken token = new  UsernamePasswordToken(name, password);

2、调用登录认证

通过得到的token信息执行subject.login(token)方法,这个方法可能是代码中自己写的代码进行调用,也有可能是通过Shiro实现的fitler自动调用。

subject.login(token);

3、生成info

调用login方法后,会执行AuthorizingRealm的doGetAuthenticationInfo方法,这个方法需要我们在项目中通过集成AuthorizingRealm类重写doGetAuthenticationInfo。(这里我们从数据库用户的信息,然后返回一个SimpleAuthenticationInfo对象,注意,这里很重要,这里很重要,这里很重要)

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // TODO Auto-generated method stub
        System.out.println("执行认证逻辑");
        //1、从数据库得到用户名和密码
        //2、判断用户名
        UsernamePasswordToken token2 = (UsernamePasswordToken) token;
        User user = new User(token2.getUsername());
        user = userService.selectUser(user);
        if (user==null) {
            return null; //shiro底层帮助抛出异常
        }
        
        return new SimpleAuthenticationInfo(user,user.getPassword(),"");
    }

4、用户名认证

第一步中,我们得到了封装了前端输入的用户信息的token,第三步中,我们得到了从数据库中查询得到了真实的用户信息。如果第三步没有从数据库中查询到用户,说明用户不存在,直接终止验证流程即可。如果查询得到了用户,则接下来就是进行密码的检验即可。

5、密码认证

密码的检验最后会由HashedCredentialsMatcher的doCredentialsMatch方法进行执行,如下

具体如何调用到这里,可以参考这篇博客:https://blog.csdn.net/caoyang0105/article/details/82769293

6、密码加密逻辑

由于数据库中保存的密码是经过shriro加密处理且不可逆的,因此前端传输过来的密码在与数据库对比前同样需要经过加密,具体的加密流程参考第六步的doCredentialsMatch方法为根方法,可逐个分析源码,我这里直接说结论,在不加盐的情况下,前端传过来的密码将会被shiro采用SHA-1加密方法,加密1024次得到新的密码,如下:

//需要导入的包 
import org.apache.shiro.crypto.hash.SimpleHash; 
new SimpleHash("SHA-1","",null,1024).toHex();

参数一:为加密的算法;参数为:为要加密的字符串(即前端传输过来的密码);参数三:盐;参数四:加密的次数。

7、默认密码

由第七步可知,如果前端传输的密码固定为""时,那么经过shrio转化后的密码为

b8f31e91d52285a5d39a9a53da819e35fb04edc6,

因此我们如果要实现用户的免密登录,则默认数据库的密码为b8f31e91d52285a5d39a9a53da819e35fb04edc6即可。

8、修改登录认证逻辑

因此我们在第三步生成数据库的SimpleAuthenticationInfo对象时,如果判断是免密码登录,则返回对象如下。

即在我们项目中通过集成AuthorizingRealm类重写doGetAuthenticationInfo的方法中,返回对象做如下改变,如果你前端的密码固定是""的话,此处的秘钥是确定的,如果不是,则参考第七步的代码生成秘钥

if (token.isMis()){
   //这是免密登录的认证逻辑
     return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()),
		"b8f31e91d52285a5d39a9a53da819e35fb04edc6",  getName());
}else {
//这是原先的登录
    return new SimpleAuthenticationInfo(new Principal(user, token.isMobileLogin()),
		user.getPassword().substring(16), ByteSource.Util.bytes(salt), getName());
}

以上是基于免密登录的需求修改的代码,自己调试得到的shiro认证逻辑,可能也不十分准确,尤其是最后的密码再次加密认证地方,源码中调用多个方法,精力有限,没有仔细深究。若是想要简单处理,就请参考第8步的代码,不要进行加盐处理。如果大家比较了解最后的密码加盐加密逻辑,还请多多指教。

 

 

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值