Shiro Learning (Ten) session management

Source: Internet
Author: User
Tags ini int size session id sessions set cookie touch


Shiro provides complete enterprise-level session management capabilities, independent of the underlying container (such as Web container tomcat) that can be used regardless of the javase or Java EE Environment, providing session management, session event snooping, session storage/persistence, container-independent clustering, expiration/expiration support, Features such as transparent support for the Web, support for SSO single sign-on, and more. Session management that uses Shiro directly can replace session management such as Web containers.



Session
The so-called session, which is the connection relationship that the user maintains when accessing the app, is applied in multiple interactions to identify who the user is currently accessing and can save some data in multiple interactions. When you visit some websites successfully, the site remembers the user and can identify who the current user is before exiting.



Shiro session support can be used not only in common javase applications, but also in Java EE applications, such as Web applications. and are used in a consistent manner.
Java code




Login ("Classpath:shiro.ini", "Zhang", "123");  
Subject Subject = Securityutils.getsubject ();  


Use Subject.getsession () to get the session after a successful login, which is equivalent to Subject.getsession (true), that is, if the session object is not currently created, one is created, and the other subject.getsession ( FALSE), NULL is returned if no session is currently created (however, by default, if you enable the Sessions store feature, you will be actively creating a session when creating subject).



Java code




Session.getid ();  


Gets the unique identity of the current session.



Java code




Session.gethost ();  


Gets the host address of the current subject, which is provided through Hostauthenticationtoken.gethost ().



Java code




Session.gettimeout ();  
Session.settimeout (MS);  


Gets/sets the expiration time of the current session, or if not set by default, is the session manager's global expiration time.



Java code




Session.getstarttimestamp ();  
Session.getlastaccesstime ();  


Gets the start time and last access time of the session, and if the Javase application needs to periodically call Session.touch () to update the last access time, if it is a web app, Session.touch () is automatically called each time it enters Shirofilter To update the last access time.



Java code




Session.touch ();  


The last access time of the session is updated and the session is destroyed, and the Stop method is automatically called when Subject.logout () destroys the session. If you are in the Web, call javax.servlet.http.HttpSession. Invalidate () also automatically calls the Shiro Session.stop method to destroy the Shiro session.



Java code




Session.setattribute ("Key", "123");  
Assert.assertequals ("123", Session.getattribute ("key"));  


Set/Get/delete session properties, which can be manipulated throughout the session.



Shiro provides a session that can be used in a JAVASE/JAVAEE environment, independent of any underlying container, and can be used as a complete session module.



Session Manager
The session Manager manages the creation, maintenance, deletion, invalidation, and validation of all subject sessions in the app. Is the core component of Shiro, the top-level component SecurityManager directly inherits SessionManager, and provides Sessionssecuritymanager implementation to delegate session management directly to the corresponding SessionManager, The Defaultsecuritymanager and Defaultwebsecuritymanager default SecurityManager inherit Sessionssecuritymanager.



SecurityManager provides the following interfaces:



Java code




Session Start (sessioncontext context); Start session  
getsession (SessionKey key) throws sessionexception;//Get session based on session key


In addition, the Websessionmanager for the Web environment provides the following interfaces:



Java code




Boolean isservletcontainersessions ();//Whether to use the session of the servlet container  


Shiro also provides validatingsessionmanager for capital verification and expiration sessions:
Java code




void Validatesessions ();//Verify that all sessions are out of date  






The Shiro provides three default implementations:
Defaultsessionmanager: The default implementation used by Defaultsecuritymanager for javase environment;
Servletcontainersessionmanager: Defaultwebsecuritymanager uses the default implementation for the Web environment, which directly uses the Servlet container's session;
Defaultwebsessionmanager: For the implementation of the Web environment, can replace the Servletcontainersessionmanager, maintain the session, and directly discard the servlet container session management.



Replace SecurityManager default SessionManager can be configured in INI (Shiro.ini):



Java code
[Main]




