shiro+redis+springMvc整合配置及说明

技术背景:shiro安全框架,redis作缓存,再整合spring。

1、配置web.xml

[java]  view plain  copy
  1. <filter>  
  2.     <filter-name>ShiroFilter</filter-name>  
  3.     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  4. </filter>  
  5.   
  6. <filter-mapping>  
  7.     <filter-name>ShiroFilter</filter-name>  
  8.     <url-pattern>/*</url-pattern>  
  9. </filter-mapping>  
2、配置spring-shiro.xml的配置文件
[java]  view plain  copy
  1.     <!--shiro配置-->   
  2.     <!--securityManager是shiro核心部分-->  
  3.     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
  4.          <property name="sessionManager" ref="webSessionManager" />  
  5.          <property name="realm" ref="restfulAuthRealm"/>  
  6.          <property name="rememberMeManager.cookie.name" value="rememberMe"/>  
  7.          <property name="rememberMeManager.cookie.maxAge" value="${rememberMeManager.cookie.maxAge}"/>  
  8.     </bean>  
  9.     <!--配置shiro的sessionManager-->  
  10.     <bean id="webSessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">  
  11.          <property name="sessionDAO" ref="redisSessionDAO"></property>  
  12.     </bean>  
  13.     <!--权限操作bean-->  
  14.     <bean id="permissionManager" class="com.securityframework.local.PermissionManagerLocalImpl" />  
  15.     <!--账号操作bean-->  
  16.     <bean id="accountManagerImpl" class="com.securityframework.local.AccountManagerLocalImpl"/>  
  17.     <!--自定义realm-->  
  18.     <bean id ="restfulAuthRealm" class="com.isoftstone.securityframework.restful.client.web.shiro.realm.RestAuthRealm">  
  19.         <property name="accountManagerImpl" ref="accountManagerImpl"></property>  
  20.         <property name="permissionManagerImpl" ref="permissionManager"></property>  
  21.         <property name="cacheManager" ref="redisCacheManager"></property>  
  22.             <property name="platformLabel">  
  23.          <value>${platformLabel}</value>  
  24.         </property>  
  25.      </bean>       
  26.      <!--动态获取filterchaindefinitions,此处与下面ShiroFilter bean所引用的类对应-->  
  27.      <bean id="systemUrlChainManager" class="com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager">  
  28.           <property name="permissionManager" ref="permissionManager"></property>  
  29.          <property name="platformLabel">  
  30.              <value>${platformLabel}</value>  
  31.          </property>  
  32.         <property name="systemLabel">  
  33.             <value>${systemLabel}</value>  
  34.         </property>  
  35.       </bean>  
  36.       <!--与web.xml中配置的filter同名,它对应的类原本是<code class="xml string">org.apache.shiro.spring.web.ShiroFilterFactoryBean,</code>-->  
  37.       <!--这里为了动态获取filterchaindefinitions改写了<code class="xml string">ShiroFilterFactoryBean类,它们的作用是一样的</code>-->   
  38.       <bean id="ShiroFilter" class="com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter">  
  39.         <property name="urlChainManager" ref="systemUrlChainManager" />  
  40.         <property name="securityManager" ref="securityManager"/>  
  41.         <property name="loginUrl" value="../../res/user/login.html"/>  
  42.         <property name="unauthorizedUrl" value="/html/413.html"/>  
  43.         <property name="filters">  
  44.             <util:map>  
  45.                 <entry key="authc">  
  46.                     <bean class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter"/>  
  47.                 </entry>  
  48.             </util:map>  
  49.         </property>                        
  50.         <property name="filterChainDefinitions">  
  51.             <value>  
  52.                 /images/** =anon  
  53.                 /help/** =anon  
  54.                 /css/** = anon  
  55.                 /easyui/** =anon  
  56.                 /javascript/** =anon  
  57.                 /commons/** =anon  
  58.                 /jsplugin/** =anon  
  59.                 /ueditor/** =anon  
  60.                 /html/** =anon                
  61.                 /index.html = anon  
  62.                 / = anon  
  63.                 /** = user  
  64.             </value>  
  65.          </property>  
  66.     </bean>  
  67. <span><span class="comments">    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --></span><span></span></span>  
  68. <pre name="code" class="java">    <bean id="lifecycleBeanPostProcessor"   class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>   
  69.        
  70.      <!--redis配置-->  
<!-- basic jedis pool configuration -->
    <bean id="basicPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxActive" value="${redis.pool.maxActive}" />  
        <property name="maxIdle" value="${redis.pool.maxIdle}" />  
        <property name="maxWait" value="${redis.pool.maxWaitTime}" />  
        <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />  
    </bean>
    <!-- JedisPool  configuration-->
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">  
        <constructor-arg index="0" ref="basicPoolConfig" />  
        <constructor-arg index="1" value="${redis.host.ip}" />  
        <constructor-arg index="2" value="${redis.host.port}" />  
    </bean>  
    <!-- JedisPool manager -->
    <bean id="jedisPoolManager" class="com.isoftstone.securityframework.support.redis.JedisPoolManager">
        <property name="jedisPool" ref="jedisPool"></property>
    </bean>
    <!--redisCacheManager要实现org.apache.shiro.cache.CacheManager接口,让shiro使用redis的缓存-->
    <bean id="redisCacheManager" class="com.securityframework.support.redis.RedisCacheManager">
        <property name="redisManager" ref="jedisPoolManager"></property>
    </bean>
    <!-- Redis session dao -->
<!--redisSessionDAO继承实现了org.apache.shiro.session.mgt.eis.SessionDAO的AbstractSessionDAO-->
    <bean id="redisSessionDAO" class="com.securityframework.support.redis.RedisSessionDAO">
        <property name="redisManager" ref="jedisPoolManager"></property>
        <property name="expire" value="${shiro.session.timeout}"></property>
    </bean>
3、上述bean对应的类(我们自己重写的)
  • com.securityframework.local.PermissionManagerLocalImpl
  • com.securityframework.local.AccountManagerLocalImpl
  • com.securityframework.restful.client.web.shiro.realm.RestAuthRealm
  • com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager
  • com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter
  • com.securityframework.support.redis.JedisPoolManager
  • com.securityframework.support.redis.RedisCacheManager
  • com.securityframework.support.redis.RedisSessionDAO

     (1)com.securityframework.local.PermissionManagerLocalImpl

         对权限信息的增删改查

     (2)com.securityframework.local.AccountManagerLocalImpl

         对账号信息的增删改查

     (3)com.securityframework.restful.client.web.shiro.realm.RestAuthRealm

         在shiro学习和使用实例(2)——登陆认证和授权有详细解释

     (4)com.securityframework.restful.client.web.shiro.mgt.RestUrlChainManager        

[java]  view plain  copy
  1. public class RestUrlChainManager {  
  2.     PermissionManager permissionManager;   
  3.       
  4.     private String platformLabel ;  
  5.       
  6.     private String systemLabel;  
  7.       
  8.     public Map<String,String> buildChainMap(){  
  9.           
  10.         Map<String,String> p = new HashMap<String,String>();  
  11.         //获取权限信息,以便获得每个权限下面的资源  
  12.         List<com.isoftstone.securityframework.api.Permission> perms = permissionManager.findSubsystemPermission(platformLabel, systemLabel);  
  13.           
  14.         if(null != perms && perms.size() > 0){  
  15.             System.out.println(" SystemUrlChainManager.buildChainMap----- STATUS_OK -----");  
  16.         }  
  17.         if (null != perms){  
  18.             String value ;  
  19.             for (int i = 0; i < perms.size(); i++) {  
  20.                 value = "";  
  21.                 com.isoftstone.securityframework.api.Permission perm = perms.get(i);  
  22.                 if(i == 0){  
  23.                     value = "authc," + perm.getPermissionName();  
  24.                 }else{  
  25.                     value = perm.getPermissionName();  
  26.                 }  
  27.                 List<com.isoftstone.securityframework.api.Resource> resources = perm.getResources();  
  28.                   
  29.                 if(null != resources){  
  30.                     for (int j = 0; j < resources.size(); j++) {  
  31.                         com.isoftstone.securityframework.api.Resource resource = resources.get(j);  
  32.                                                 //格式{'mvc/web/usermgt/add.json','perms[com.securitycenter.user:ADD]'},它  
  33.                                                 //对应spring-shiro.xml配置文件中ShiroFilter bean下的filterChainDefinitions  
  34.                                                 p.put(resource.getRes(), String.format("perms[%s]", value));  
  35.                     }  
  36.                 }  
  37.             }  
  38.         }  
  39.         return p;  
  40.     }  
  41.   
  42.         /** 
  43.          *  setter和getter方法省略 
  44.          **/  
  45.  }  
      RestUrlChainManager类中的buildChainMap方法是从数据库获取资源,组成动态的filterChainDefinitions,以便系统对所有的资源请求的拦截都可以动态可配置

     (5)com.securityframework.restful.client.web.shiro.filter.RestAuthShiroFilter

