shiro:每次页面request,SecurityUtils.getSubject() 返回不同的值

andylive 发布于 2013/07/30 21:09
阅读 45K+
收藏 0

@eyelee 你好,想跟你请教个问题:

jfinal整合shiro,shiro权限的使用中,每次页面request,SecurityUtils.getSubject() 得到的subject 不一样,

SecurityUtils.java
    public static Subject getSubject() {
        Subject subject = ThreadContext.getSubject();
        if (subject == null) {
            subject = (new Subject.Builder()).buildSubject();
            ThreadContext.bind(subject);
        }
        return subject;
    }


ThreadContext.java
    public static final String SUBJECT_KEY = ThreadContext.class.getName() + "_SUBJECT_KEY";
    public static Subject getSubject() {
        return (Subject) get(SUBJECT_KEY);
    }

因为每次页面过来的request都会是一个不同的thread,所以 SUBJECT_KEY 不一样,得到subject不一样,
 权限检测这样就出问题了subject是按线程保持,shiro有自定义的subject可以线程共享,但仍没搞明白,如何同一用户取到一样的subject?谢谢~

加载中
1
leon_rock
leon_rock
<!-- shiro  --> 
<listener> 
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class> 
</listener> 
<filter> 
<filter-name>shiro</filter-name> 
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class> 
        <init-param> 
       <param-name>staticSecurityManagerEnabled</param-name> 
       <param-value>true</param-value> 
   </init-param> 
</filter> 
<filter-mapping> 
<filter-name>shiro</filter-name> 
<url-pattern>/*</url-pattern> 
</filter-mapping>

@andylive 这一段放在最上面,在JFinal 之前



听_风
听_风
回复 @andylive : 我说我咋没碰到过呢,原来是顺序问题
a
andylive
问题在这里。
0
leon_rock
leon_rock
ServletContext servletContext = ; 
WebEnvironment webEnv = WebUtils.getRequiredWebEnvironment(servletContext);
org.apache.shiro.mgt.SecurityManager sm = webEnv.getWebSecurityManager();
SecurityUtils.setSecurityManager(sm);
Subject subject = SecurityUtils.getSubject();
这样获取试试
0
a
andylive
这段代码放在哪里?只是获取的地方用吗?只是获取的地方不行啊,还是拿到的不同,只有相同的线程id才能拿到,我已经崩溃了。。。
0
JFinal
a
andylive
嗯,参考的,非常感谢@JFinal@玛雅牛
0
a
andylive

引用来自“eyelee”的答案

ServletContext servletContext = ; 
WebEnvironment webEnv = WebUtils.getRequiredWebEnvironment(servletContext);
org.apache.shiro.mgt.SecurityManager sm = webEnv.getWebSecurityManager();
SecurityUtils.setSecurityManager(sm);
Subject subject = SecurityUtils.getSubject();
这样获取试试
程序初始化的时候按照你的思路,再加上ThreadContext.bind ( SecurityUtils.getSubject() ) 方法,这个问题解决了。
a
andylive
ThreadContext.bind(SecurityUtils.getSubject()); Subject suject = SecurityUtils.getSubject(); 可以得到同一个subject了。
leon_rock
leon_rock
Subject subject = ThreadContext.getSubject(); 这个试试~~
a
andylive
啊,官方文档我看的不够仔细吧。谢谢~@eyelee
leon_rock
leon_rock
我这个是官方文档给出的~~~
0
a
andylive
多个用户登录,每个用户拿到的subject,都是被最后一个用户给改写。。。加bind()改也是错的。。
0
a
andylive

@eyelee  @JFinal 

index的请求没有走 filter.

JFinal action report -------- 2013-08-02 17:49:22 ------------------------------
Controller  : com.pos.controller.LoginController.(LoginController.java:1)
Method      : index
Interceptor : com.jfinal.ext.plugin.shiro.ShiroInterceptor.(ShiroInterceptor.java:1)
--------------------------------------------------------------------------------
[INFO ] 08-02 17:49:22.570 [qtp625962559-36] c.j.e.p.shiro.ShiroInterceptor:36   - ShiroInterceptor call intercept() currentTread: qtp625962559-36
getSubject() is null buildSubjecte! 
[INFO ] 08-02 17:49:41.171 [qtp625962559-36] c.p.controller.LoginController:44   - LoginController call index() currentTread: qtp625962559-36
[INFO ] 08-02 17:49:41.649 [qtp625962559-41]   com.jfinal.core.JFinalFilter:70   - JFinalFilter call doFilter() currentTread: qtp625962559-41
[INFO ] 08-02 17:49:47.608 [qtp625962559-41] o.a.s.s.m.AbstractValidatingSessionManager:230  - Enabling session validation scheduler...
[INFO ] 08-02 17:49:47.623 [qtp625962559-41] o.a.s.c.ehcache.EhCacheManager:170  - Using existing EHCache named [shiro-activeSessionCache]
[INFO ] 08-02 17:49:59.782 [qtp625962559-41]  o.a.s.w.s.AbstractShiroFilter:360  - AbstractShiroFilter call doFilterInternal!

这个web.xml配置对吗?

Web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">


<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<param-value>com.pos.config.PosConfig</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


    <!-- shiro  -->
<listener>
<listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
<filter-name>shiro</filter-name>
<filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
        <init-param>
       <param-name>staticSecurityManagerEnabled</param-name>
       <param-value>true</param-value>
   </init-param>
</filter>
<filter-mapping>
<filter-name>shiro</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


</web-app>
0
s
sdls10qq
经验学习
0
车开源
车开源

请教下:如果我需要在public void sessionDestroyed(HttpSessionEvent arg0)方法里获取Subject该如何弄呢?

在Controller里获取没问题,就是在HttpSessionListener里就取不到。

目前获取不到,总是Null

也尝试过org.apache.shiro.session.SessionListener实现会话监听,一直没弄成功,测试发现只有onStart被触发,onExpiration,onStop没动静,等等会话过期之后,刷新页面就获取不到会话数值导致出错

返回顶部
顶部