前言
本文主要讲解的知识点有以下:
- Shiro授权过滤器使用
- Shiro缓存
- 与Ehcache整合
- Shiro应用->实现验证码功能
- 记住我功能
一、授权过滤器测试
我们的授权过滤器使用的是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和权限对应起来进行配置,是比较不方便的。我们可以使用授权的另外两种方式
- 注解式
- 标签式
2.1注解式
如果要使用注解式,那么就必须在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; }
2.2jsp标签 授权
这里写图片描述
这里写图片描述
当调用controller的一个方法,由于该 方法加了@RequiresPermissions("item:query") ,shiro调用realm获取数据库中的权限信息,看"item:query"是否在权限数据中存在,如果不存在就拒绝访问,如果存在就授权通过。
当展示一个jsp页面时,页面中如果遇到,shiro调用realm获取数据库中的权限信息,看item:update是否在权限数据中存在,如果不存在就拒绝访问,如果存在就授权通过。