授权具体实现
授权
/**
* 授权
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
//从认证器中得到CurrentUser对象
CurrentUser user = (CurrentUser)principals.getPrimaryPrincipal();
//通过用户ID查询到对应的权限表示符
List<String> userPermission = userDao.findUserPermissions(user.getUserid());
//将list转为set
Set<String> set = new HashSet<String>();
for(String c : userPermission){
if(c!=null && !("".equals(c))){
set.add(c);
}
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(set);
System.out.println("=====================================================>>>>>>>>>>");
return info;
}
授权配置
在SpringMVC的配置文件中开启shiro注解
添加依赖
<!-- Aop -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!-- shiro整合ehcache缓存管理器 -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.3.1</version>
</dependency>
springMVC配置文件
<!-- 基于注解权限控制 基于类的代理 -->
<aop:config proxy-target-class="true"></aop:config>
spring-shiro.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 配置web.xml中过滤器对应的spring容器的bean -->
<bean id="shiro" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" >
<!-- 注册SecurityManager -->
<property name="securityManager" ref="securityManager"></property>
<!-- 登录时访问的链接 -->
<property name="loginUrl" value="/loginUI"></property>
<!-- 用户无权限时需要访问的页面 -->
<property name="unauthorizedUrl" value="/errorUI"></property>
<!-- 设置 过滤器链 -->
<property name="filterChainDefinitions">
<value>
/bootstrap/** = anon
/dist/** = anon
/images/** = anon
/jquery/** = anon
/tzms/** = anon
<!-- 所有请求匿名访问 /** = anon -->
<!-- 点击登录 不需要认证 -->
/login = anon
<!-- 退出 此方法会清空shiro中session的数据 -->
/logout = logout
<!-- 所有的url都必须要认证通过后才可以访问 -->
/** = authc
</value>
</property>
</bean>
<!-- 配置安全管理器对象 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 配置自定义数据源 -->
<property name="realm" ref="shiroUserRealm"></property>
<!-- 配置缓存 -->
<property name="cacheManager" ref="ehCacheManager"></property>
</bean>
<!-- 配置自定义Realm -->
<bean id="shiroUserRealm" class="com.tanzhou.tzms.common.service.impl.ShiroRealmsOne">
<!-- 配置凭证匹配器 -->
<property name="credentialsMatcher" ref="credentialsMatcher"></property>
</bean>
<!-- 定义凭证匹配器 -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<!-- 匹配散列算法 -->
<property name="hashAlgorithmName" value="MD5"></property>
<!-- 匹配散列次数 -->
<property name="hashIterations" value="1"></property>
</bean>
<bean id="advisor" class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager"></property>
</bean>
<!-- 配置缓存管理器 -->
<bean id="ehCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<!-- 配置缓存管理文件 -->
<property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml"></property>
</bean>
</beans>
shrio-ehcache.xml缓存配置文件
<?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">
<!--
diskStore:为缓存路径,ehcache分为内存和磁盘两级,
此属性定义磁盘的缓存位置。参数解释如下:
-->
<diskStore path="F:\ehcache"/>
<!--
defaultCache:默认缓存策略
-->
<!--
maxElementsInMemory:缓存最大数目
maxElementsOnDisk:硬盘最大缓存个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
overflowToDisk:是否保存到磁盘,当系统当机时
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
FIFO,first in first out,这个是大家最熟的,先进先出。
LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
<defaultCache
eternal="false"
maxElementsInMemory="10000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
基于注解式资源授权验证
清空缓存
在自定义Realm中添加清空方法
/**
* 清空缓存
*/
public void clearCache(){
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
super.clearCache(principals);
}
添加业务处理方法
第一次正常请求会授权,之后访问从缓存中获取。当调用清空缓存方法后,再次请求的时候因为缓存已经空了,所以会再次授权,
场景: 权限修改生效后,立即刷新清空缓存,则可以实现用户不退出生效新的权限