一、授权流程

  

二、三种授权方式

2.1、编程式:通过写if/else 授权代码块完成:

  1. Subject subject = SecurityUtils.getSubject();
  2. if(subject.hasRole(“admin”)) {
  3. //有权限
  4. } else {
  5. //无权限
  6. }

2.2、注解式:通过在执行的Java方法上放置相应的注解完成:

  1. @RequiresRoles("admin")
  2. public void hello() {
  3. //有权限
  4. }

2.3、JSP/GSP 标签:在JSP/GSP 页面通过相应的标签完成:

  1. <shiro:hasRole name="admin">
  2. <!— 有权限—>
  3. </shiro:hasRole>

三、建立权限配置

shiro-permission.ini里边的内容相当于在数据库

  1. #用户
  2. [users]
  3. #用户zhang的密码是123,此用户具有role1和role2两个角色
  4. zhang=,role1,role2
  5. wang=,role2
  6.  
  7. #权限
  8. [roles]
  9. #角色role1对资源user拥有create、update权限
  10. role1=user:create,user:update
  11. #角色role2对资源user拥有create、delete权限
  12. role2=user:create,user:delete
  13. #角色role3对资源user拥有create权限
  14. role3=user:create

权限标识符号规则【中间使用半角:分隔】:资源:操作:实例  

  user:create:01  表示对用户资源的01实例进行create操作。

  user:create  表示对用户资源进行create操作,相当于user:create:*,对所有用户资源实例进行create操作。

  user:*:01   表示对用户资源实例01进行所有操作。

四、代码开发

4.1、测试ini程序

  1. // 角色授权、资源授权测试
  2. @Test
  3. public void testAuthorization() {
  4.  
  5. // 创建SecurityManager工厂
  6. Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
  7.  
  8. // 创建SecurityManager
  9. SecurityManager securityManager = factory.getInstance();
  10.  
  11. // 将SecurityManager设置到系统运行环境,和spring后将SecurityManager配置spring容器中,一般单例管理
  12. SecurityUtils.setSecurityManager(securityManager);
  13.  
  14. // 创建subject
  15. Subject subject = SecurityUtils.getSubject();
  16.  
  17. // 创建token令牌
  18. UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");
  19.  
  20. // 执行认证
  21. try {
  22. subject.login(token);
  23. } catch (AuthenticationException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27.  
  28. System.out.println("认证状态:" + subject.isAuthenticated());
  29. // 认证通过后执行授权
  30.  
  31. // 基于角色的授权
  32. // hasRole传入角色标识
  33. boolean ishasRole = subject.hasRole("role1");
  34. System.out.println("单个角色判断" + ishasRole);
  35. // hasAllRoles是否拥有多个角色
  36. boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1", "role2", "role3"));
  37. System.out.println("多个角色判断" + hasAllRoles);
  38.  
  39. // 使用check方法进行授权,如果授权不通过会抛出异常
  40. // subject.checkRole("role13");
  41.  
  42. // 基于资源的授权
  43. // isPermitted传入权限标识符
  44. boolean isPermitted = subject.isPermitted("user:create:1");
  45. System.out.println("单个权限判断" + isPermitted);
  46.  
  47. boolean isPermittedAll = subject.isPermittedAll("user:create:1", "user:delete");
  48. System.out.println("多个权限判断" + isPermittedAll);
  49.  
  50. // 使用check方法进行授权,如果授权不通过会抛出异常
  51. subject.checkPermission("items:create:1");
  52.  
  53. }

4.2、自定义realm

  上边的程序通过shiro-permission.ini对权限信息进行静态配置,实际开发中从数据库中获取权限数据。就需要自定义realm,由realm从数据库查询权限数据。

  realm根据用户身份查询权限数据,将权限数据返回给authorizer(授权器)。

4.2.1、realm编写,结合上节完善写法

  在原来自定义的realm中,修改doGetAuthorizationInfo方法。

  1. package com.lhx.shiro.realm;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.List;
  5.  
  6. import org.apache.shiro.authc.AuthenticationException;
  7. import org.apache.shiro.authc.AuthenticationInfo;
  8. import org.apache.shiro.authc.AuthenticationToken;
  9. import org.apache.shiro.authc.SimpleAuthenticationInfo;
  10. import org.apache.shiro.authz.AuthorizationInfo;
  11. import org.apache.shiro.authz.SimpleAuthorizationInfo;
  12. import org.apache.shiro.realm.AuthorizingRealm;
  13. import org.apache.shiro.subject.PrincipalCollection;
  14.  
  15. /**
  16. *
  17. * <p>
  18. * Title: CustomRealm
  19. * </p>
  20. * <p>
  21. * Description:自定义realm
  22. * </p>
  23. * @version 1.0
  24. */
  25. public class CustomRealm extends AuthorizingRealm {
  26.  
  27. // 设置realm的名称
  28. @Override
  29. public void setName(String name) {
  30. super.setName("customRealm");
  31. }
  32.  
  33. // 用于认证
  34. @Override
  35. protected AuthenticationInfo doGetAuthenticationInfo(
  36. AuthenticationToken token) throws AuthenticationException {
  37.  
  38. // token是用户输入的
  39. // 第一步从token中取出身份信息
  40. String userCode = (String) token.getPrincipal();
  41.  
  42. // 第二步:根据用户输入的userCode从数据库查询
  43. // ....
  44.  
  45. // 如果查询不到返回null
  46. //数据库中用户账号是zhangsansan
  47. /*if(!userCode.equals("zhangsansan")){//
  48. return null;
  49. }*/
  50.  
  51. // 模拟从数据库查询到密码
  52. String password = "111111";
  53.  
  54. // 如果查询到返回认证信息AuthenticationInfo
  55.  
  56. SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
  57. userCode, password, this.getName());
  58.  
  59. return simpleAuthenticationInfo;
  60. }
  61.  
  62. // 用于授权
  63. @Override
  64. protected AuthorizationInfo doGetAuthorizationInfo(
  65. PrincipalCollection principals) {
  66.  
  67. //从 principals获取主身份信息
  68. //将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到SimpleAuthenticationInfo中身份类型),
  69. String userCode = (String) principals.getPrimaryPrincipal();
  70.  
  71. //根据身份信息获取权限信息
  72. //连接数据库...
  73. //模拟从数据库获取到数据
  74. List<String> permissions = new ArrayList<String>();
  75. permissions.add("user:create");//用户的创建
  76. permissions.add("items:add");//商品添加权限
  77. //....
  78.  
  79. //查到权限数据,返回授权信息(要包括 上边的permissions)
  80. SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
  81. //将上边查询到授权信息填充到simpleAuthorizationInfo对象中
  82. simpleAuthorizationInfo.addStringPermissions(permissions);
  83.  
  84. return simpleAuthorizationInfo;
  85. }
  86.  
  87. }

