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