• shiro实现基于机构加username的验证以及rememberMe


    一、Shiro的一些经验与rememberMe实现原理

    Shiro的登录(Authorization)和验权(Authentication)。默认都是依据usernameUserName来做验证和授权的。

    登录用的是UsernamePasswordTokenusernamepassword对,验权用的是PrincipalCollection身份集合(默认是username和Realm名称),有一个统一的入口就是Subject(表示一个人或其它什么的要登录进来的对象)。

    关系是登陆时subject.login(token),然后登陆成功了subject里就有了subject.getPrincipal()。拿到此用户的username了。

    不论什么地方都能够直接使用工具方法拿到subject: Subject subject = SecurityUtils.getSubject();

    能够通过subject.isAuthenticated()为true能够推断当前用户已经登录过了;此时能够直接通过subject.getSession()去获取我们放入session的信息了。

    假设subject.isRemembered()为true,则登录后,Shiro会将principal对象序列化为Byte[],再base64。加入到client的cookie里。默认过期时间为1年。用户下次訪问登录时,直接将cookie里的rememberMe数据拿出来,传到server端。Shiro就可以反序列化。还原出来原用户的身份信息。在浏览器的设置里能够查看这个base64的cookie值:


    二、实现机构加username的验证

    Shiro默认这一套机制都是依照username来做的。如今我们的系统里存在多个机构,不同机构能够有同样的username,那么我们怎么来实现基于机构+username的验证呢?

    两个思路能够解决问题:

    1. 把机构+username拼接到一起来作为UsernamePasswordToken里的UserName
    2. 扩展UsernamePasswordToken与Principal的实现

    这两个思路各有利弊。第一个比較简单粗暴,第二个比較规范通用。

    因为我们是先做好基于UserName的实现以后再修改代码实现把机构扩展进去,所以第一种方式修改最小:

    1. 系统登录页面表单加上机构类型与机构名称选择,
    2. 后台把机构类型+机构id+username拼接成admin:1:3的形式,作为UsernamePasswordToken的Username,
    3. Realm实现使用自己定义的或者我写的这个ServiceRealm(仅仅有3个类)SQL改成依据机构id+username获取password
    4. 然后使用subject.login登录就可以实现基于机构+用户的验证。
    5. 登录后查看subject.getPrincipal已经是admin:1:3的形式了。

    另外一种以后再分析。

    三、如上改动UserName格式+rememberMe造成的一个小问题

    假设浏览器之前使用了rememberMe选型以后安装上面的方式改动了UserName格式(比方admin:1:3)。则由于其cookie有效期为1年。每次再自己主动登录诗、从client提交上来的序列化的cookie数据里都是旧的数据。还原出来的principal还是老的格式(比方admin),造成了数据不一致,程序运行出错。

    解决的方法:清空浏览器的cookie,或者直接强制client使用一次login登录就可以。


  • 相关阅读:
    i春秋xss平台
    i春秋exec
    bugku 你必须让他停下
    bugku 域名解析
    bugku web3
    bugku 矛盾
    (转)ubuntu下怎么放wifi热点给andriod设备
    (转)如何在 ubuntu 下使用 iNode 客户端
    博客更新啦!!
    HDU 5351 MZL's Border (多校联合第5场1009)
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7344273.html
Copyright © 2020-2023  润新知