4.2.2、在shiro-realm.ini中配置自定义的realm,将realm设置到securityManager中

  1. [main]
  2. #自定义 realm
  3. customRealm=com.lhx.shiro.realm.CustomRealm
  4. #\将realm设置到securityManager相当于spring中注入
  5. securityManager.realms=$customRealm

4.2.3、测试程序

  1. // 自定义realm进行资源授权测试
  2. @Test
  3. public void testAuthorizationCustomRealm() {
  4.  
  5. // 创建SecurityManager工厂
  6. Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini");
  7.  
  8. // 创建SecurityManager
  9. SecurityManager securityManager = factory.getInstance();
  10.  
  11. // 将SecurityManager设置到系统运行环境,和spring后将SecurityManager配置spring容器中,一般单例管理
  12. SecurityUtils.setSecurityManager(securityManager);
  13.  
  14. // 创建subject
  15. Subject subject = SecurityUtils.getSubject();
  16.  
  17. // 创建token令牌
  18. UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "111111");
  19.  
  20. // 执行认证
  21. try {
  22. subject.login(token);
  23. } catch (AuthenticationException e) {
  24. // TODO Auto-generated catch block
  25. e.printStackTrace();
  26. }
  27.  
  28. System.out.println("认证状态:" + subject.isAuthenticated());
  29. // 认证通过后执行授权
  30.  
  31. // 基于资源的授权,调用isPermitted方法会调用CustomRealm从数据库查询正确权限数据
  32. // isPermitted传入权限标识符,判断user:create:1是否在CustomRealm查询到权限数据之内
  33. boolean isPermitted = subject.isPermitted("user:create:1");
  34. System.out.println("单个权限判断" + isPermitted);
  35.  
  36. boolean isPermittedAll = subject.isPermittedAll("user:create:1", "user:create");
  37. System.out.println("多个权限判断" + isPermittedAll);
  38.  
  39. // 使用check方法进行授权,如果授权不通过会抛出异常
  40. subject.checkPermission("items:add:1");
  41.  
  42. }

4.3、授权流程

1、对subject进行授权,调用方法isPermitted("permission串")

2、SecurityManager执行授权,通过ModularRealmAuthorizer执行授权

3、ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据

调用realm的授权方法:doGetAuthorizationInfo

4、realm从数据库查询权限数据,返回ModularRealmAuthorizer

5、ModularRealmAuthorizer调用PermissionResolver进行权限串比对

6、如果比对后,isPermitted中"permission串"在realm查询到权限数据中,说明用户访问permission串有权限,否则 没有权限,抛出异常。

小结:以上004-006即是shiro基础权限认证,后续将编写结合spring,cache等文章

