سؤال

Well, I have posted following question on Shiro's forum for 1 week but no response until now.

I am just trying to use Shiro with a simple Spring application. The security manager is defined as DefaultWebSecurityManager which set session manager as ServletContainerSessionManager by default and it works for me. However, after I changed the session manager to DefaultWebSessionManager which means I want to use Shiro's native session, it not works on Chrome. I dug out some following information:-

  • When using DefaultWebSessionManager, Shiro tries to get session id from request cookie. The logic SimpleCookie is looping all request cookies and return when a cookie's name is 'JSESSIONID'. However, in the requests come from Chrome, there are 2 cookies with name 'JSESSIONID'. The value of the first one is different with 'requestedSessionid' in request and the other one equals. That result in a new redirect to login page after authentication successfully. To make it simple, the process now is: access any address -> redirect to login page by Shiro -> submit principals and credentials -> authentication successfully and redirect to home page by Shiro -> a new request comes and found another session id which is not cached in Shiro, result in a InvalidSessionException in resolveSession method in DefaultSecurityManager -> redirect back to login page.
  • When using ServletContainerSessionManager, since the session id is come from request.getSession(false), the session could be found after redirect.

My question is if this is a defect or anything configurations or codes can fix this problem? Note only Chrome fires this problem. I guess it's about Chrome's cache but can you explain more?

Below is the necessary sources for you to replicate:-

web.xml

<listener>
  <listener-class>test.shiro.framework.WebSessionListener</listener-class>
</listener>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/spring-servlet.xml</param-value>
</context-param>  


<filter>
  <filter-name>shiroFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  <init-param>
    <param-name>targetFilterLifecycle</param-name>
    <param-value>true</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>shiroFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
  <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/controller/*</url-pattern>
</servlet-mapping>

spring-servlet.xml:

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
  <property name="securityManager" ref="securityManager" />
  <property name="loginUrl" value="/login.jsp"/>
  <property name="successUrl" value="/home.jsp"/>  
  <property name="unauthorizedUrl" value="/unauthorized.jsp"/>

  <property name="filterChainDefinitions">
    <value>
      /** = authc 
    </value>
  </property>
</bean>

<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">

  <property name="realm" ref="myRealm" />
  <property name="sessionManager">
    <bean class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"></bean>
  </property>

</bean>
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

<bean id="myRealm" class="org.apache.shiro.realm.text.TextConfigurationRealm">
  <property name="userDefinitions">
    <value>
      huzj=12345678,authc 
      guodg=12345678,operator 
      sadd=12345678,guest 
    </value>
  </property>
  <property name="roleDefinitions">
    <value>
      authc=* 
      operator=book:* 
      guest=book:view:* 
    </value>
  </property>
</bean>

Feb 18 UPDATE: A further testing shows that the problem only occured when I tried to change from ServletContainerSessionManager to DefaultWebSessionManager. I guess chrome records a junk cookie in this situation by mistake.

After all I tried @paulochf's solution and it does work. I debugged again and believe you got the point. Many thanks!

هل كانت مفيدة؟

المحلول

At my work, we had the very same problem, but we resolved it.

Using Google Chrome, the application could not keep the session because it's ID changed almost at each request made. Meanwhile, Firefox didn't have it. The guy who had turned DefaultWebSessionManager on used an example from the web, where it set the cookie name as "cookie".

He resolved changing the name of the cookie to another, for example,

cookie = org.apache.shiro.web.servlet.SimpleCookie 
cookie.name = your.cookie
cookie.path = /
sessionManager.sessionIdCookie = $cookie

I expect this works to you.

نصائح أخرى

Your solution still works. Current environment : Shiro 1.2.3 , Chrome Version 42.0.2311.90 (64-bit), Linux OS.

For those who configure Shiro via Spring, here's how to override the JSESSIONID as the default cookie name (to "JSESSID" in this case).

<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="globalSessionTimeout" value="..." />
    <property name="sessionListeners">
        <util:list>
            <ref bean="..." />
        </util:list>
    </property>
    <property name="sessionIdCookie">
        <bean class="org.apache.shiro.web.servlet.SimpleCookie">
            <property name="name" value="JSESSID" />
        </bean>
    </property>
</bean>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top