首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何阻止shiro的特定url的会话超时?

如何阻止shiro的特定url的会话超时?
EN

Stack Overflow用户
提问于 2015-10-22 20:36:30
回答 2查看 982关注 0票数 0

我已经在我的webapp中使用Spring配置了Shiro全局超时,所以如果我的web页面(客户端)在过去30分钟内没有任何请求(只是实例),客户端的会话将超时并将页面重定向到登录页面。这已经可以了。我的问题如下:

web页面在后台有一个ajax请求,它将以设置的时间间隔向服务器发出请求。而且每次请求都会清除Shiro中会话的超时计数器,因此客户端会话永远不会超时!

是否可以配置Shiro使某些特定的urls不会清除或刷新会话超时?

这个问题真的很难命名,也很难搜索。但我觉得总会有一些人有同样的要求!任何人有任何想法,请告诉我。非常感谢~

我的part配置如下:

代码语言:javascript
复制
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="filters">
        <map>
            <entry key="ssl" value-ref="sslFilter"/>
            <entry key="login" value-ref="userLoginFilter"/>
            <entry key="nosessi" value-ref="unSessionFilter"/>
        </map>
    </property>
    <property name="securityManager" ref="securityManager"/>
    <property name="filterChainDefinitions">
        <value>
            /alarms/current-alarm-states = nosessi
            /js/** = anon
            /css/** = anon
            /images/** = anon
            /login = anon,ssl
            /login/** = anon,ssl
            /** = login,ssl
        </value>
    </property>
</bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realms">
        <list>
            <ref bean="userRealm"/>
        </list>
    </property>
    <property name="sessionManager" ref="sessionManager"/>
</bean>

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="sessionListeners">
        <list>
            <ref bean="sessionListener"/>
            <ref bean="tsSessionListener"/>
        </list>
    </property>
    <!-- 3 minutes: 180000 -->
    <property name="globalSessionTimeout" value="180000"/>
    <property name="sessionIdCookie.name" value="MY_SESSIONID"/>
</bean>
EN

回答 2

Stack Overflow用户

发布于 2015-10-22 22:01:42

你不能在Shiro中配置这个。超时与shiro无关,它是一个servlet容器配置。

用户会话是服务器中的单个对象,只要您的请求发送会话cookie (JSESSIONID ),并且servlet容器可以找到会话对象(因此它还没有超时),超时就会被重置。

您必须自己创建一些筛选器来跟踪超时。对于每个请求,您可以使用会话侦听器(http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpSessionListener.html)创建一个会话计时器。例如,您可以使用Timer对象来执行此操作。每次有请求进入时,过滤器都会获取会话计时器并重置它,除了那些你不希望发生这种情况的url。

你也可以查看Vaadin的源代码,因为他们有一个类似的设置,并以某种方式处理了它:https://vaadin.com/book/-/page/application.lifecycle.html#application.lifecycle.ui-expiration

票数 2
EN

Stack Overflow用户

发布于 2015-10-26 08:44:51

我调试了shiro,跟踪会话的行为。我发现最后一次访问的时间在ShiroFilterFactoryBean类中被更新了,之后,大多数过滤器都会用session的lastAccessTime来检查请求时间,除了一个过滤器。

基于此,我想出了一个解决方案。扩展ShiroFilterFactoryBean并覆盖更新会话访问时间的方法,该方法不会为特殊url更新。此外,特殊的必须使用anon过滤器。

代码语言:javascript
复制
public class MyShiroFilterFactoryBean extends ShiroFilterFactoryBean {

@Override
protected AbstractShiroFilter createInstance() throws Exception {
    SecurityManager securityManager = this.getSecurityManager();
    String manager1;
    if(securityManager == null) {
        manager1 = "SecurityManager property must be set.";
        throw new BeanInitializationException(manager1);
    } else if(!(securityManager instanceof WebSecurityManager)) {
        manager1 = "The security manager does not implement the WebSecurityManager interface.";
        throw new BeanInitializationException(manager1);
    } else {
        FilterChainManager manager = this.createFilterChainManager();
        PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
        chainResolver.setFilterChainManager(manager);
        return new NmsShiroFilterFactoryBean.SpringShiroFilter((WebSecurityManager)securityManager, chainResolver);
    }
}

@Override
public Class getObjectType() {
    return NmsShiroFilterFactoryBean.SpringShiroFilter.class;
}

private static final class SpringShiroFilter extends AbstractShiroFilter {
    protected SpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
        if(webSecurityManager == null) {
            throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
        } else {
            this.setSecurityManager(webSecurityManager);
            if(resolver != null) {
                this.setFilterChainResolver(resolver);
            }

        }
    }

    @Override
    protected void updateSessionLastAccessTime(ServletRequest request, ServletResponse response) {
        if(request instanceof HttpServletRequest) {
            String requestURI = ((HttpServletRequest) request).getRequestURI();
            if(requestURI.equals("/alarms/current-alarm-states")) { // no update the last access time of session
                return;
            }
        }
        super.updateSessionLastAccessTime(request, response);
    }
}

}

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33281215

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档