About Apache shiro implementation of an account only one person logged in at a time of shiro single sign on

  • 2020-06-15 10:59:38
  • OfStack

Today, I encountered a project problem, how to realize the existence of only 1session for one account at the same time. I found several articles and sorted out the core code here. The specific situation is as follows.

1. If you are using Apache shrio and the project requires that only one user exists for each account at any one time, you should add the following code to your shiro profile:


<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"></bean> 
  <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">  
    <constructor-arg name="name" value="SHRIOSESSIONID"/>  
  </bean>  
  <!--  configuration shiro session  the 1 A manager  --> 
  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> 
    <property name="sessionDAO" ref="sessionDAO"></property> 
  </bean> 
  <!--  configuration shiro  The cache 1 A manager  --> 
  <bean id="shiroCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"></bean> 
  <!--  configuration  Shiro  the  SecurityManager Bean. --> 
  <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
    <!-- <property name="cacheManager" ref="cacheManager"/>--> 
    <property name="realm" ref="myRealm"/> 
    <!-- shiro Cache manager  --> 
    <property name="cacheManager" ref="shiroCacheManager"></property> 
    <!-- shiro session manager  --> 
    <property name="sessionManager" ref="sessionManager"></property> 
  </bean> 

Next you should add the following code to your realm to determine if the user's account is logged in.


@Autowired 
private SessionDAO sessionDAO; 
............... 

Then you should get all the accounts that are logged in in realm's cache and determine if the current user is logged in


//apache shiro Get all online users  
    Collection<Session> sessions = sessionDAO.getActiveSessions(); 
    for(Session session:sessions){ 
      String loginUsername = String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY));// To obtain session Is the name of the logged in user  
       
      if(username.equals(loginUsername)){ // Here, username That's the one that's currently logged in username 
        session.setTimeout(0); // Here is the session Clear,  
         
      } 
    } 

2.SessionManager

There is a possible place for bug to appear. You can configure the sessionIdCookie attribute to resolve session ID overridden by the server in cookie


<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  <property name="globalSessionTimeout" value="1800000"/>  
  <property name="deleteInvalidSessions" value="true"/>  
  <property name="sessionValidationSchedulerEnabled" value="true"/>  
  <property name="sessionValidationInterval" value="1800000"/>  
  <property name="sessionIdCookie" ref="sessionIdCookie"/>  
</bean>  
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">  
  <constructor-arg name="name" value="SHRIOSESSIONID"/>  
</bean>  

Related articles: