shiro会话管理

目录

1. 会话管理

2. 基础组件

 2.1 SessionManager

 2.2 SessionListener 

 2.3 SessionDao 

 2.4 会话验证

3. 缓存管理 

3.1 为什么要使用缓存 

3.2 什么是ehcache 

3.3 ehcache特点 

4. 添加pom依赖 

5. 添加相关配置文件

 5.1 ehcache.xml (添加到main\resources目录下)

 5.2 spring-ehcache.xml,shiro与ehcache整合(添加到main\resources目录下)

 5.3 修改spring-shiro.xml文件,添加相关配置 (完整,可直接覆盖即可)


 

 1. 会话管理

Shiro提供了完整的企业级会话管理功能,不依赖于底层容器(如Tomcat),不管是J2SE还是J2EE环境都可以使用,提供了会话管理,会话事件监听,会话存储/持久化,容器无关的集群,失效/过期支持,对Web的透明支持,SSO单点登录的支持等特性。所谓会话,即用户访问应用时保持的连接关系,在多次交互中应用能够识别出当前访问的用户是谁,且可以在多次交互中保存一些数据。如访问一些网站时登录成功后,网站可以记住用户,且在退出之前都可以识别当前用户是谁。 

2. 基础组件

 2.1 SessionManager

会话管理器管理着应用中所有 Subject 的会话的创建、维护、删除、失效、验证等工作。是Shiro 的核心组件,顶层组件SecurityManager直接继承了SessionManager,且提供了SessionsSecurityManager实现直接把会话管理委托给相应的SessionManager
1)DefaultSessionManager:使用的默认实现,用于JavaSE环境
2)ServletContainerSessionManager:使用的默认实现,用于Web环境,其直接使用Servlet容器的会话
3)DefaultWebSessionManager:用于Web环境的实现,可以替代ServletContainerSessionManager,自己维护着会话,直接废弃了Servlet容器的会话管理 

 2.2 SessionListener 

  SessionListener会话监听器用于监听会话创建、过期及停止事件。
  实现方式:
  1)实现SessionListener,必须实现所有方法
  2)继承SessionListenerAdapter,重写指定方法 

 相关API: 

  1)onStart(Session session):监听会话创建事件
  2)onStop(Session session):监听会话销毁事件
  3)onExpiration(Session session):监听会话过期事件 

 2.3 SessionDao 

Shiro提供SessionDAO用于会话的CRUD,即DAO(Data Access Object)模式实现。
1)AbstractSessionDAO:提供了SessionDAO的基础实现,如生成会话ID等
2)CachingSessionDAO:提供了对开发者透明的会话缓存的功能,需要设置相应的CacheManager 
3)MemorySessionDAO:直接在内存中进行会话维护(默认方式)
4)EnterpriseCacheSessionDAO:提供了缓存功能的会话维护,默认情况下使用MapCache实现,内部使用ConcurrentHashMap保存缓存的会话。

 相关API: 

  如DefaultSessionManager在创建完session后会调用该方法;
  如保存到关系数据库/文件系统/NoSQL数据库;
  即可以实现会话的持久化;返回会话ID;主要此处返回的ID.equals(session.getId());  
  Serializable create(Session session);
  根据会话ID获取会话  
  Session readSession(Serializable sessionId) throws UnknownSessionException;  
  更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用  
  void update(Session session) throws UnknownSessionException;  
  删除会话;当会话过期/会话停止(如用户退出时)会调用  
  void delete(Session session);  
  获取当前所有活跃用户,如果用户量多此方法影响性能  
  Collection<Session> getActiveSessions();

 2.4 会话验证


1)Shiro提供了会话验证调度器,用于定期的验证会话是否已过期,如果过期将停止会话。
2)出于性能考虑,一般情况下都是获取会话的同时来验证会话是否过期并停止会话的;但是如果在Web环境中,如果用户不主动退出是不知道会话是否过期的,因此需要定义的检测会话是否过期,Shiro提供了会话验证调度器来定期检查会话是否过期,SessionValidationScheduler 。
3)Shrio也提供了使用Quartz会话验证调度器 QuartzSessionValidationScheduler 。 

3. 缓存管理 

3.1 为什么要使用缓存 

在没有使用缓存的情况下,我们每次发送请求都会调用一次doGetAuthorizationInfo方法来进  行用户的授权操作,但是我们知道,一个用户具有的权限一般不会频繁的修改,也就是每次  授权的内容都是一样的,所以我们希望在用户登录成功的第一次授权成功后将用户的权限保  存在缓存中,下一次请求授权的话就直接从缓存中获取,这样效率会更高一些

 3.2 什么是ehcache 

