文档章节

shiro 多节点

110hxl
 110hxl
发布于 2015/05/06 16:15
字数 986
阅读 49
收藏 0

首先,在系统中shiro提供交互的对象是Subject;所以先弄明白subject的生成和保存;

知道shiro是以filter的方式整合到系统中的,那么就查看shiro的filter

主要看AbstractShiroFilter的doFilterInternal方法就行了,里面的一部分主要代码

final Subject subject = createSubject(request, response);//这里创建或者从缓存里取subject

//noinspection unchecked
subject.execute(new Callable() {
     public Object call() throws Exception {
          updateSessionLastAccessTime(request, response);//这里更新或者保存session
          executeChain(request, response, chain);
          return null;
         }
});

所以得知每次被拦截都会生成或者提取subject;

createSubject(....)的主要调用代码在DefaultSecurityManager类的createSubject(SubjectContext subjectContext)方法中;

/**
     * This implementation functions as follows:
     * <p/>
     * <ol>
     * <li>Ensures the {@code SubjectContext} is as populated as it can be, using heuristics to acquire
     * data that may not have already been available to it (such as a referenced session or remembered principals).</li>
     * <li>Calls {@link #doCreateSubject(org.apache.shiro.subject.SubjectContext)} to actually perform the
     * {@code Subject} instance creation.</li>
     * <li>calls {@link #save(org.apache.shiro.subject.Subject) save(subject)} to ensure the constructed
     * {@code Subject}'s state is accessible for future requests/invocations if necessary.</li>
     * <li>returns the constructed {@code Subject} instance.</li>
     * </ol>
     *
     * @param subjectContext any data needed to direct how the Subject should be constructed.
     * @return the {@code Subject} instance reflecting the specified contextual data.
     * @see #ensureSecurityManager(org.apache.shiro.subject.SubjectContext)
     * @see #resolveSession(org.apache.shiro.subject.SubjectContext)
     * @see #resolvePrincipals(org.apache.shiro.subject.SubjectContext)
     * @see #doCreateSubject(org.apache.shiro.subject.SubjectContext)
     * @see #save(org.apache.shiro.subject.Subject)
     * @since 1.0
     */
    public Subject createSubject(SubjectContext subjectContext) {
        //create a copy so we don't modify the argument's backing map:
        SubjectContext context = copy(subjectContext);//上下文环境?其实就几个属性

        //ensure that the context has a SecurityManager instance, and if not, add one:
        context = ensureSecurityManager(context);

        //Resolve an associated Session (usually based on a referenced session ID), and place it in the context before
        //sending to the SubjectFactory.  The SubjectFactory should not need to know how to acquire sessions as the
        //process is often environment specific - better to shield the SF from these details:
        context = resolveSession(context);//关联session的方法,如果配置session则会取缓存中的session

        //Similarly, the SubjectFactory should not require any concept of RememberMe - translate that here first
        //if possible before handing off to the SubjectFactory:
        context = resolvePrincipals(context);//关联授权信息

        Subject subject = doCreateSubject(context);

        //save this subject for future reference if necessary:
        //(this is needed here in case rememberMe principals were resolved and they need to be stored in the
        //session, so we don't constantly rehydrate the rememberMe PrincipalCollection on every operation).
        //Added in 1.2:
        save(subject);//保存subject,subject是保存为线程相关的,其实是线程继承相关,所以也就跟容器相关;而授权信息、认证信息也保存在session里

        return subject;
    }

shiro提供获取subject的途径是SecurityUtils.getSubject(),就会返回线程相关的subject。保存的容器被定义为

private static final ThreadLocal<Map<Object, Object>> resources = new InheritableThreadLocalMap<Map<Object, Object>>();

-----------------------------------------------以下是吐槽-----------------------------------------------------

项目要改为支持多节点的部署方式,觉得应该把shiro的session缓存在redis中就行了,于是用了http://www.oschina.net/p/shiro-redis(其实一直在用的)。把项目部署到两个tomcat后,一直登陆验证模块就失效了,不是说不走shiro拦截了,这个肯定是经过的。只是登陆的流程中两台tomcat都有接受到请求。调试的结果发现在一台tomcat上成功登陆的信息,在另一个tomcat上获取为空.....各种不明白,就这样花了我两天时间,,,,,,,没搞定。。。嗯,还好有高手指点。问题是shiro-redis的提供了本地缓存。。。。。。。。。。。无语,,,无语中把shiro-redis的sessionDAO自己实现一个,自己实现的是直接从redis中获取shiro的信息,不用什么本地缓存。