[java]  view plain  copy
  1. public Map<String,String> getChainFilterMap(){  
  2.         return getUrlChainManager().buildChainMap();  
  3.     }  
  4. public void setFilterChainDefinitionMap(Map<String, String> filterChainDefinitionMap) {  
  5.         Map<String, String> allFilterChainDefinitionMap = getFilterChainDefinitionMap();  
  6.         if (CollectionUtils.isEmpty(allFilterChainDefinitionMap)){  
  7.             this.filterChainDefinitionMap = filterChainDefinitionMap;  
  8.         }else{  
  9.             //add custom chain definition  
  10.             allFilterChainDefinitionMap.putAll(filterChainDefinitionMap);  
  11.         }  
  12.                   
  13.     }  
  14. public void setFilterChainDefinitions(String definitions) {  
  15.         Ini ini = new Ini();  
  16.         ini.load(definitions);  
  17.         //did they explicitly state a 'urls' section?  Not necessary, but just in case:  
  18.         Ini.Section section = ini.getSection(IniFilterChainResolverFactory.URLS);  
  19.         if (CollectionUtils.isEmpty(section)) {  
  20.             //no urls section.  Since this _is_ a urls chain definition property, just assume the  
  21.             //default section contains only the definitions:  
  22.             section = ini.getSection(Ini.DEFAULT_SECTION_NAME);  
  23.         }  
  24.         setFilterChainDefinitionMap(section);  
  25.           
  26.         //add custom path filter map   
  27.         try{  
  28.             Map<String,String> permFilterMap = this.getChainFilterMap();  
  29.             if(!CollectionUtils.isEmpty(permFilterMap)){  
  30.                 setFilterChainDefinitionMap(permFilterMap);  
  31.             }  
  32.         }catch(Exception ex){  
  33.             log.error("Load custom path filters to shiro filter failure.");  
  34.             ex.printStackTrace();  
  35.         }  
  36.           
  37.     }  
      RestAuthShiroFilter其实就是使用的 org.apache.shiro.spring.web.ShiroFilterFactoryBean ,里面的方法完全一样,只是为了动态获取filterChainDefinitions在 ShiroFilterFactoryBean 类的基础上,增改了上述三个方法。实现的目的就是将RestUrlChainManager组装的{资源,权限}map加入到filterChainDefinitions中,实现拦截。从而能够动态的维护shiro拦截器拦截的内容。

     (6)com.securityframework.support.redis.JedisPoolManager