Ehcache是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大。是Hibernate中默认CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。 

  • 本章介绍的是2.X版本,3.x的版本和2.x的版本API差异比较大 

3.3 ehcache特点 

1) 够快
 Ehcache的发行有一段时长了,经过几年的努力和不计其数的性能测试,Ehcache终被设计于large, high concurrency systems.
 2) 够简单
 开发者提供的接口非常简单明了,从Ehcache的搭建到运用运行仅仅需要的是你宝贵的几分钟。其实很多开发者都不知道自己用在用Ehcache,Ehcache被广泛的运用于其他的开源项目
 3) 够袖珍

关于这点的特性,官方给了一个很可爱的名字small foot print ,一般Ehcache的发布版本不会到2M,V 2.2.3 才 668KB。
4) 够轻量
核心程序仅仅依赖slf4j这一个包,没有之一!
5) 好扩展
Ehcache提供了对大数据的内存和硬盘的存储,最近版本允许多实例、保存对象高灵活性、  提供LRU、LFU、FIFO淘汰算法,基础属性支持热配置、支持的插件多
6) 监听器
缓存管理器监听器 (CacheManagerListener)和 缓存监听器(CacheEvenListener),做一些统计或数据一致性广播挺好用的
7) 分布式缓存
从Ehcache 1.2开始,支持高性能的分布式缓存,兼具灵活性和扩展性 

4. 添加pom依赖 

  • 复制下方依赖可直接覆盖 
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.jmh</groupId>
  <artifactId>mybatis03</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>mybatis03 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <!--版本-->
  <properties>
    <spring.version>5.0.2.RELEASE</spring.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <jackson.version>2.9.3</jackson.version>
    <shiro.version>1.2.5</shiro.version>
    <slf4j.version>1.7.7</slf4j.version>
    <log4j2.version>2.9.1</log4j2.version>
  </properties>

  <dependencies>
    <!-- **********************spring依赖 ********************** -->
    <!--1)spring核心依赖-->
    <!-- ********************** spring-ore核心依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!--spring ioc依赖 -->
    <!-- ********************** spring-ioc依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!--spring 扩展依赖 -->
    <!-- ********************** spring-context依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!--2)spring dao层依赖-->
    <!-- ********************** spring-orm依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- ********************** spring-tx依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}
      </version>
    </dependency>

    <!--3)aop相关依赖 -->
    <!-- ********************** spring-aspects依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!--4)spring web相关依赖 -->
    <!-- ********************** spring-web依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!--5) spring test相关依赖 -->
    <!-- ********************** spring-test依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- ********************** spring-webmvc依赖 ********************** -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>

    <!-- ********************** JSTL依赖 ********************** -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <!-- ********************** Json相关依赖 ********************** -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
      <exclusions>
        <exclusion>
          <artifactId>jackson-annotations</artifactId>
          <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jackson.version}</version>
    </dependency>

    <!-- ********************** 文件上传依赖 ********************** -->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.3</version>
    </dependency>

    <!-- ********************** JSR303依赖 ********************** -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.7.Final</version>
    </dependency>

    <!-- ********************** junit单元测试依赖 ********************** -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <!-- ********************** JavaServlet API  ********************** -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- ********************** Mybatis依赖 ********************** -->
    <!--1) mybatis核心 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.5</version>
    </dependency>

    <!--2) Mybatis分页插件-->
    <!-- ********************** Mybatis分页插件 ********************** -->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.2</version>
    </dependency>

    <!--3) spring整合mybatis -->
    <!-- ********************** spring整合mybatis ********************** -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>

    <!-- ********************** MysqlJDBC驱动 ********************** -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.44</version>
    </dependency>

    <!--dbcp2连接池依赖-->
    <!-- ********************** dbcp2连接池依赖 ********************** -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>2.1.1</version>
    </dependency>

    <!-- ********************** commons-pool2 ********************** -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>2.4.3</version>
    </dependency>

    <!-- **********************  日志配置  ********************** -->
    <!--记得修改mybatis.cfg.xml添加如下内容-->
    <!--<setting name="logImpl"value="LOG4J2"/>-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>${slf4j.version}</version>
      <scope>runtime</scope>
      <exclusions>
        <exclusion>
          <artifactId>slf4j-api</artifactId>
          <groupId>org.slf4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <!-- 用于与slf4j保持桥接-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>${log4j2.version}</version>
      <exclusions>
        <exclusion>
          <artifactId>slf4j-api</artifactId>
          <groupId>org.slf4j</groupId>
        </exclusion>
      </exclusions>
    </dependency>

    <!--核心log4j2jar包-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <!--web工程需要包含log4j-web,非web工程不需要-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-web</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <!--需要使用log4j2的AsyncLogger需要包含disruptor -->
    <dependency>
      <groupId>com.lmax</groupId>
      <artifactId>disruptor</artifactId>
      <version>3.2.0</version>
    </dependency>

    <!-- **********************  lombok依赖  ********************** -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.20</version>
      <scope>provided</scope>
    </dependency>

    <!-- ********************** shiro相关依赖  ********************** -->
    <!-- shiro核心包 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-core</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <!-- 添加shiro web支持 -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-web</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <!--shiro和spring的集成-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>${shiro.version}</version>
    </dependency>

    <!-- ********************** ehcache缓存依赖  ********************** -->
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>2.10.0</version>
    </dependency>

    <!-- ********************** spring对ehcache的整合依赖  ********************** -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>1.4.1</version>
    </dependency>
    <!-- spring对ehcache的相关支持-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>

  </dependencies>
  <!--插件部分-->
  <build>
    <finalName>shiro02</finalName>
    <resources>
      <!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题-->
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题-->
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>jdbc.properties</include>
          <include>*.xml</include>
        </includes>
      </resource>
    </resources>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <groupId>org.mybatis.generator</groupId>
          <artifactId>mybatis-generator-maven-plugin</artifactId>
          <version>1.3.2</version>
          <dependencies>
            <!--使用Mybatis-generator插件不能使用太高版本的mysql驱动-->
            <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.44</version>
            </dependency>
          </dependencies>
          <configuration>
            <overwrite>true</overwrite>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

