您的位置:首页 > 编程语言 > Java开发

java鬼混笔记:shiro 9、缓存授权,免重新登录更新用户权限

2017-09-17 00:59 573 查看
完整的项目下载路径(项目下载网上的hui框架来着,什么鬼文件都在里面,暂清除,所以很多):
http://download.csdn.net/download/u013845177/9992748
相关的lib包路径:
http://download.csdn.net/download/u013845177/9992728
上一篇通过数据授权后,用户每一次操作都会重新刷新数据库获取权限信息,这是很不好的方法,所以要用上缓存进行处理。同时在修改用户权限时,不用用户重新登录就可以让用户的权限改变

一、加入缓存功能,用的是ehcache缓存(hibernate好像也是这个)

首先添加一个shiro-ehcache.xml文件,内容如下:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!--diskStore:缓存数据持久化的目录  -->
<diskStore path="F:\shiro\ehcache" />
<defaultCache
maxElementsInMemory="80000"
maxElementsOnDisk="0"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="180"
timeToLiveSeconds="180"
diskExpiryThreadIntervalSeconds="180"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
<!--
maxElementsInMemory 内存中保持的对象数量
maxElementsOnDisk 	 DiskStore中保持的对象数量,默认值为0,表示不限制
eternal  是否是永恒数据,如果是,则它的超时设置会被忽略
overflowToDisk 如果内存中数据数量超过maxElementsInMemory限制,是否要缓存到磁盘上
timeToIdleSeconds 对象空闲时间,指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问 单位秒
timeToLiveSeconds  对象存活时间,指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问
diskPersistent 	 是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false
diskExpiryThreadIntervalSeconds  对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次
diskSpoolBufferSizeMB 	 DiskStore使用的磁盘大小,默认值30MB。每个cache使用各自的DiskStore
memoryStoreEvictionPolicy  如果内存中数据超过内存限制,向磁盘缓存时的策略。默认值LRU,可选FIFO、LFU
-->
</ehcache>
接着在applicationContext-shiro.xml中加入一个bean配置,代码如下:

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


同时在id="securityManager"(安全管理器)的bean中加入<property name="cacheManager" ref="cacheManager"/>,代码如下:

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


OK,打个断点就发现从数据库里授权获取只执行一次.
二、免重新登录更新用户权限

这个功能也实用,当发现某个用户不应该拥有这个权限时,我们可以把用户的这个权限给关了,但是,平时都是用户退出后重新登录才可以更新他的权限,用户要是不退出的话, 还是可以继续操作的,所以shiro提供一个好的方法来处理,那就是清空授权缓存上面功能是进行授权缓存的,也就是用户的权限信息都在缓存里,如果我们把缓存清空了,那么用户再一次操作时,会重新加载数据库里的权限信息,这时用户拿到的权限信息是最新的,也是修改之后的,用户就不用退出重新登录获取新的权限了

上代码:

首先在我们自定义的LSRealm.java中加入一个方法clearCached(),代码如下:

...省略
public class LSRealm extends AuthorizingRealm {

@Autowired
private UserService userService;
// 注入缓存管理器
@Autowired
private EhCacheManager cacheManager;

@Override
public void setName(String name) {
super.setName("LSRealm");
}

// 授权处理
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
...省略
}

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
...省略
}

/**
* 清空缓存
*/
public void clearCached() {
cacheManager.getCache("cn.common.LSRealm.authorizationCache").clear();// 清空所有缓存
//也可以清除指定用户的缓存
//cacheManager.getCache("cn.common.LSRealm.authorizationCache").remove(sessionId);// 指定用户的sessionId


}}

有个地方要注意,当A用户的[role:list]权限被清空后,再点击[role:list]对应的url,就报这个错误org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [role:list]解决方法: 在spring-mvc.xml中加入

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- 没权限访问跳转 -->
<prop key="org.apache.shiro.authz.AuthorizationException">redirect:/powerFlag.do</prop>
</props>
</property>
</bean>
// powerFlag.do 方法
@RequestMapping("powerFlag")
public String powerFlag(HttpServletRequest request) {

String requestType = request.getHeader("X-Requested-With");
if (requestType != null && requestType.equals("XMLHttpRequest")) {// ajax请求
return "redirect:/forAjax.do";//forAjax()方法返回json数据
} else {
return "redirect:/noPower.do";// 跳转权限页面
}
}




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