Sessionmanager=org.apache.shiro.session.mgt.defaultsessionmanager  


INI configuration in the Web Environment (Shiro-web.ini):



Java code




[Main]  
Sessionmanager=org.apache.shiro.web.session.mgt.servletcontainersessionmanager  
Securitymanager.sessionmanager= $sessionManager  


You can also set the global expiration time (in milliseconds) for a session by default of 30 minutes:



Java code




SessionManager. globalsessiontimeout=1800000   


By default, Globalsessiontimeout will be applied to all sessions. You can set the Timeout property of each session individually to set its time-out for each session.



In addition, if you use Servletcontainersessionmanager for session management, the session timeout depends on the time-out period of the underlying servlet container, and the time-out (in minutes) that can be configured in Web. XML for its sessions:
Java code




<session-config>  
  <session-timeout>30</session-timeout>  
</session-config>  


In the Servlet container, the session is maintained by default using the Jsessionid cookie, and the session is bound to the container by default, and in some cases it may be necessary to use its own session mechanism, at which point we can use Defaultwebsessionmanager to maintain the session:
Java code




sessionidcookie=org.apache.shiro.web.servlet.simplecookie sessionManager= Org.apache.shiro.web.session.mgt.DefaultWebSessionManager sessionidcookie.name=sid #sessionIdCookie. domain= Sishuok.com #sessionIdCookie. path= sessionidcookie.maxage=1800 sessionidcookie.httponly=true Sessionmanager.sessio nidcookie= $sessionIdCookie sessionmanager.sessionidcookieenabled=true securitymanager.sessionmanager=$ SessionManager 


Sessionidcookie is a template for SessionManager to create session cookies:
Sessionidcookie.name: Set cookie name, default is Jsessionid;
Sessionidcookie.domain: Set the domain name of the cookie, default null, namely the domain name that is currently visited;
Sessionidcookie.path: Set the path of the cookie, default empty, that is stored under the domain name root;
Sessionidcookie.maxage: Sets the expiration time of the cookie, in seconds, by default-1 means that the cookie expires when the browser is closed;
Sessionidcookie.httponly: If set to true, clients are not exposed to client script code, and using the HttpOnly cookie helps reduce certain types of cross-site scripting attacks; This attribute requires the implementation of Servlet 2.5 MR6 and above version of the specification servlet container support;
Sessionmanager.sessionidcookieenabled: Whether to enable/disable session ID cookie, which is enabled by default, if disabled, the session ID cookie will not be set. That is, the jsessionid of the servlet container is used by default and is rewritten by URL (in the URL "; Jsessionid=id "section) to save the session ID.



In addition we can be like "SessionManager." Sessionidcookie.name=sid "This way to manipulate cookie templates.



Session Listener
Session listeners are used to listen for session creation, expiration, and stop events:
Java code




public class MySessionListener1 implements Sessionlistener {  
    @Override public  
    void OnStart (Session session) {// Trigger SYSTEM.OUT.PRINTLN When session is created  
        ("Session creation:" + Session.getid ());  
    }  
    Trigger System.out.println when @Override public void Onexpiration (session session) {//session expires  
        : + Session.getid ()) ;  
    }  
    @Override public  
    void OnStop (Session session) {//exit/session expires when SYSTEM.OUT.PRINTLN is triggered  
        ("conversation stopped:" + Session.getid ());  
    }    
}  


If you only want to listen to an event, you can inherit the Sessionlisteneradapter implementation:
Java code




public class MySessionListener2 extends Sessionlisteneradapter {  
    @Override public  
    void OnStart (Session session) {  
        System.out.println ("Conversation creation:" + Session.getid ())}  
}  


In the Shiro-web.ini configuration file, you can configure the session listener as follows:
Java code




Sessionlistener1=com.github.zhangkaitao.shiro.chapter10.web.listener.mysessionlistener1  
sessionListener2= Com.github.zhangkaitao.shiro.chapter10.web.listener.MySessionListener2  
sessionmanager.sessionlisteners=$ SessionListener1, $sessionListener 2  