5. 添加相关配置文件

 5.1 ehcache.xml (添加到main\resources目录下)

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <!--磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存-->
    <!--path:指定在硬盘上存储对象的路径-->
    <!--java.io.tmpdir 是默认的临时文件路径。 可以通过如下方式打印出具体的文件路径 System.out.println(System.getProperty("java.io.tmpdir"));-->
    <diskStore path="java.io.tmpdir"/>


    <!--defaultCache:默认的管理策略-->
    <!--eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断-->
    <!--maxElementsInMemory:在内存中缓存的element的最大数目-->
    <!--overflowToDisk:如果内存中数据超过内存限制,是否要缓存到磁盘上-->
    <!--diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false-->
    <!--timeToIdleSeconds:对象空闲时间(单位:秒),指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问-->
    <!--timeToLiveSeconds:对象存活时间(单位:秒),指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问-->
    <!--memoryStoreEvictionPolicy:缓存的3 种清空策略-->
    <!--FIFO:first in first out (先进先出)-->
    <!--LFU:Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存-->
    <!--LRU:Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存-->
    <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
                  timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>


    <!--name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)-->
    <cache name="stuCache" eternal="false" maxElementsInMemory="100"
           overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
           timeToLiveSeconds="300" memoryStoreEvictionPolicy="LRU"/>
</ehcache>

 5.2 spring-ehcache.xml,shiro与ehcache整合(添加到main\resources目录下)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用ehcache缓存-->
    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml"/>
        <property name="shared" value="true"/>
    </bean>
    <!-- 默认是cacheManager -->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManager" ref="cacheManagerFactory"/>
    </bean>
</beans>
  • 同时也要导入到spring.xml文件中 
