Shiro之保存Session到数据库中

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/yelllowcong/article/details/78863232
            </div>
                                                <!--一个博主专栏付费入口-->
                      <!--一个博主专栏付费入口结束-->
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-4a3473df85.css">
                                    <div id="content_views" class="markdown_views">
                <!-- flowchart 箭头图标 勿删 -->
                <svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
                    <path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
                </svg>
                                        <blockquote>

将Session统一存放到Mysql数据库中进行管理操作,这样我们就可以通过向操作数据库一样,对session进行操作和处理了。实现Session存储到数据库的大致步骤是,1、创建Session表;2、创建操作Session表的Mapper,3、创建继承EnterpriseCacheSessionDAO 的Dao,4、配置管理session的Dao到securityManager中,5、配置ecache配置。

源码地址

https://gitee.com/yellowcong/shior-dmeo/tree/master/test

环境架构

服务版本
数据库Mysql
缓存ehcache
框架Spring+SpringMVC+Mybatis

项目结构

这里写图片描述

添加SessionDao

数据库表设计

数据表设计中,我们可以自己在我的基础上,进行字段的扩展

CREATE TABLE `sys_session` (
  `id` varchar(200) NOT NULL COMMENT 'Sessoin的id',
  `session` varchar(2000) DEFAULT NULL COMMENT 'Session的序列化对象',
  `username` varchar(32) DEFAULT NULL COMMENT '用户名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述

SessionMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yellowcong.shiro.dao.SessionMapper">
  <resultMap id="Session" type="com.yellowcong.shiro.model.Session">
    <id column="id" jdbcType="VARCHAR" property="id" />
    <result column="session" jdbcType="VARCHAR" property="session" />
    <result column="username" jdbcType="VARCHAR" property="username" />
  </resultMap>

  <!-- 添加数据到session中 -->
  <insert id="insert" >
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.String">
      SELECT LAST_INSERT_ID()
    </selectKey>
    insert into sys_session (id,session)
    values (#{id,jdbcType=VARCHAR},#{session,jdbcType=VARCHAR})
  </insert>

  <!-- 根据id来删除session -->
  <delete id="delete" parameterType="java.lang.String">
    delete from sys_session where id = #{sessionid,jdbcType=VARCHAR}
  </delete>

  <!-- 更新session -->
  <update id="update" >
    update sys_session set 
        session = #{session,jdbcType=VARCHAR} 
        <if test="username != null">
         , username = #{username,jdbcType=VARCHAR} 
        </if>
    where id = #{id,jdbcType=VARCHAR} 
   </update>

   <!-- 获取session -->
   <select id="load" parameterType="java.lang.String" resultMap="Session">
    select * from sys_session where id = #{sessionid,jdbcType=VARCHAR}
  </select>

  <!-- 根据用户名来获取session -->
   <select id="loadByUserName" resultMap="Session">
    select * from sys_session where username = #{username,jdbcType=VARCHAR}
  </select>


</mapper>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

SessionMapper.java

package com.yellowcong.shiro.dao;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.yellowcong.shiro.model.Session;

/**
 * 创建日期:2017/12/21<br/>
 * 创建时间:8:44:22<br/>
 * 创建用户:yellowcong<br/>
 * 机能概要:
 */
public interface SessionMapper {

    /**
     * 创建日期:2017/12/21<br/>
     * 创建时间:8:44:54<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:插入session
     * 
     * @param session
     */
    public int insert(@Param("id") String id,@Param("session") String session);

    /**
     * 创建日期:2017/12/21<br/>
     * 创建时间:8:48:06<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:删除session
     * 
     * @param session
     * @return
     */
    public int delete(String  sessionid);

    /**
     * 
     * 创建日期:2017/12/21<br/>
     * 创建时间:8:48:23<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:删除session
     * 
     * @param session
     * @return
     */
    public int update(@Param("id") String id,@Param("session") String session,@Param("username") String username);

    /**
     * 创建日期:2017/12/21<br/>
     * 创建时间:8:49:13<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:通过sessionid来获取session数据
     * 
     * @param sessionid
     * @return
     */
    public Session load(String sessionid);

    /**
     * 创建日期:2017/12/21<br/>
     * 创建时间:11:52:02<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:根据用户名获取sesssion
     * @param username
     * @return
     */
    public List<Session> loadByUserName(@Param("username") String username);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

创建SessionDao,管理session

SessionDao需要继承EnterpriseCacheSessionDAO ,实现里面的抽象方法,同时,自己还添加了一个根据用户名来获取Session对象的方法。这个里面直接操作Session存储到数据库。

对于插入用户名,需要在update sessiond的地方做处理,不然获取不到用户名

package com.yellowcong.shiro.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.ValidatingSession;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.springframework.beans.factory.annotation.Autowired;

import com.yellowcong.shiro.utils.SerializableUtils;

/**
 * 创建日期:2017/12/21<br/>
 * 创建时间:8:31:04<br/>
 * 创建用户:yellowcong<br/>
 * 机能概要:用于Session的保存
 */
public class SessionDao extends EnterpriseCacheSessionDAO {

    @Autowired
    private SessionMapper sessionMapper;

    public void delete(Session session) {
        //删除session
        this.sessionMapper.delete(session.getId().toString());
    }

    public void update(Session session) throws UnknownSessionException {
        //当是ValidatingSession 无效的情况下,直接退出
        if(session instanceof ValidatingSession && 
                !((ValidatingSession)session).isValid() ) {
            return ;
        }

        //检索到用户名
        String username = String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY));

        //序列化Session
        this.sessionMapper.update(session.getId().toString(), SerializableUtils.serializ(session),username);
    }

    @Override
    protected Serializable doCreate(Session session) {
        //生成session的id
        Serializable sessionId = generateSessionId(session);
        //给Session设定id
        assignSessionId(session, sessionId);


        //插入session 到数据库
        this.sessionMapper.insert(session.getId().toString(), SerializableUtils.serializ(session));

        return sessionId;
    }

    /**
     * 创建日期:2017/12/21<br/>
     * 创建时间:13:56:15<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:通过名称来获取用户 Session
     * @param username
     * @return
     */
    public List<Session> loadByUserName(String username) {
        //获取session的字符串
        List<com.yellowcong.shiro.model.Session> dbSessions = this.sessionMapper.loadByUserName(username);

        //判断是否存在用户的情况
        if(dbSessions == null || dbSessions.size() == 0) {
            return null;
        }

        List<Session> result = new ArrayList<Session>();
        for(com.yellowcong.shiro.model.Session session:dbSessions) {
            //加载session数据
            String sessionStr = session.getSession();

            //将Session的数据串,转化为对象
            result.add(SerializableUtils.deserializ(sessionStr));
        }

        return result;
    }


    @Override
    protected Session doReadSession(Serializable sessionId) {
        //获取session的字符串
        com.yellowcong.shiro.model.Session dbSession = this.sessionMapper.load(sessionId.toString());
        if(dbSession == null) {
            return null;
        }

        //加载session数据
        String sessionStr = dbSession.getSession();
        return SerializableUtils.deserializ(sessionStr);
    }

}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

SerializableUtils

序列和反序列Session对象,只有将session对象序列化成字符串,才可以存储到Mysql上,不能直接存

package com.yellowcong.shiro.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Base64;

import org.apache.shiro.session.Session;

/**
 * 创建日期:2017/12/21<br/>
 * 创建时间:9:21:25<br/>
 * 创建用户:yellowcong<br/>
 * 机能概要:
 */
public class SerializableUtils {

    /**
     * 创建日期:2017/12/21<br/>
     * 创建时间:9:25:30<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:将Session序列化成String类型
     * @param session
     * @return
     */
    public static String serializ(Session session) {
        try {
            //ByteArrayOutputStream 用于存储序列化的Session对象
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            //将Object对象输出成byte数据
            ObjectOutputStream out = new ObjectOutputStream(bos);
            out.writeObject(session);

            //将字节码,编码成String类型数据
            return Base64.getEncoder().encodeToString(bos.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException("序列化失败");
        }
    }


    /**
     * 创建日期:2017/12/21<br/>
     * 创建时间:9:26:19<br/>
     * 创建用户:yellowcong<br/>
     * 机能概要:将一个Session的字符串序列化成字符串,反序列化
     * @param sessionStr
     * @return
     */
    public static Session deserializ(String sessionStr) {
        try {
            //读取字节码表
            ByteArrayInputStream bis  = new ByteArrayInputStream(Base64.getDecoder().decode(sessionStr));

            //将字节码反序列化成 对象
            ObjectInputStream in = new ObjectInputStream(bis);
            Session session = (Session) in.readObject();
            return session;
        } catch (Exception e) {
            throw new RuntimeException("反序列化失败");
        }
    }
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

配置spring-shiro.xml配置文件

注意这个sessionDao 里面配置了activeSessionsCacheName 这个属性,这个在ecache.xml里面必须也配置一个shiro-activeSessionCache节点,用于存激活的session,简单来讲,就是登录的用户。

<!-- 给予shior的内存缓存系统 ,这个是shiro的缓存服务-->
    <!-- <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />  
     --> 

    <!--  
         配置 CacheManager. 
    -->     
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/> 
    </bean>


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

    <!-- 创建SessionDao  这个SessionDao继承了 EnterpriseCacheSessionDAO-->
    <bean id="sessionDao" class="com.yellowcong.shiro.dao.SessionDao">
        <!-- 配置SessionDao里面的 id生成器 -->
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
        <!-- 设置Session缓存到Eacehc的名字,默认就是shiro-activeSessionCache -->
        <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
    </bean>

    <!-- 配置Session管理 -->           
    <!-- org.apache.shiro.session.mgt.DefaultSessionManager
    DefaultWebSessionManager 继承了 DefaultSessionManager 这个类
     -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- session超时 30 分钟 -->
        <property name="globalSessionTimeout" value="1800000"/>

        <property name="deleteInvalidSessions" value="true"/>

        <!-- Session调度器,用来检查Session是否还存在的问题 -->
        <property name="sessionValidationSchedulerEnabled" value="true"/>
        <!--  设定session的调度管理器-->
        <property name="sessionValidationScheduler" ref="sessionValidationScheduler" />
        <!-- 配置管理session的 dao -->
        <property name="sessionDAO" ref="sessionDao"/>

        <!-- 开启cookie 不然一直登录不上 -->
        <property name="sessionIdCookieEnabled" value="true"/>
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean>

    <!-- 全局的会话信息检测扫描信息间隔30分钟 
         设定检查sesion过期事件,
    -->
    <bean id="sessionValidationScheduler"
        class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
        <property name="sessionValidationInterval" value="1800000" />
        <property name="sessionManager" ref="sessionManager" />
    </bean>

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

        <!-- 验证 -->        
        <property name="authenticator" ref="authenticator"/>

        <!-- 多个验证策略 realmes -->
        <property name="realms">
            <list>
                <!-- 这个认证,有一个先后的顺序 -->
                <ref bean="sampleRealm1"/>
                <ref bean="sampleRealm2"/>
            </list>
        </property>

        <!-- 配置SessionManager -->
      <property name="sessionManager" ref="sessionManager"/> 
    </bean> 
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
下面是完整配置

其中还有一部分是关于Shiro生命周期的,存储在了Spring-mvc中,因为生命周期配置在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" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <description>== Shiro Components ==</description>

    <!-- 给予shior的内存缓存系统 ,这个是shiro的缓存服务-->
    <!-- <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />  
     --> 

    <!--  
         配置 CacheManager. 
    -->     
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/> 
    </bean>


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

    <!-- 创建SessionDao  这个SessionDao继承了 EnterpriseCacheSessionDAO-->
    <bean id="sessionDao" class="com.yellowcong.shiro.dao.SessionDao">
        <!-- 配置SessionDao里面的 id生成器 -->
        <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
        <!-- 设置Session缓存到Eacehc的名字,默认就是shiro-activeSessionCache -->
        <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
    </bean>

    <!-- 配置Session管理 -->           
    <!-- org.apache.shiro.session.mgt.DefaultSessionManager
    DefaultWebSessionManager 继承了 DefaultSessionManager 这个类
     -->
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <!-- session超时 30 分钟 -->
        <property name="globalSessionTimeout" value="1800000"/>

        <property name="deleteInvalidSessions" value="true"/>

        <!-- Session调度器,用来检查Session是否还存在的问题 -->
        <property name="sessionValidationSchedulerEnabled" value="true"/>
        <!--  设定session的调度管理器-->
        <property name="sessionValidationScheduler" ref="sessionValidationScheduler" />
        <!-- 配置管理session的 dao -->
        <property name="sessionDAO" ref="sessionDao"/>

        <!-- 开启cookie 不然一直登录不上 -->
        <property name="sessionIdCookieEnabled" value="true"/>
        <property name="sessionIdCookie" ref="sessionIdCookie"/>
    </bean>

    <!-- 全局的会话信息检测扫描信息间隔30分钟 
         设定检查sesion过期事件,
    -->
    <bean id="sessionValidationScheduler"
        class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
        <property name="sessionValidationInterval" value="1800000" />
        <property name="sessionManager" ref="sessionManager" />
    </bean>

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

        <!-- 验证 -->        
        <property name="authenticator" ref="authenticator"/>

        <!-- 多个验证策略 realmes -->
        <property name="realms">
            <list>
                <!-- 这个认证,有一个先后的顺序 -->
                <ref bean="sampleRealm1"/>
                <ref bean="sampleRealm2"/>
            </list>
        </property>

        <!-- 配置SessionManager -->
      <property name="sessionManager" ref="sessionManager"/> 
    </bean>  


    <!-- 会话Cookie模板 -->
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
        <constructor-arg value="sid"/>
        <property name="httpOnly" value="true"/>
        <property name="maxAge" value="-1"/>
    </bean>

    <!-- 授权策略 -->
    <bean id="authenticator" class="org.apache.shiro.authc.pam.ModularRealmAuthenticator">
        <property name="authenticationStrategy" >
            <!-- 所有Reaml都全部匹配的策略 -->
            <!-- <bean class="org.apache.shiro.authc.pam.AllSuccessfulStrategy"/> -->
            <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"/>
        </property>
    </bean>

    <!-- 授权 认证 ,自己定义的,领域(Realm),shiro需要配置一个领域(Realm),以便我们可以访问用户-->
    <bean id="sampleRealm1" class=" com.yellowcong.shiro.realm.SampleRealm" >

        <!-- 如果不加入密码匹配的操作,密码就不会存在 -->
        <!-- 加入了密码匹配器之后,就会默认将前台传递过来的密码自动MD5加密 -->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!-- 加密的方式 -->
                <constructor-arg index="0" type="java.lang.String" value="MD5" />
                <!-- 加密的次数,默认是1次 -->
                <property name="hashIterations" value="1"/>
            </bean>
        </property>
    </bean>


    <!-- 授权 认证 ,自己定义的,领域(Realm),shiro需要配置一个领域(Realm),以便我们可以访问用户-->
    <bean id="sampleRealm2" class=" com.yellowcong.shiro.realm.SampleRealm2" >

        <!-- 如果不加入密码匹配的操作,密码就不会存在 -->
        <!-- 加入了密码匹配器之后,就会默认将前台传递过来的密码自动SHA1加密 -->
        <property name="credentialsMatcher">
            <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
                <!-- 加密的方式 -->
                <constructor-arg index="0" type="java.lang.String" value="SHA1" />
                <!-- 加密的次数,默认是1次 -->
                <property name="hashIterations" value="1"/>
            </bean>
        </property>
    </bean>

    <!-- Shior的过滤器配置 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
       <property name="securityManager" ref="securityManager" />  
       <!-- 用户登录地址 -->
       <property name="loginUrl" value="/user/login" />  
       <!-- 登录成功 -->
       <property name="successUrl" value="/user/list" />  
       <!-- 未授权的钦奎光 -->
       <property name="unauthorizedUrl" value="/user/error" />  

       <!-- 通过工厂模式,获取数据库里面 权限配置-->
       <property name="filterChainDefinitionMap" ref="filterChainDefinitionMap"/>
   </bean> 

   <!-- 获取Bean里面的Map集合 -->
   <bean id="filterChainDefinitionMap" factory-bean="filterChainDefinitionsMapBuilder" factory-method="loadFilterChainDefinitions"/>

   <!-- 读取初始自定义权限内容-->
   <bean id="filterChainDefinitionsMapBuilder" class="com.yellowcong.shiro.filter.FilterChainDefinitionsMapBuilder" />
</beans>

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
spring-mvc.xml的shiro配置
 <!-- Shiro生命周期处理器-->
   <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

    <!-- AOP式方法级权限检查 -->  
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"  
        depends-on="lifecycleBeanPostProcessor">  
        <property name="proxyTargetClass" value="true" />  
    </bean>  

    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
        <property name="securityManager" ref="securityManager" />  
    </bean>     
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里写图片描述

配置ecache

这个地方,必须添加一个shiro-activeSessionCache 的配置,不然就缓存不到session的数据了。

<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by
         its value in the running VM.

         The following properties are translated:
         user.home - User's home directory
         user.dir - User's current working directory
         java.io.tmpdir - Default temp file path -->
    <diskStore path="java.io.tmpdir"/>

    <cache name="authorizationCache"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="authenticationCache"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <cache name="shiro-activeSessionCache"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>

    <!--Default Cache configuration. These will applied to caches programmatically created through
        the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <!--Predefined caches.  Add your cache configuration settings here.
        If you do not have a configuration for your cache a WARNING will be issued when the
        CacheManager starts

        The following attributes are required for defaultCache:

        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->

    <!-- Sample cache named sampleCache1
        This cache contains a maximum in memory of 10000 elements, and will expire
        an element if it is idle for more than 5 minutes and lives for more than
        10 minutes.

        If there are more than 10000 elements it will overflow to the
        disk cache, which in this configuration will go to wherever java.io.tmp is
        defined on your system. On a standard Linux system this will be /tmp"
        -->
  <!--   <cache name="sampleCache1"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />
 -->
    <!-- Sample cache named sampleCache2
        This cache contains 1000 elements. Elements will always be held in memory.
        They are not expired. -->

    <!-- Place configuration for your caches following -->

</ehcache>

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105

测试登录

这里写图片描述

参考文章

http://blog.csdn.net/qq_32347977/article/details/51084480
http://blog.csdn.net/lhacker/article/details/20444295
http://blog.csdn.net/lhacker/article/details/19340757

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值