------------------------------------------以下是待解决的问题--------------------------------------------------------

在开启session中发现,认证信息也是可以缓存的,就是AuthenticationInfo也是可以放入缓存中的,不必每次登陆都从数据库中获取数据进行认证。调试得知缓存认证是根据密码匹配的;但是如何刷新还没查看

------------------------------------------------05.07---------------------------------------------

以下来说明上面待解决的问题;

如果开启了认证和授权的缓存.

AuthenticatingRealm.cacheAuthenticationInfoIfPossible方法缓存认证信息;

AuthorizingRealm.getAuthorizationInfo方法缓存和获取授权信息;

注意认证或是授权缓存的key值是否有对象的hash值,如果有每次都保存同一个账号的多个缓存值;

授权缓存的key是根据Principal类的toString得到的

© 著作权归作者所有

110hxl
粉丝 6
博文 211
码字总数 54059
作品 0
深圳
程序员
私信 提问
Shiro之CAS单点登录-yellowcong

配置单点登录,有点坑的是,我将Session存在了缓存中,导致我每次登录的时候,都不去cas验证中心,我就感觉很无语,后来将sessionManager删除后,就好用了,太坑了,这问题坑了一天多。实现C...

yelllowcong
2017/12/21
0
0
权限框架Shiro学习之表结构设计

权限框架Shiro学习之表结构设计 Shiro是一款优秀的开源安全框架,学习Shiro大家可以参考张开涛老师的博客:跟我学Shiro,当然也可参考我之前的笔记:Shiro实现身份认证、Shiro实现授权。 在学...

TyCoding
2018/09/18
630
0
JFianl整合Shiro

原文: 入门必看 英文好的可以直接看官网教程,英文不好的可以看下开涛的博客《跟我学Shiro》系列 在看教程之前,最好了解想一些shiro的概念:Apache Shiro Terminology 自己入门时踩的坑 一...

听_风
2016/08/30
138
0
base-framework 工程文档收录

1 shrio 实用功能说明 apache shiro 是功能强大并且容易集成的开源权限框架,它能够完成认证、授权、加密、会话管理等功能。认证和授权为权限控制的核心,简单来说,“认证”就是证明“你是谁...

晨润--菜菜
2014/02/11
2K
0
JFinal Authority 1.1 分布 jfinal 权限后台

更新内容 20140505 使用redis缓存 重写shiro sessionDao实现分布式session 20140504 添加redis缓存 20140504 过滤简单的 xss攻击 20140429 修复bug 登录过时 ajax请求没有跳转到登录页面 20...

12叔
2014/05/09
6.2K
27

没有更多内容

加载失败,请刷新页面

加载更多

Redis集群搭建

服务器资源 ip 账号 配置 操作系统 xxx.70 root/xxx 磁盘50G(/)+150G(/home)、内存16G、CPU 16core CentOS Linux release 7.2.1511 (Core) xxx.74 root/xxx 磁盘50G(/)+150G(/home)、......

jxlgzwh
23分钟前
3
0
avro

一、 ```我们已经接触过很多序列化框架(或者集成系统),比如protobuf、hessian、thrift等,它们各有优缺点以及各自的实用场景,Avro也是一个序列化框架,它的设计思想、编程模式都和thi...

hexiaoming123
24分钟前
5
0
QML TextInput的字体超出控件范围

本文链接:https://blog.csdn.net/chyuanrufeng/article/details/54691998 问题描述 :QML TextInput输入内容超过TextInput的大小 当输入过多的字符串时,会出现内容超过TextInput的大小,字...

shzwork
26分钟前
4
0
《Java 8 in Action》Chapter 10:用Optional取代null

1965年,英国一位名为Tony Hoare的计算机科学家在设计ALGOL W语言时提出了null引用的想法。ALGOL W是第一批在堆上分配记录的类型语言之一。Hoare选择null引用这种方式,“只是因为这种方法实...

HelloDeveloper
26分钟前
3
0
进击的 Java ,云原生时代的蜕变

作者| 易立 阿里云资深技术专家<br /> <br />导读:云原生时代的来临,与Java 开发者到底有什么联系?有人说,云原生压根不是为了 Java 存在的。然而,本文的作者却认为云原生时代,Java 依然...

阿里巴巴云原生
29分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部