Session Storage/Persistence
Shiro provides a crud for Sessiondao sessions, the DAO (Data Access Object) pattern implementation:
Java code




This method is called when Defaultsessionmanager is created, such as saving to a relational database/file system/nosql database, which enables session persistence, returning the session ID, and the main returned Id.equals ( Session.getid ());  
Serializable Create (Session session);  
Gets session  
readsession (Serializable sessionId) throws unknownsessionexception based on session ID;  
Update session, such as update session last access time/stop session/Set timeout/Set remove property, etc. call  
Void Update (Session session) throws Unknownsessionexception;  
Delete the session; Void Delete (session session) is called when the session expires/the session stops (such as when the user exits)  
;  
Gets the current all active users, if the user volume is more than this method affects performance  
collection<session> getactivesessions ();   


Shiro Embedded The following Sessiondao implementation:

Abstractsessiondao provides the basic implementation of SESSIONDAO, such as generating session ID, etc. Cachingsessiondao provides a transparent session cache for developers, only need to set the corresponding CacheManager Memorysessiondao session maintenance directly in memory, while Enterprisecachesessiondao provides session maintenance for the cache function, which is implemented by default using MapCache. Internally use Concurrenthashmap to save the cached session.




You can set Sessiondao with the following configuration:
Java code




Sessiondao=org.apache.shiro.session.mgt.eis.enterprisecachesessiondao  
sessionmanager.sessiondao=$ Sessiondao   


Shiro provides for session storage using Ehcache, Ehcache can be implemented in a container-independent distributed cluster with terracotta.



First, add the following dependencies in the Pom.xml:
Java code




<dependency>  
    <groupId>org.apache.shiro</groupId>  
    <artifactId>shiro-ehcache< /artifactid>  
    <version>1.2.2</version>  
</dependency>   


Then configure the Shiro-web.ini file:
Java code




Sessiondao=org.apache.shiro.session.mgt.eis.enterprisecachesessiondao  
Sessiondao. activeSessionsCacheName= Shiro-activesessioncache  
sessionmanager.sessiondao= $sessionDAO  
CacheManager = Org.apache.shiro.cache.ehcache.EhCacheManager  
Cachemanager.cachemanagerconfigfile=classpath:ehcache.xml  
Securitymanager.cachemanager = $cacheManager   


Sessiondao. Activesessionscachename: Set session cache name, default is Shiro-activesessioncache;
CacheManager: Cache manager for managing caches, which are implemented here using Ehcache;
Cachemanager.cachemanagerconfigfile: Set configuration file for Ehcache cache;
Securitymanager.cachemanager: Setting the CacheManager of SecurityManager, the corresponding object that implements Cachemanageraware interface is set automatically, such as Sessiondao CacheManager;



Then configure Ehcache.xml:
Java Code Collection Code




<cache name= "Shiro-activesessioncache"  
       maxentrieslocalheap= "10000"  
       overflowtodisk= "false"  
       Eternal= "false"  
       diskpersistent= "false"  
       timetoliveseconds= "0"  
       timetoidleseconds= "0"  
       statistics= "True"/>   


The name of the cache is Shiro-activesessioncache, which is the value of the Activesessionscachename property of the Sessiondao set.



You can also set the session ID generator with the following INI configuration:
Java code




Sessionidgenerator=org.apache.shiro.session.mgt.eis.javauuidsessionidgenerator  
Sessiondao.sessionidgenerator= $sessionIdGenerator   


Used to generate the session ID, which is javauuidsessionidgenerator by default and generated using Java.util.UUID.



If the custom implementation Sessiondao, inherit the Cachingsessiondao:
Java code