006-shiro授权的更多相关文章

  1. Apache Shiro 使用手册(三)Shiro 授权

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等. 一.授权的三要素 授权有着三 ...

  2. Apache shiro集群实现 (四)shiro授权(Authentication)--访问控制

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  3. Shiro笔记(五)Shiro授权

    Shiro授权 也叫访问控制,即在应用中控制谁能访问那些资源(如访问页面.编辑数据.页面操作等).在授权中需要了解几个关键对象:主体(subject).资源(resource).权限(Permissi ...

  4. Shiro授权管理

    一.授权 授权,也叫访问控制,即在应用中控制谁能访问哪些资源(如访问页面/编辑数据/页面操作等).在授权中需了解的几个关键对象:主体(Subject).资源(Resource).权限(Permissi ...

  5. 转:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法、shiro认证与shiro授权

    原文地址:JAVAWEB开发之权限管理(二)——shiro入门详解以及使用方法.shiro认证与shiro授权 以下是部分内容,具体见原文. shiro介绍 什么是shiro shiro是Apache ...

  6. shiro授权-记调试过程

    根据张开涛老师的shiro教程学习过程中 感觉shiro授权这块有点绕 调试了十几遍 大概有个思路  记录一下 1.单元测试入口 2.subject().isPermitted("+user ...

  7. frame shiro 授权及原理简述

    shiro 授权模式 shiro采用的是rbac授权模式rbac,基于角色的权限管理,谁扮演什么角色,被允许做什么事情. shiro 授权流程 shiro 授权方式 1.编程式 通过写if/else授 ...

  8. Apache Shiro 使用手册(三)Shiro 授权(转发:http://kdboy.iteye.com/blog/1155450)

    授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限. 如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等. 一.授权的三要素 授权有着三 ...

  9. Shiro授权流程

    1,授权中涉及的一些概念      [1]授权:访问控制,即在应用中认证用户能否访问的系统资源(如一个页面,一个按钮等).      [2]资源:在Web应用中反应为用户可以访问的URL.       ...

  10. shiro授权+注解式开发

    shiro授权和注解式开发 1.shiro授权角色.权限 2.Shiro的注解式开发 ShiroUserMapper.xml <select id="getRolesByUserId& ...

随机推荐

  1. tail 命令详解

    tail 指令 功能:从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不 ...

  2. 基于ZK的分布式锁实现

    import java.util.concurrent.TimeUnit; import org.apache.curator.framework.CuratorFramework; import o ...

  3. Ubuntu安装新版本nodejs的5种姿势

    引言: 写这篇文章之前,关于ubuntu14.04(Trusty)默认安装的NodeJS版本是0.10.25百思不解(什么鬼,哪一年的NodeJS) 写这篇文章之时,NodeJS的LTS版本号都已经1 ...

  4. nodejs系列笔记01---Buffer

    纯JavaScript无法处理二进制数据,buffer就是用来处理二进制数据的 原始数据保存在buffer实例中,一个buffer实例类似于数组.buffer的大小在建立时指定的不可更改. buffe ...

  5. python web框架 推荐

    Flask 很轻,花很少的成本就能够开发一个简单的网站.非常适合初学者学习. 学会以后,可以考虑学习插件的使用,用 SQLAlchemy + Flask-SQLAlchemy 来对你的数据库进行控制. ...

  6. C语言 百炼成钢27

    /* 题目63:编写C++程序完成以下功能: (1)声明一个纯虚函数类Shape(形状),其中包含来计算面积.计算周长的方法: (2)从Shape派生两个类矩形和圆形: (3)从矩形派生正方形: (4 ...

  7. 第一百四十八节,封装库--JavaScript,菜单切换

    第一百四十八节,封装库--JavaScript,菜单切换 首先在封装库封装点击切换方法 /** dian_ji_qie_huan()方法,设置点击切换,将元素设置成点击切换,也就是点击目标元素后,循环 ...

  8. git 入门一(初识)

    分布式版本控制系统 & 集中式版本控制系统   分布式版本控制系统( Distributed Version Control System)在这类系统中,像 Git,Mercurial,Baz ...

  9. linux程序设计——主机字节序和网络字节序(第十五章)

    15.2.10    主机字节序和网络字节序 当在基于intel处理器的linux机器上执行新版本号的server和客户程序时,能够用netstat命令查看网络连接状况.它显示了客户/server连接 ...

  10. 用MathType编辑异或与非符号有什么方法

    在数学中我们会遇到各种数学符号,有运算符号,希腊符号,还有表示逻辑关系的逻辑符号等,这些大多都是比较常用的符号.其中逻辑符号中我们经常会用到异或与非等,这些符号的编辑我们常常会需要用MathType这 ...