[java]  view plain  copy
  1. /** 
  2.  * JedisPool 管理类  
  3.  * 用于单个redis 集群, 每个redis集群由master-salve组成 
  4.  */  
  5. public class JedisPoolManager {  
  6.   
  7.     private static Log log = LogFactory.getLog(JedisPoolManager.class);  
  8.   
  9.     private JedisPool jedisPool;  
  10.     /** 
  11.      * redis的List集合 ,向key这个list添加元素 
  12.      */  
  13.     public long rpush(String key, String string) {  
  14.         Jedis jedis = null;  
  15.         try {  
  16.             jedis = jedisPool.getResource();  
  17.             long ret = jedis.rpush(key, string);  
  18.             jedisPool.returnResource(jedis);  
  19.             return ret;  
  20.         } catch (Exception e) {  
  21.             log.error(e);  
  22.             if (jedis != null) {  
  23.                 jedisPool.returnBrokenResource(jedis);  
  24.             }  
  25.             throw new JedisException(e);  
  26.         }  
  27.     }  
  28.     /** 
  29.      * 获取key这个List,从第几个元素到第几个元素 LRANGE key start 
  30.      * stop返回列表key中指定区间内的元素,区间以偏移量start和stop指定。 
  31.      * 下标(index)参数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。 
  32.      * 也可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。 
  33.      */  
  34.     public List<String> lrange(String key, long start, long end) {  
  35.         Jedis jedis = null;  
  36.         try {  
  37.             jedis = jedisPool.getResource();  
  38.             List<String> ret = jedis.lrange(key, start, end);  
  39.             jedisPool.returnResource(jedis);  
  40.             return ret;  
  41.         } catch (Exception e) {  
  42.             log.error(e);  
  43.             if (jedis != null) {  
  44.                 jedisPool.returnBrokenResource(jedis);  
  45.             }  
  46.             throw new JedisException(e);  
  47.         }  
  48.     }  
  49.     /** 
  50.      * 将哈希表key中的域field的值设为value。 
  51.      */  
  52.     public void hset(String key, String field, String value) {  
  53.         Jedis jedis = null;  
  54.         try {  
  55.             jedis = jedisPool.getResource();  
  56.             jedis.hset(key, field, value);  
  57.             jedisPool.returnResource(jedis);  
  58.         } catch (Exception e) {  
  59.             log.error(e);  
  60.             if (jedis != null) {  
  61.                 jedisPool.returnBrokenResource(jedis);  
  62.             }  
  63.             throw new JedisException(e);  
  64.         }  
  65.     }  
  66.     /** 
  67.      * 向key赋值 
  68.      */  
  69.     public void set(String key, String value) {  
  70.         Jedis jedis = null;  
  71.         try {  
  72.             jedis = jedisPool.getResource();  
  73.             jedis.set(key, value);  
  74.             jedisPool.returnResource(jedis);  
  75.         } catch (Exception e) {  
  76.             log.error(e);  
  77.             if (jedis != null) {  
  78.                 jedisPool.returnBrokenResource(jedis);  
  79.             }  
  80.             throw new JedisException(e);  
  81.         }  
  82.     }  
  83.     /** 
  84.      * 向key赋值 
  85.      */  
  86.     public void set(byte[] key, byte[] value) {  
  87.         Jedis jedis = null;  
  88.         try {  
  89.             jedis = jedisPool.getResource();  
  90.             jedis.set(key, value);  
  91.             jedisPool.returnResource(jedis);  
  92.         } catch (Exception e) {  
  93.             log.error(e);  
  94.             if (jedis != null) {  
  95.                 jedisPool.returnBrokenResource(jedis);  
  96.             }  
  97.             throw new JedisException(e);  
  98.         }  
  99.     }  
  100.     /** 
  101.      * 获取key的值 
  102.      */  
  103.     public String get(String key) {  
  104.         Jedis jedis = null;  
  105.         try {  
  106.             jedis = jedisPool.getResource();  
  107.             String value = jedis.get(key);  
  108.             jedisPool.returnResource(jedis);  
  109.             return value;  
  110.         } catch (Exception e) {  
  111.             log.error(e);  
  112.             if (jedis != null) {  
  113.                 jedisPool.returnBrokenResource(jedis);  
  114.             }  
  115.             throw new JedisException(e);  
  116.         }  
  117.     }  
  118.     /** 
  119.      * 获取key的值 
  120.      */  
  121.     public byte[] get(byte[] key) {  
  122.         Jedis jedis = null;  
  123.         try {  
  124.             jedis = jedisPool.getResource();  
  125.             byte[] value = jedis.get(key);  
  126.             jedisPool.returnResource(jedis);  
  127.             return value;  
  128.         } catch (Exception e) {  
  129.             log.error(e);  
  130.             if (jedis != null) {  
  131.                 jedisPool.returnBrokenResource(jedis);  
  132.             }  
  133.             throw new JedisException(e);  
  134.         }  
  135.   
  136.     }  
  137.     /** 
  138.      * 将多个field - value(域-值)对设置到哈希表key中。 
  139.      */  
  140.     public void hmset(String key, Map<String, String> map) {  
  141.         Jedis jedis = null;  
  142.         try {  
  143.              jedis = jedisPool.getResource();  
  144.             jedis.hmset(key, map);  
  145.             jedisPool.returnResource(jedis);  
  146.         } catch (Exception e) {  
  147.             log.error(e);  
  148.             if (jedis != null) {  
  149.                 jedisPool.returnBrokenResource(jedis);  
  150.             }  
  151.             throw new JedisException(e);  
  152.         }  
  153.     }  
  154.     /** 
  155.       * 给key赋值,并生命周期设置为seconds 
  156.      */  
  157.     public void setex(String key, int seconds, String value) {  
  158.         Jedis jedis = null;  
  159.         try {  
  160.              jedis = jedisPool.getResource();  
  161.             jedis.setex(key, seconds, value);  
  162.             jedisPool.returnResource(jedis);  
  163.          } catch (Exception e) {  
  164.             log.error(e);  
  165.             if (jedis != null) {  
  166.                 jedisPool.returnBrokenResource(jedis);  
  167.             }  
  168.             throw new JedisException(e);  
  169.         }  
  170.     }  
  171.     /** 
  172.      * 给key赋值,并生命周期设置为seconds 
  173.      */  
  174.     public byte[] setex(byte[] key, byte[] value, int seconds) {  
  175.         Jedis jedis = null;  
  176.         try {  
  177.              jedis = jedisPool.getResource();  
  178.             jedis.setex(key, seconds, value);  
  179.             jedisPool.returnResource(jedis);  
  180.             return value;  
  181.         } catch (Exception e) {  
  182.             log.error(e);  
  183.             if (jedis != null) {  
  184.                 jedisPool.returnBrokenResource(jedis);  
  185.             }  
  186.             throw new JedisException(e);  
  187.         }  
  188.           
  189.   
  190.     }  
  191.     /** 
  192.      * 为给定key设置生命周期 
  193.      */  
  194.     public void expire(String key, int seconds) {  
  195.         Jedis jedis = null;  
  196.         try {  
  197.              jedis = jedisPool.getResource();  
  198.             jedis.expire(key, seconds);  
  199.             jedisPool.returnResource(jedis);  
  200.         } catch (Exception e) {  
  201.             log.error(e);  
  202.             if (jedis != null) {  
  203.                 jedisPool.returnBrokenResource(jedis);  
  204.             }  
  205.              throw new JedisException(e);  
  206.         }  
  207.     }  
  208.     /** 
  209.      * 检查key是否存在 
  210.      */  
  211.     public boolean exists(String key) {  
  212.         Jedis jedis = null;  
  213.         try {  
  214.             jedis = jedisPool.getResource();  
  215.             boolean bool = jedis.exists(key);  
  216.             jedisPool.returnResource(jedis);  
  217.             return bool;  
  218.         } catch (Exception e) {  
  219.             log.error(e);  
  220.             if (jedis != null) {  
  221.                 jedisPool.returnBrokenResource(jedis);  
  222.             }  
  223.             throw new JedisException(e);  
  224.         }  
  225.     }  
  226.         /** 
  227.      * 检查key是否存在 
  228.      */  
  229.     public boolean exists(byte[] key) {  
  230.         Jedis jedis = null;  
  231.         try {  
  232.             jedis = jedisPool.getResource();  
  233.             Set<byte[]> hashSet = jedis.keys(key);  
  234.             jedisPool.returnResource(jedis);  
  235.             if (null != hashSet && hashSet.size() >0 ){  
  236.                 return true;  
  237.             }else{  
  238.                 return false;  
  239.             }  
  240.   
  241.         } catch (Exception e) {  
  242.              log.error(e);  
  243.             if (jedis != null) {  
  244.                 jedisPool.returnBrokenResource(jedis);  
  245.             }  
  246.             throw new JedisException(e);  
  247.         }  
  248.     }  
  249.     /** 
  250.      * 返回key值的类型 none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表) 
  251.      */  
  252.     public String type(String key) {  
  253.         Jedis jedis = null;  
  254.         try {  
  255.             jedis = jedisPool.getResource();  
  256.             String type = jedis.type(key);  
  257.             jedisPool.returnResource(jedis);  
  258.             return type;  
  259.         } catch (Exception e) {  
  260.             log.error(e);  
  261.             if (jedis != null) {  
  262.                 jedisPool.returnBrokenResource(jedis);  
  263.             }  
  264.             throw new JedisException(e);  
  265.         }  
  266.     }  
  267.     /** 
  268.      * 从哈希表key中获取field的value 
  269.      */  
  270.     public String hget(String key, String field) {  
  271.         Jedis jedis = null;  
  272.         try {  
  273.              jedis = jedisPool.getResource();  
  274.             String value = jedis.hget(key, field);  
  275.             jedisPool.returnResource(jedis);  
  276.             return value;  
  277.         } catch (Exception e) {  
  278.             log.error(e);  
  279.             if (jedis != null) {  
  280.                 jedisPool.returnBrokenResource(jedis);  
  281.             }  
  282.             throw new JedisException(e);  
  283.         }  
  284.     }  
  285.     /** 
  286.      * 返回哈希表key中,所有的域和值 
  287.      */  
  288.     public Map<String, String> hgetAll(String key) {  
  289.         Jedis jedis = null;  
  290.         try {  
  291.              jedis = jedisPool.getResource();  
  292.             Map<String, String> map = jedis.hgetAll(key);  
  293.             jedisPool.returnResource(jedis);  
  294.             return map;  
  295.         } catch (Exception e) {  
  296.              log.error(e);  
  297.             if (jedis != null) {  
  298.                 jedisPool.returnBrokenResource(jedis);  
  299.             }  
  300.             throw new JedisException(e);  
  301.         }  
  302.   
  303.     }  
  304.     /** 
  305.      * 返回哈希表key中,所有的域和值 
  306.      */  
  307.     public Set<?> smembers(String key) {  
  308.         Jedis jedis = null;  
  309.         try {  
  310.             jedis = jedisPool.getResource();  
  311.              Set<?> set = jedis.smembers(key);  
  312.             jedisPool.returnResource(jedis);  
  313.             return set;  
  314.         } catch (Exception e) {  
  315.             log.error(e);  
  316.             if (jedis != null) {  
  317.                 jedisPool.returnBrokenResource(jedis);  
  318.             }  
  319.              throw new JedisException(e);  
  320.         }  
  321.     }     
  322.     /** 
  323.      * 返回匹配的 keys 列表 
  324.      */  
  325.      public Set<byte[]> keys(String pattern) {  
  326.         Jedis jedis = null;  
  327.         try {  
  328.             jedis = jedisPool.getResource();  
  329.             Set<byte[]> keys = jedis.keys(pattern.getBytes());  
  330.             jedisPool.returnResource(jedis);  
  331.             return keys;  
  332.         } catch (Exception e) {  
  333.             log.error(e);  
  334.             if (jedis != null) {  
  335.                 jedisPool.returnBrokenResource(jedis);  
  336.             }  
  337.             throw new JedisException(e);  
  338.         }  
  339.   
  340.     }  
  341.     /** 
  342.      * 移除set集合中的member元素 
  343.      */  
  344.     public void delSetObj(String key, String field) {  
  345.         Jedis jedis = null;  
  346.         try {  
  347.             jedis = jedisPool.getResource();  
  348.             jedis.srem(key, field);  
  349.             jedisPool.returnResource(jedis);  
  350.         } catch (Exception e) {  
  351.             log.error(e);  
  352.             if (jedis != null) {  
  353.                 jedisPool.returnBrokenResource(jedis);  
  354.             }  
  355.             throw new JedisException(e);  
  356.         }  
  357.     }  
  358.     /** 
  359.      * 删除元素 
  360.      */  
  361.     public void del(byte[] key) {  
  362.          Jedis jedis = null;  
  363.         try {  
  364.             jedis = jedisPool.getResource();  
  365.             jedis.del(key);  
  366.             jedisPool.returnResource(jedis);  
  367.         } catch (Exception e) {  
  368.             log.error(e);  
  369.             if (jedis != null) {  
  370.                 jedisPool.returnBrokenResource(jedis);  
  371.             }  
  372.             throw new JedisException(e);  
  373.         }  
  374.     }  
  375.     /** 
  376.      * 判断member元素是否是集合key的成员。是(true),否则(false) 
  377.      */  
  378.     public boolean isNotField(String key, String field) {  
  379.         Jedis jedis = null;  
  380.         try {  
  381.             jedis = jedisPool.getResource();  
  382.              boolean bool = jedis.sismember(key, field);  
  383.             jedisPool.returnResource(jedis);  
  384.              return bool;  
  385.         } catch (Exception e) {  
  386.              log.error(e);  
  387.             if (jedis != null) {  
  388.                 jedisPool.returnBrokenResource(jedis);  
  389.             }  
  390.             throw new JedisException(e);  
  391.         }  
  392.     }  
  393.     /** 
  394.      * 如果key已经存在并且是一个字符串,将value追加到key原来的值之后 
  395.      */  
  396.     public void append(String key, String value) {  
  397.         Jedis jedis = null;  
  398.         try {  
  399.             jedis = jedisPool.getResource();  
  400.             jedis.append(key, value);  
  401.             jedisPool.returnResource(jedis);  
  402.         } catch (Exception e) {  
  403.             log.error(e);  
  404.             if (jedis != null) {  
  405.                 jedisPool.returnBrokenResource(jedis);  
  406.             }  
  407.             throw new JedisException(e);  
  408.         }  
  409.     }  
  410.     /** 
  411.      * 清空当前的redis 库 
  412.      */  
  413.     public void flushDB() {  
  414.         Jedis jedis = null;  
  415.         try {  
  416.             jedis = jedisPool.getResource();  
  417.             jedis.flushDB();  
  418.             jedisPool.returnResource(jedis);  
  419.         } catch (Exception e) {  
  420.             log.error(e);  
  421.             if (jedis != null) {  
  422.                 jedisPool.returnBrokenResource(jedis);  
  423.             }  
  424.             throw new JedisException(e);  
  425.         }  
  426.   
  427.      }  
  428.     /** 
  429.      * 返回当前redis库所存储数据的大小 
  430.      */  
  431.     public Long dbSize() {  
  432.           
  433.         Long dbSize = 0L;  
  434.           
  435.         Jedis jedis = null;  
  436.         try {  
  437.             jedis = jedisPool.getResource();  
  438.              jedis.dbSize();  
  439.             jedisPool.returnResource(jedis);  
  440.             return dbSize;  
  441.         } catch (Exception e) {  
  442.             log.error(e);  
  443.             if (jedis != null) {  
  444.                 jedisPool.returnBrokenResource(jedis);  
  445.             }  
  446.             throw new JedisException(e);  
  447.         }  
  448.   
  449.     }  
  450.     /** 
  451.      * 关闭 Redis 
  452.      */  
  453.     public void destory() {  
  454.         jedisPool.destroy();  
  455.     }  
  456.   
  457.        public JedisPool getJedisPool() {  
  458.         return jedisPool;  
  459.     }  
  460.     public void setJedisPool(JedisPool jedisPool) {  
  461.         this.jedisPool = jedisPool;  
  462.     }  
  463. }  