public class Mysessiondao extends Cachingsessiondao {private JdbcTemplate JdbcTemplate = jdbctemplateutils.jdbctemp  
     Late ();  
        Protected Serializable Docreate (Session session) {Serializable sessionId = Generatesessionid (session);  
        Assignsessionid (session, SESSIONID);  
        String sql = "INSERT into sessions (ID, session) VALUES (?,?)";  
        Jdbctemplate.update (SQL, SessionId, serializableutils.serialize (session));  
    return Session.getid (); } protected void DoUpdate (session session) {if (Session instanceof Validatingsession &&! (validatingsession) session). IsValid ()) {return;//If the session expires/stops it is not necessary to update the} String sql = "Update sess Ions set session=?  
        where id=? ";  
    Jdbctemplate.update (SQL, Serializableutils.serialize (session), Session.getid ());  
        } protected void DoDelete (Session session) {String sql = "Delete from sessions where id=?"; Jdbctemplate.update (SQL, SessIon.getid ()); } protected session doreadsession (Serializable sessionId) {String sql = "Select session from Sessions whe  
        Re id=? ";  
        list<string> sessionstrlist = jdbctemplate.queryforlist (sql, String.class, sessionId);  
        if (sessionstrlist.size () = = 0) return null;  
    Return Serializableutils.deserialize (sessionstrlist.get (0));    }  
}


The docreate/doupdate/dodelete/doreadsession represents the Create/modify/delete/read sessions, respectively, where the session is serialized and stored in the database, and then configured in Shiro-web.ini:
Java code




Sessiondao=com.github.zhangkaitao.shiro.chapter10.session.dao.mysessiondao  


The other settings are the same as before because Cachingsessiondao is inherited, and all reads are checked for presence in the cache, and if not found in the database.



Session Validation
Shiro provides a session validation scheduler for periodic validation sessions that have expired, stops sessions if they expire, and in general, for performance reasons, to verify that the session expires and stops the session, as in the case of a web environment, if the user does not actively exit without knowing whether the session is out of date, So it is necessary to periodically check whether the session is out of date, Shiro provides the session validation scheduler Sessionvalidationscheduler to do this.



Session validation can be turned on using the following INI configuration:
Java code




Sessionvalidationscheduler=org.apache.shiro.session.mgt.executorservicesessionvalidationscheduler  
Sessionvalidationscheduler.interval = 3600000  
sessionvalidationscheduler.sessionmanager= $sessionManager  
sessionmanager.globalsessiontimeout=1800000  
sessionmanager.sessionvalidationschedulerenabled=true  
Sessionmanager.sessionvalidationscheduler= $sessionValidationScheduler   


Sessionvalidationscheduler: Session Verification Scheduler, sessionmanager default is to use Executorservicesessionvalidationscheduler, It uses the scheduledexecutorservice of the JDK to schedule periodically and verify that the session is out of date;
Sessionvalidationscheduler.interval: Set the schedule interval, in milliseconds, the default is 1 hours;
Sessionvalidationscheduler.sessionmanager: Session Manager to set session validation scheduler for session validation;
Sessionmanager.globalsessiontimeout: Set global session timeout, default 30 minutes, that is, if no access session within 30 minutes expires;
Sessionmanager.sessionvalidationschedulerenabled: Whether to turn on the session authenticator, which is enabled by default;
Sessionmanager.sessionvalidationscheduler: Set the session Validation scheduler by default, using Executorservicesessionvalidationscheduler.



Shiro also provides the use of Quartz session Authentication Scheduler:
Java code




Sessionvalidationscheduler=org.apache.shiro.session.mgt.quartz.quartzsessionvalidationscheduler  
Sessionvalidationscheduler.sessionvalidationinterval = 3600000  
sessionvalidationscheduler.sessionmanager=$ SessionManager   


You need to import Shiro-quartz dependencies when using:
Java code




<dependency>  
     <groupId>org.apache.shiro</groupId>  
     <artifactid>shiro-quartz</ artifactid>  
     <version>1.2.2</version>  
</dependency>  


such as the previous session verification scheduler implementation is directly called Abstractvalidatingsessionmanager Validatesessions method for validation, Its direct call to Sessiondao's Getactivesessions method gets all the sessions to be validated, and if the session is more numerous, it can affect performance, consider, for example, paging to get the session and verify, such as Com.github.zhangkaitao.shiro.chapter10.session.scheduler.MySessionValidationScheduler:
Java code




