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>
<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>
<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时间
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时间
// 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>
<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>
<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>
<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" />
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 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" />
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" />
第四阶段:缓存同步,做到分布式
<!-- 配置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"/>
/>
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有提供部分实用的标签,在此不做介绍,网上很多