JedisPool 管理类 ,对redis的java客户端jedis的封装

     (7)com.securityframework.support.redis.RedisCacheManager

[java]  view plain  copy
  1. public class RedisCacheManager implements CacheManager {  
  2.   
  3.     private static final Logger logger = LoggerFactory.getLogger(RedisCacheManager.class);  
  4.   
  5.     // fast lookup by name map  
  6.     private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();  
  7.   
  8.     private JedisPoolManager redisManager;  
  9.   
  10.     public <K, V> Cache<K, V> getCache(String name) throws CacheException {  
  11.         logger.debug("获取名称为: " + name + " 的RedisCache实例");  
  12.         Cache c = caches.get(name);  
  13.         if (c == null) {  
  14.             c = new RedisCache<K, V>(redisManager);  
  15.             caches.put(name, c);  
  16.         }  
  17.         return c;  
  18.     }  
  19.         //setter和getter方法省略  
  20. }  
     RedisCacheManager实现org.apache.shiro.cache.CacheManager接口,是shiro使用redis的缓存

     (8)com.securityframework.support.redis.RedisSessionDAO

[java]  view plain  copy
  1. public class RedisSessionDAO extends AbstractSessionDAO {  
  2.   
  3.     private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class);  
  4.     /** 
  5.      * shiro-redis的session对象前缀 
  6.      */  
  7.     private final String SHIRO_REDIS_SESSION_PRE = "shiro_redis_session:";  
  8.       
  9.     /** 
  10.      * 存放uid的对象前缀 
  11.      */  
  12.     private final String SHIRO_SHESSIONID_PRE = "shiro_sessionid:";  
  13.       
  14.     /** 
  15.      * 存放uid 当前状态的前缀 
  16.      */  
  17.     private final String UID_PRE = "uid:";  
  18.       
  19.     /** 
  20.      * 存放用户权限的前缀 
  21.      */  
  22.     private final String PERMISSION_PRE ="permission:";  
  23.   
  24.        private JedisPoolManager redisManager;  
  25.   
  26.     private long expire=180000;  
  27.       
  28.     @Override  
  29.     public void update(Session session) throws UnknownSessionException {  
  30.         this.saveSession(session);  
  31.     }  
  32.   
  33.     /** 
  34.      * save session 
  35.      *  
  36.      * @param session 
  37.      * @throws UnknownSessionException 
  38.      */  
  39.     private void saveSession(Session session) throws UnknownSessionException {  
  40.         if (session == null || session.getId() == null) {  
  41.             logger.error("session or session id is null");  
  42.             return;  
  43.         }  
  44.         session.setTimeout(expire);  
  45.         Long redisExpire = expire/1000;  
  46.         int timeout = redisExpire.intValue();  
  47.             JedisPool jedisPool = this.redisManager.getJedisPool();  
  48.         Jedis jedis = null;  
  49.         try {  
  50.             jedis =  jedisPool.getResource();             
  51.             //保存用户会话  
  52.             jedis.setex(this.getByteKey(this.SHIRO_REDIS_SESSION_PRE,session.getId()), timeout, SerializeUtils.serialize(session));  
  53.             String uid = this.getUserId(session);  
  54.             if (null != uid && !"".equals(uid)){  
  55.                 //保存用户会话对应的UID  
  56.                 jedis.setex(this.getByteKey(this.SHIRO_SHESSIONID_PRE,session.getId()),timeout, uid.getBytes());  
  57.                 //保存在线UID  
  58.                 jedis.setex(this.getByteKey(this.UID_PRE,uid), timeout,"online".getBytes());  
  59.             }  
  60.             jedisPool.returnResource(jedis);  
  61.         }catch(Exception ex){  
  62.             if (jedis != null) {  
  63.                 jedisPool.returnBrokenResource(jedis);  
  64.             }  
  65.             throw new JedisException(ex);  
  66.         }  
  67.           
  68.           
  69.     }  
  70.       
  71.     @Override  
  72.     public void delete(Session session) {  
  73.         if (session == null || session.getId() == null) {  
  74.             logger.error("session or session id is null");  
  75.             return;  
  76.         }  
  77.           
  78.         JedisPool jedisPool = this.redisManager.getJedisPool();  
  79.         Jedis jedis = null;  
  80.         try {  
  81.             jedis =  jedisPool.getResource();  
  82.               
  83.             //删除用户会话  
  84.             jedis.del(this.getByteKey(this.SHIRO_REDIS_SESSION_PRE,session.getId()));  
  85.             //获取缓存的用户会话对应的UID  
  86.             byte[] uid = jedis.get(this.getByteKey(this.SHIRO_SHESSIONID_PRE,session.getId()));  
  87.               
  88.             //删除用户会话对应的UID  
  89.             jedis.del(this.getByteKey(this.SHIRO_SHESSIONID_PRE,session.getId()));  
  90.               
  91.             //删除在线UID  
  92.             jedis.del(this.getByteKey(this.UID_PRE,new String(uid)));  
  93.               
  94.             //删除用户缓存的权限  
  95.             jedis.del(this.getByteKey(this.PERMISSION_PRE, new String(uid)));  
  96.               
  97.             jedisPool.returnResource(jedis);  
  98.         }catch(Exception ex){  
  99.             if (jedis != null) {  
  100.                 jedisPool.returnBrokenResource(jedis);  
  101.             }  
  102.             throw new JedisException(ex);  
  103.         }  
  104.       
  105.     }  
  106.   
  107.         @Override  
  108.     public Collection<Session> getActiveSessions() {  
  109.         Set<Session> sessions = new HashSet<Session>();  
  110.   
  111.         Set<byte[]> keys = redisManager  
  112.                 .keys(this.SHIRO_REDIS_SESSION_PRE + "*");  
  113.         if (keys != null && keys.size() > 0) {  
  114.             for (byte[] key : keys) {  
  115.                 Session s = (Session) SerializeUtils.deserialize(redisManager  
  116.                         .get(key));  
  117.                 sessions.add(s);  
  118.             }  
  119.         }  
  120.   
  121.         return sessions;  
  122.     }  
  123.       
  124.     public boolean isOnLine(String uid){  
  125.           
  126.         Set<byte[]>keys = redisManager.keys(this.UID_PRE + uid);  
  127.         if (keys != null && keys.size() > 0){  
  128.           return true;  
  129.         }  
  130.         return false;  
  131.     }  
  132.   
  133.     @Override  
  134.     protected Serializable doCreate(Session session) {  
  135.         Serializable sessionId = this.generateSessionId(session);  
  136.         this.assignSessionId(session, sessionId);  
  137.         this.saveSession(session);  
  138.         return sessionId;  
  139.     }  
  140.   
  141.     @Override  
  142.     protected Session doReadSession(Serializable sessionId) {  
  143.         if (sessionId == null) {  
  144.             logger.error("session id is null");  
  145.             return null;  
  146.         }  
  147.           
  148.         logger.debug("#####Redis.SessionId=" + new String(getByteKey(this.SHIRO_REDIS_SESSION_PRE,sessionId)));  
  149.           
  150.         Session s = (Session) SerializeUtils.deserialize(redisManager.get(this  
  151.                 .getByteKey(this.SHIRO_REDIS_SESSION_PRE,sessionId)));  
  152.         return s;  
  153.     }  
  154.       
  155.     /** 
  156.      * 获得byte[]型的key 
  157.      *  
  158.      * @param key 
  159.      * @return 
  160.      */  
  161.     private byte[] getByteKey(String preKey,Serializable sessionId) {  
  162.         String key = preKey + sessionId;  
  163.         return key.getBytes();  
  164.       
  165.     }  
  166.       
  167.     /** 
  168.      * 获取用户唯一标识 
  169.      * @param session 
  170.      * @return 
  171.      */  
  172.     private String getUserId(Session session){  
  173.         SimplePrincipalCollection pricipal = (SimplePrincipalCollection)session.getAttribute("org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY");  
  174.         if (null != pricipal){  
  175.             Account account = ((Account) pricipal.getPrimaryPrincipal());  
  176.             return account.getAccountId();  
  177.         }  
  178.         return  "";  
  179.     }  
  180.     //setter和getter省略  
  181.   
  182. }  
    RedisSessionDAO继承org.apache.shiro.session.mgt.eis.AbstractSessionDAO,而AbstractSessionDAO是实现了org.apache.shiro.session.mgt.eis.SessionDAO接口的。    通过redis实现shiro的CacheManager接口,继承AbstractSessionDAO,实现shiro和redis的整合。

猜你喜欢

转载自blog.csdn.net/neilgy/article/details/79964133