授权过滤器测试

我们的授权过滤器使用的是permissionsAuthorizationFilter来进行拦截。我们可以在application-shiro中配置filter规则


<!--商品查询需要商品查询权限 -->
/items/queryItems.action = perms[item:query]
/items/editItems.action = perms[item:edit]

测试流程:

1、在applicationContext-shiro.xml中配置filter规则

  • <!--商品查询需要商品查询权限 -->
  • /items/queryItems.action = perms[item:query]

2、用户在认证通过后,请求/items/queryItems.action

3、被PermissionsAuthorizationFilter拦截,发现需要“item:query”权限

4、PermissionsAuthorizationFilter**调用realm中的doGetAuthorizationInfo获取数据库中正确的权限**

5、PermissionsAuthorizationFilter对item:query 和从realm中获取权限进行对比,如果“item:query”在realm返回的权限列表中,授权通过。

realm中获取认证的信息,查询出该用户对应的权限,封装到simpleAuthorizationInfo中,PermissionsAuthorizationFilter会根据对应的权限来比对。


@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) { //从 principals获取主身份信息
//将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型),
ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal(); //根据身份信息获取权限信息
//从数据库获取到权限数据
List<SysPermission> permissionList = null;
try {
permissionList = sysService.findPermissionListByUserId(activeUser.getUserid());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//单独定一个集合对象
List<String> permissions = new ArrayList<String>();
if(permissionList!=null){
for(SysPermission sysPermission:permissionList){
//将数据库中的权限标签 符放入集合
permissions.add(sysPermission.getPercode());
}
} /* List<String> permissions = new ArrayList<String>();
permissions.add("user:create");//用户的创建
permissions.add("item:query");//商品查询权限
permissions.add("item:add");//商品添加权限
permissions.add("item:edit");//商品修改权限
*/ //.... //查到权限数据,返回授权信息(要包括 上边的permissions)
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//将上边查询到授权信息填充到simpleAuthorizationInfo对象中
simpleAuthorizationInfo.addStringPermissions(permissions); return simpleAuthorizationInfo;
}

在bean中我们已经配置了:如果没有权限,那么跳转到哪个JSP页面了


<!-- 通过unauthorizedUrl指定没有权限操作时跳转页面-->
<property name="unauthorizedUrl" value="/refuse.jsp" />

到目前为止,现在问题又来了:

1、在applicationContext-shiro.xml中配置过虑器链接,需要将全部的url和权限对应起来进行配置,比较发麻不方便使用。

2、每次授权都需要调用realm查询数据库,对于系统性能有很大影响,可以通过shiro缓存来解决。


使用注解式和标签式配置授权

上面的那种方法,还是需要我们将全部的url和权限对应起来进行配置,是比较不方便的。我们可以使用授权的另外两种方式

  • 注解式
  • 标签式

注解式

如果要使用注解式,那么就必须在Spring中开启controller类aop支持


<!-- 开启aop,对类代理 -->
<aop:config proxy-target-class="true"></aop:config>
<!-- 开启shiro注解支持 -->
<bean
class="
org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>

在Controller中使用注解来进行配置就行了,就不用在我们的application-shiro中全部集中配置了


//商品信息方法
@RequestMapping("/queryItems")
@RequiresPermissions("item:query")//执行queryItems需要"item:query"权限
public ModelAndView queryItems(HttpServletRequest request) throws Exception { System.out.println(request.getParameter("id")); //调用service查询商品列表
List<ItemsCustom> itemsList = itemsService.findItemsList(null); ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("itemsList", itemsList);
// 指定逻辑视图名
modelAndView.setViewName("itemsList"); return modelAndView;
}

jsp标签 授权

当调用controller的一个方法,由于该 方法加了@RequiresPermissions(“item:query”) ,shiro调用realm获取数据库中的权限信息,看”item:query”是否在权限数据中存在,如果不存在就拒绝访问,如果存在就授权通过。

当展示一个jsp页面时,页面中如果遇到,shiro调用realm获取数据库中的权限信息,看item:update是否在权限数据中存在,如果不存在就拒绝访问,如果存在就授权通过。


Shiro缓存

针对上边授权频繁查询数据库,需要使用shiro缓存

缓存流程

shiro中提供了对认证信息和授权信息的缓存。shiro默认是关闭认证信息缓存的,对于授权信息的缓存shiro默认开启的。主要研究授权信息缓存,因为授权的数据量大。

用户认证通过。

该用户第一次授权:调用realm查询数据库

该用户第二次授权:不调用realm查询数据库,直接从缓存中取出授权信息(权限标识符)。

使用ehcache和Shiro整合

导入jar包

配置缓存管理器,注入到安全管理器中


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


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

ehcache的配置文件shiro-ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!--diskStore:缓存数据持久化的目录 地址 -->
<diskStore path="F:\develop\ehcache" />
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>

缓存清空

如果用户正常退出,缓存自动清空。

如果用户非正常退出,缓存自动清空。

还有一种情况:

  • 当管理员修改了用户的权限,但是该用户还没有退出,在默认情况下,修改的权限无法立即生效。需要手动进行编程实现:在权限修改后调用realm的clearCache方法清除缓存。

清除缓存:


//清除缓存
public void clearCached() {
PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
super.clearCache(principals);
}

sessionManager

和shiro整合后,使用shiro的session管理,shiro提供sessionDao操作 会话数据。

配置sessionManager


<!-- 会话管理器 -->
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<!-- session的失效时长,单位毫秒 -->
<property name="globalSessionTimeout" value="600000"/>
<!-- 删除失效的session -->
<property name="deleteInvalidSessions" value="true"/>
</bean>

注入到安全管理器中


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

Shiro第五篇【授权过滤、注解、JSP标签方式、与ehcache整合】的更多相关文章

  1. .NetCore 下开发独立的(RPL)含有界面的组件包 (五)授权过滤参数处理

    .NetCore 下开发独立的(RPL)含有界面的组件包 (一)准备工作 .NetCore 下开发独立的(RPL)含有界面的组件包 (二)扩展中间件及服 务 .NetCore 下开发独立的(RPL)含 ...

  2. shiro框架学习-7- Shiro权限控制注解和编程方式

    讲解权限角色控制 @RequiresRoles, @RequiresPermissions等注解的使用和编程式控制 配置文件的方式 使用ShiroConfig 注解方式 @RequiresRoles( ...

  3. shiro:10个过滤器;10个jsp标签;5个@注解

    10个过滤器 过滤器简称 对应的java类 anon org.apache.shiro.web.filter.authc.AnonymousFilter authc org.apache.shiro. ...

  4. .NetCore 下开发独立的(RPL)含有界面的组件包 (四)授权过滤

    .NetCore 下开发独立的(RPL)含有界面的组件包 (一)准备工作 .NetCore 下开发独立的(RPL)含有界面的组件包 (二)扩展中间件及服 务 .NetCore 下开发独立的(RPL)含 ...

  5. shiro源码篇 - shiro认证与授权,你值得拥有

    前言 开心一刻 我和儿子有个共同的心愿,出国旅游.昨天儿子考试得了全班第一,我跟媳妇合计着带他出国见见世面,吃晚饭的时候,一家人开始了讨论这个.我:“儿子,你的心愿是什么?”,儿子:“吃汉堡包”,我: ...

  6. Shiro笔记(五)JSP标签

    Shiro笔记(五)JSP标签 导入标签库 <%@taglib prefix="shiro" uri="http://shiro.apache.org/tags&q ...

  7. Spring Boot干货系列:(五)开发Web应用JSP篇

    Spring Boot干货系列:(五)开发Web应用JSP篇 原创 2017-04-05 嘟嘟MD 嘟爷java超神学堂 前言 上一篇介绍了Spring Boot中使用Thymeleaf模板引擎,今天 ...

  8. JSP第五篇【JSTL的介绍、core标签库、fn方法库、fmt标签库】

    什么是JSTL JSTL全称为 JSP Standard Tag Library 即JSP标准标签库. JSTL作为最基本的标签库,提供了一系列的JSP标签,实现了基本的功能:集合的遍历.数据的输出. ...

  9. Shiro入门这篇就够了【Shiro的基础知识、回顾URL拦截】

    前言 本文主要讲解的知识点有以下: 权限管理的基础知识 模型 粗粒度和细粒度的概念 回顾URL拦截的实现 Shiro的介绍与简单入门 一.Shiro基础知识 在学习Shiro这个框架之前,首先我们要先 ...

随机推荐

  1. volatile可见性的一些认识

    一.前言 volatile的关键词的使用在JVM内存模型中已是老生常谈了,这篇文章主要结合自己对可见性的一些认识和一些直观的例子来谈谈volatile.文章正文大致分为三部分,首先会介绍一下happe ...

  2. Centos定时任务

    安装crontab:yum install crontabs说明:/sbin/service crond start //启动服务/sbin/service crond stop //关闭服务/sbi ...

  3. RSA简介(四)——求逆算法

    此处所谓求逆运算,是指在模乘群里求逆. 第一节里提到互质的两个定义: (1)p,q两整数互质指p,q的最大公约数为1. (2)p.q两整数互质指存在整数a,b,使得ap+bq=1. 只要明白了欧几里得 ...

  4. 利用pyinotify监控文件内容,像tailf命令但比它更强

    Linux的tail/tailf命令使用了内核提供的inotify功能,下面的Python例子也使用inotify实现比tail/tailf更强的监控文件功能. watchfile.py #!/usr ...

  5. Mybatis 插入数据并返回刚刚插入的数据id

    1.在Mybatis Mapper文件中添加属性“useGeneratedKeys”和“keyProperty”,其中keyProperty是Java对象的属性名,而不是表格的字段名. 2.Mybat ...

  6. OKCoin期货现货API[Python3版]

    OKCoin 期货 现货 API [Python版] 一.HttpMD5Util.py,基础类,包括MD5签名,HTTP Post及HTTP Get方法 #!/usr/bin/python # -*- ...

  7. 关于原根的存在性及个数(Primitive Root Theorem)

    我在RSA学习总结的第三部分关于Mille-Rabin素数测试的正确性证明里需要用到此定理,由于证明太长,故另开一章于此.(为啥我说话突然文绉绉了Orz,可能是这周辩论打多了) 结论是对素数p,mod ...

  8. Capacitor电容

    capacitor无正负极性. cap electrolit有极性,实际中不能接反,否则电容会烧毁或爆炸. MULTISIM仿真中接反会有漏阻存在,但不会烧毁. 电容的分类 按结构可分为:固定电容,可 ...

  9. maven 搭建 SpringMVC + MyBatis(1)

    ·做了两年多Java Web一多半的项目都是SSM架构的,只搭建过两次,趁着周末做个总结整理. Eclipse搭建Maven项目 1.new project  --> Maven project ...

  10. Java开发相关命名规范

    JAVA文件命名规范 1.类命名 抽象类以 Abstract 或者 Base 开头.异常类以 Exception 作为后缀.枚举类以 Enum 作为后缀.工具类以 Utils 作为后缀(相应的包名最后 ...