<import resource="spring-ehcache.xml"/>

 5.3 修改spring-shiro.xml文件,添加相关配置 (完整,可直接覆盖即可)

 需要修改创建会话监听器的位置到你自己的那里(资源在下方已提供)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置自定义的Realm-->

    <!--****************************** 需要修改01 ***************************************-->
    <bean id="shiroRealm" class="com.jmh.shiro.utils.Realm">
        <!--开启缓存-->
        <property name="cachingEnabled" value="true"/>
        <!--开启授权缓存-->
        <property name="authorizationCachingEnabled" value="true"/>
        <!--设置ehcache的中的缓存对象名-->
        <property name="authorizationCacheName" value="shiroAuthzCache"/>
        <!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 -->
        <!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 -->
        <!--注意:重要的事情说三次~~~~~~此处加密方式要与用户注册时的算法一致 -->
        <!--以下三个配置告诉shiro将如何对用户传来的明文密码进行加密-->
        <property name="credentialsMatcher">
            <bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!--指定hash算法为MD5-->
                <property name="hashAlgorithmName" value="md5"/>
                <!--指定散列次数为1024次-->
                <property name="hashIterations" value="1024"/>
                <!--true指定Hash散列值使用Hex加密存. false表明hash散列值用用Base64-encoded存储-->
                <property name="storedCredentialsHexEncoded" value="true"/>
            </bean>
        </property>
    </bean>

    <!--注册安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="shiroRealm" />
        <!--设置缓存管理器-->
        <property name="cacheManager" ref="cacheManager"/>
    </bean>

    <!--Shiro核心过滤器-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- Shiro的核心安全接口,这个属性是必须的 -->
        <property name="securityManager" ref="securityManager" />
        <!-- 身份验证失败,跳转到登录页面 -->
        <property name="loginUrl" value="/home/index.shtml"/>
        <!-- 身份验证成功,跳转到指定页面 -->
        <!--<property name="successUrl" value="/index.jsp"/>-->
        <!-- 权限验证失败,跳转到指定页面 -->
        <!--<property name="unauthorizedUrl" value="/user/noauthorizeUrl"/>-->
        <!-- Shiro连接约束配置,即过滤链的定义 -->
        <property name="filterChainDefinitions">
            <value>
                <!--
                注:anon,authcBasic,auchc,user是认证过滤器
                    perms,roles,ssl,rest,port是授权过滤器
                -->
                <!--anon 表示匿名访问,不需要认证以及授权-->
                <!--authc表示需要认证 没有进行身份认证是不能进行访问的-->
                <!--roles[admin]表示角色认证,必须是拥有admin角色的用户才行-->
                /user/login=anon
                /book/**=authc
                /common/**=authc
               <!-- /css/**               = anon
                /images/**            = anon
                /js/**                = anon
                /                     = anon
                /user/logout          = logout
                /user/**              = anon
                /userInfo/**          = authc
                /dict/**              = authc
                /console/**           = roles[admin]
                /**                   = anon-->
            </value>
        </property>
    </bean>

    <!-- Shiro生命周期,保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>

    <!--1)创建Session ID生成器-->
    <!-- Session ID 生成器 -->
    <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator">
    </bean>

    <!--2)自定义会话管理-->
    <!--sessionDao自定义会话管理,针对Session会话进行CRUD操作-->
    <bean id="customSessionDao" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO">
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
    </bean>

    <!--3)创建会话监听器-->
    <!--会话监听器-->
    <bean id="shiroSessionListener" class="com.jmh.shiro.utils.ShiroSessionListener"/>

    <!--4)会话cookie模板-->
    <!--会话cookie模板-->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <!--设置cookie的name-->
        <constructor-arg value="shiro.session"/>
        <!--设置cookie有效时间-->
        <property name="maxAge" value="-1"/>
        <!--设置httpOnly-->
        <property name="httpOnly" value="true"/>
    </bean>

    <!--5)SessionManager会话管理器-->
    <!--SessionManager会话管理器-->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!--设置session会话过期时间 毫秒 3分钟=180000-->
        <property name="globalSessionTimeout" value="180000"/>
        <!--设置sessionDao-->
        <property name="sessionDAO" ref="customSessionDao"/>
        <!--设置间隔多久检查一次session的有效性 默认60分钟-->
        <property name="sessionValidationInterval" value="1800000"/>
        <!--配置会话验证调度器-->
        <!--<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>-->
        <!--是否开启检测,默认开启-->
        <!--<property name="sessionValidationSchedulerEnabled" value="true"/>-->
        <!--是否删除无效的session,默认开启-->
        <property name="deleteInvalidSessions" value="true"/>
        <!--配置session监听器-->
        <property name="sessionListeners">
            <list>
                <ref bean="shiroSessionListener"/>
            </list>
        </property>
        <!--会话Cookie模板-->
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
        <!--取消URL后面的JSESSIONID-->
       <!-- <property name="sessionIdUrlRewritingEnabled" value="false"/>-->
    </bean>

</beans>
  •  ShiroSessionListener

package com.jmh.shiro.utils;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionListener;

/**
 *   SessionListener会话监听器用于监听会话创建、过期及停止事件。
 *   实现方式:
 *   1)实现SessionListener,必须实现所有方法
 *   2)继承SessionListenerAdapter,重写指定方法
 *     相关API:
 *   1)onStart(Session session):监听会话创建事件
 *   2)onStop(Session session):监听会话销毁事件
 *   3)onExpiration(Session session):监听会话过期事件
 */
public class ShiroSessionListener implements SessionListener {
    @Override
    public void onStart(Session session) {
        System.out.println("监听会话创建事件" + session.getId());
    }

    @Override
    public void onStop(Session session) {
        System.out.println("监听会话销毁事件" + session.getId());
    }

    @Override
    public void onExpiration(Session session) {
        System.out.println("监听会话过期事件" + session.getId());
    }
}

  注:这里只开启了授权缓存,避免每次请求都要重新查询授权数据!!! 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值