//paging gets the session and validates String sql = "Select session from Sessions limit?,?"; int start = 0; Start record int size = 20;  
Size per page list<string> sessionlist = jdbctemplate.queryforlist (sql, String.class, start, size); while (Sessionlist.size () > 0) {for (String sessionstr:sessionlist) {try {session session = Serial  
      Izableutils.deserialize (SESSIONSTR); Method Validatemethod = Reflectionutils.findmethod (Abstractvalidatingsessionmanager.class, "Vali  
      Date ", Session.class, Sessionkey.class);  
      Validatemethod.setaccessible (TRUE);  
    Reflectionutils.invokemethod (Validatemethod, SessionManager, Session, New Defaultsessionkey (Session.getid ()));  
  } catch (Exception e) {//ignore}} start = start + size;  
sessionlist = jdbctemplate.queryforlist (sql, String.class, start, size); }   


Its direct transformation from Executorservicesessionvalidationscheduler, such as the code is the core of the verification code, can be adapted to their own needs of this verification scheduler, INI configuration and similar.



If you do not want to delete an expired session when the session expires, you can set it by using the following INI configuration:
Java code




Sessionmanager.deleteinvalidsessions=false  


The default is on, and when the session expires, it calls Sessiondao's Delete method to remove the session: This method can be called to delete the session when it is persisted for storage.



If you verify that the session has expired when you get the session, you will throw invalidsessionexception, so you need to catch this exception and jump to the appropriate page to tell the user that the session has expired and have it log back on, as you can configure the appropriate error page in Web. xml:
Java code




<error-page>  
    <exception-type>org.apache.shiro.session.invalidsessionexception</ exception-type>  
    <location>/invalidSession.jsp</location>  
</error-page>  


sessionfactory
Sessionfactory is the factory that creates the session, creates the session based on the appropriate subject context information, and provides the simplesessionfactory to create the simplesession session by default.



First, customize a session:
Java code




public class Onlinesession extends Simplesession {public  
    static enum Onlinestatus {  
        on_line ("online"), Hidden ("stealth") , Force_logout ("forced exit");  
        Private final String info;  
        Private Onlinestatus (String info) {  
            this.info = info;  
        }  
        Public String GetInfo () {  
            return info;  
        }  
    }  
    Private String useragent; User browser type  
    private onlinestatus status = onlinestatus.on_line;//Online Status  
    private String systemhost;//user logon system ip< c13/>//omit Other  
}   


The onlinesession is used to save the current logged-on user's online status and to support controls such as offline status.



Then customize the sessionfactory:
Java code




public class Onlinesessionfactory implements Sessionfactory {  

    @Override the public  
    Session createsession ( Sessioncontext initdata) {  
        onlinesession session = new Onlinesession ();  
        if (InitData! = null && initdata instanceof websessioncontext) {  
            Websessioncontext Sessioncontext = (Websessi Oncontext) InitData;  
            HttpServletRequest request = (HttpServletRequest) sessioncontext.getservletrequest ();  
            if (Request! = null) {  
                session.sethost (iputils.getipaddr (Request));  
                Session.setuseragent (Request.getheader ("user-agent"));  
                Session.setsystemhost (REQUEST.GETLOCALADDR () + ":" + request.getlocalport ());  
            }  
        }  
        return session;  
    }  
}   


Creates a corresponding onlinesession based on the session context.



Finally, configure in the Shiro-web.ini configuration file:
Java code




Sessionfactory=org.apache.shiro.session.mgt.onlinesessionfactory  
sessionmanager.sessionfactory=$ Sessionfactory  


Please refer to the relevant code in Https://github.com/zhangkaitao/es/tree/master/web/src/main/java/org/apache/shiro for more information.



Sample source code: Https://github.com/zhangkaitao/shiro-example


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.