shiro学习与应用

jeli007 12年前
第一阶段:装配shiro
    shiro这个安全框架的使用,经过自己在项目中的实际应用,确实要比springsecurity要好用得多了...
        附件中的demo只是结合springmvc把登陆验证部分做了,没有加任何封装,非常的原生态,有助于理解shiro工作原理
        另外还有一大功能就是权限的组装和认证,其实很简单,只要在shiro的配置文件中关注以下部分:
<property name="filterChainDefinitions">
   <value>
    /login = anon(不用登陆也能访问)
    /user/** = authc(登陆之后才能访问)
    /role/edit/* = perms[role:edit]
    /role/save = perms[role:edit]
    /role/list = perms[role:view]
    /** = authc
         </value>
  </property>
        当shiro拦截到<value></value>中预先配好的请求路径,就会去调用doGetAuthorizationInfo()方法,这是我们需要在此方法中手动添加权限查询权限语句(可以来自文件系统,也可以来自数据库),shiro会通过此方法返回的list中的权限列表去匹配此用户是否具有权限(“role:edit”即为数据库所存字段的格式),若无:<property name="unauthorizedUrl" value="/nopermission.jsp" />
 
第二阶段:权限细化到按钮级别
    <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%>
      
      <shiro:hasPermission name="user:add"> 
           <li><a href="javascript:" onclick="refresh('user/pre_add_user')">添加运营人员</a></li>
      </shiro:hasPermission>
 
第三阶段:shiro的session与权限缓存控制
    登录认证通过后,存入shiro session中:
        User user=new User(username, password);
        org.apache.shiro.subject.Subject subject = org.apache.shiro.SecurityUtils.getSubject();
        org.apache.shiro.session.Session session = subject.getSession();
        session.getAttribute(user); 
      1.代码中控制session时间
        session.setTimeout(5000); //过期时间在代码中设置
        //      Date start = session.getStartTimestamp();
        //      Date timestamp = session.getLastAccessTime(); 
      2.配置文件中控制session时间
             a、shiroFilter中注入securityManager
            <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
                     <property name="securityManager" ref="websecurityManager" />
             </bean>
               b、websecurityManager中注入sessionMode、cacheManager、sessionManager
            <bean id="websecurityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
                   <!-- 如果用shiro的session,sessionMode要设置成为native -->
                    <property name="sessionMode" value="native" />
                    <property name="cacheManager" ref="shiroCacheManager" />
                    <property name="sessionManager" ref="sessionManager" /> 
             </bean>
             
            配置cache以及注入cache配置文件
             <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">  
                   <property name="cacheManagerConfigFile" value="classpath:beans/shiro-cache.xml"/>
            </bean>  
            
            配置sessioncache,此处指明为shiro-activeSessionCache,即可在shiro-cache.xml中对session过期时间等参数进行配置
             <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
                     <property name="sessionDAO" ref="sessionDAO"/>
             </bean>
             <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
                     <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/>
             </bean>
            
           另附shiro-cache.xml
<ehcache>
 <diskStore path="java.io.tmpdir/tuan-oauth" />
         <defaultCache maxElementsInMemory="10000" 
              eternal="false"
              timeToIdleSeconds="120" 
              timeToLiveSeconds="120" 
              overflowToDisk="false"
              diskPersistent="false" 
              diskExpiryThreadIntervalSeconds="120" />
        
        <!-- sessioncache -->
         <cache name="shiro-activeSessionCache"  
                 maxElementsInMemory="10000"
                 eternal="false" 
                 overflowToDisk="false" 
                 diskPersistent="true"
                 timeToIdleSeconds="120" 
                 timeToLiveSeconds="120" 
                 diskExpiryThreadIntervalSeconds="120" />
 
         <!-- 权限cache,默认命名shiro.authorizationCache -->
        <cache name="shiro.authorizationCache" 
                 maxElementsInMemory="100"
                 eternal="false" 
                 timeToLiveSeconds="120" 
                 overflowToDisk="false" />
</ehcache>
    
 
 第四阶段:缓存同步,做到分布式
<!-- 配置PeerProvider -->
 <!-- 手动方式同步sever2中的userCache和resourceCache -->
 <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
  properties="peerDiscovery=manual, rmiUrls=//localhost:8080/userCache|//localhost:8080/userCache" /> -->
 
 <!-- 自动方式同步sever2中的userCache和resourceCache -->
 <!-- <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"  
  properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,  
     multicastGroupPort=4446, timeToLive=32"/> -->
 
 
 <!-- 配置CacheManagerPeerListener 配置中server1监听本机40001端口 -->
 <!-- <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
  properties="hostName=127.0.0.0, port=8080,socketTimeoutMillis=2000" />  
 
 
<defaultCache  
  maxElementsInMemory="10000"  
  eternal="false"  
  timeToIdleSeconds="120"  
  timeToLiveSeconds="120"  
  overflowToDisk="true"  
  diskSpoolBufferSizeMB="30"  
  maxElementsOnDisk="10000000"  
  diskPersistent="false"  
  diskExpiryThreadIntervalSeconds="120"  
  memoryStoreEvictionPolicy="LRU"  
  <cacheEventListenerFactory  
  class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>  
  />
 
 
另外shiro默认使用ehcache,也可以用第三方缓存做分布是缓存等等
除此以外,shiro有提供部分实用的标签,在此不做介绍,网上很多