当前位置: 首页 > news >正文

shiro权限认证与授权

什么是shiro

Shiroapache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。

 

为什么要用shiro

既然可以基于url实现权限的管理,为什么还要用shiro呢??

1.shiro将安全认证相关的功能抽取出来组成一个框架,使用shiro就可以非常快速的完成认证、授权等功能的开发,降低系统成本。最主要的就是方便了我们的开发。

2.shiro使用广泛,shiro可以运行在web应用,非web应用,集群分布式应用中越来越多的用户开始使用shiro

 

shiro认证

认证流程:

 

实例:

1.创建一个Java工程,并加入shiro-corejar包以及它的依赖包。

 

2.自定义realm

Shiro有自带的IniRealmIniRealmini配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义realm

 

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class CustomRealm extends AuthorizingRealm {  
  2.   
  3.     @Override  
  4.     public String getName() {  
  5.         return "customRealm";  
  6.     }  
  7.   
  8.     // 用于认证  
  9.     @Override  
  10.     protected AuthenticationInfo doGetAuthenticationInfo(  
  11.             AuthenticationToken token) throws AuthenticationException {  
  12.   
  13.         // token是用户输入的  
  14.         // 第一步从token中取出身份信息  
  15.         String userCode = (String) token.getPrincipal();  
  16.   
  17.         // 第二步:根据用户输入的userCode从数据库中查询  
  18.         // 模拟从数据库查询到密码  
  19.         String password = "111111";  
  20.   
  21.         // 如果查询到返回认证信息AuthenticationInfo  
  22.   
  23.         SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(  
  24.                 userCode, password, this.getName());  
  25.         return simpleAuthenticationInfo;  
  26.     }  
  27. }  

 

3.配置shiro-realm.ini文件

[html]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. [main]  
  2. #自定义realm  
  3. customRealm=cn.itcast.shiro.realm.CustomRealm  
  4. #将realm设置到securityManager,相当于spring中注入  
  5. securityManager.realms=$customRealm  

4.创建认证代码

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1.  // 用户登录和退出  
  2. @Test  
  3. public void testCustomRealm() {  
  4.   
  5.     // 创建securityManager工厂,通过ini配置文件创建securityManager工厂  
  6.     Factory<SecurityManager> factory = new IniSecurityManagerFactory(  
  7.                 "classpath:shiro-realm.ini");  
  8.   
  9.     // 通过工厂创建SecurityManager  
  10.     SecurityManager securityManager = factory.getInstance();  
  11.   
  12.     // 将securityManager设置到运行环境中  
  13.     SecurityUtils.setSecurityManager(securityManager);  
  14.   
  15.     // 创建一个Subject实例,该实例认证要使用上边创建的securityManager进行  
  16.     Subject subject = SecurityUtils.getSubject();  
  17.   
  18.     // 创建token令牌,记录用户认证的身份和凭证即账号和密码  
  19.     UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",  
  20.                 "111111");  
  21.   
  22.     try {  
  23.         // 用户登陆  
  24.         subject.login(token);  
  25.     } catch (AuthenticationException e) {  
  26.         // TODO Auto-generated catch block  
  27.         e.printStackTrace();  
  28.     }  
  29.   
  30.     // 用户认证状态  
  31.   
  32.     Boolean isAuthenticated = subject.isAuthenticated();  
  33.   
  34.     System.out.println("用户认证状态:" + isAuthenticated);  
  35.   
  36.     // 用户退出  
  37.   
  38.     subject.logout();  
  39.   
  40.     isAuthenticated = subject.isAuthenticated();  
  41.   
  42.     System.out.println("用户认证状态:" + isAuthenticated);  
  43.   
  44. }  

5.认证流程

1)创建token令牌,token中有用户提交的认证信息即账号和密码

2)执行subject.login(token),最终由securityManager通过Authenticator进行认证

3Authenticator的实现ModularRealmAuthenticator调用realm从数据库中取用户真实的账号和密码

4CustomRealm先根据token中的账号去数据库中找该账号,如果找不到则给ModularRealmAuthenticator返回null,如果找到则匹配密码,匹配密码成功则认证通过。

6.测试

登录时用户认证成功,退出时用户认证失败。

 

shiro授权

授权流程


 

授权方式

shiro支持三种方式的授权:

1.编程式

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. Subject subject = SecurityUtils.getSubject();  
  2. if(subject.hasPermission(“admin”)) {  
  3. //有权限  
  4. else {  
  5. //无权限  
  6. }  

2.注解式

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. @RequiresPermissions("admin")  
  2. public void hello() {  
  3. //有权限  
  4. }  

3.JSP/GSP标签

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. <shiro:hasPermission name="admin">  
  2. <!— 有权限—>  
  3. </shiro:hasRole>  

web系统集成中使用后两种方式,我在这儿举个简单的例子就用第一种方式了。

实例

1.自定义realm

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1.    // 用于授权  
  2. @Override  
  3. protected AuthorizationInfo doGetAuthorizationInfo(  
  4.         PrincipalCollection principals) {  
  5.     // 获取身份信息  
  6.     //将getPrimaryPrincipal方法返回值转为真实身份类型(在上边的doGetAuthenticationInfo认证通过填充到Simpl)  
  7.     String username = (String) principals.getPrimaryPrincipal();  
  8.       
  9.     // 根据身份信息从数据库中查询权限数据  
  10.     // ....这里使用静态数据模拟  
  11.     List<String> permissions = new ArrayList<String>();  
  12.     permissions.add("user:create");  
  13.     permissions.add("user:delete");  
  14.   
  15.     // 将权限信息封闭为AuthorizationInfo  
  16.     SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();  
  17.     for (String permission : permissions) {  
  18.         simpleAuthorizationInfo.addStringPermission(permission);  
  19.     }  
  20.   
  21.     return simpleAuthorizationInfo;  
  22.   
  23. }  

2.配置shiro-realm.ini文件与上面认证配置文件相同

3.创建授权代码

[java]  view plain  copy
 
 在CODE上查看代码片派生到我的代码片
  1. // 自定义realm进行资源授权测试  
  2. @Test  
  3. public void testAuthorizationCustomRealm() {  
  4.   
  5.     // 从ini文件中创建SecurityManager工厂  
  6.     Factory<SecurityManager> factory = new IniSecurityManagerFactory(  
  7.             "classpath:shiro-realm.ini");  
  8.   
  9.     // 创建SecurityManager  
  10.     SecurityManager securityManager = factory.getInstance();  
  11.   
  12.     // 将securityManager设置到运行环境  
  13.     SecurityUtils.setSecurityManager(securityManager);  
  14.   
  15.     // 创建主体对象  
  16.     Subject subject = SecurityUtils.getSubject();  
  17.   
  18.     // 对主体对象进行认证  
  19.     // 用户登陆  
  20.     // 设置用户认证的身份(principals)和凭证(credentials)  
  21.     UsernamePasswordToken token = new UsernamePasswordToken("zhangsan",  
  22.             "111111");  
  23.     try {  
  24.         subject.login(token);  
  25.     } catch (AuthenticationException e) {  
  26.         // TODO Auto-generated catch block  
  27.         e.printStackTrace();  
  28.     }  
  29.   
  30.     // 用户认证状态  
  31.     Boolean isAuthenticated = subject.isAuthenticated();  
  32.   
  33.     System.out.println("用户认证状态:" + isAuthenticated);  
  34.   
  35.     // 授权检测,失败则抛出异常  
  36.     // subject.checkRole("role22");  
  37.   
  38.     // 基于资源授权  
  39.     System.out.println("是否拥有某一个权限:" + subject.isPermitted("user:delete"));  
  40.     System.out.println("是否拥有多个权限:"  
  41.             + subject.isPermittedAll("user:update", "user:delete"));  
  42.   
  43.     // 检查权限  
  44.     subject.checkPermission("user:delete");  
  45.   
  46. }  

4.授权流程

1)执行subject.isPermitted("user:delete")

2securityManager通过ModularRealmAuthorizer进行授权

3ModularRealmAuthorizer调用realm获取权限信息

4ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

5.测试


表明该用户拥有delete权限但是不拥有update权限。

 

转载:http://blog.csdn.net/u010539352/article/details/51220276

转载于:https://www.cnblogs.com/fengli9998/p/6560331.html

相关文章:

  • 时间处理的一些代码片段
  • 自动化-----saltstack基础技术
  • 排序算法(java版)
  • 初学ArcGIS API for JavaScript
  • 倒排列表求交集算法汇总
  • BZOJ 4195: [Noi2015]程序自动分析 [并查集 离散化 | 种类并查集WA]
  • UIButton的titleLabel不同状态字体判断
  • STM32 Flash Download failed
  • H5+css从入门到精通
  • xpath与css的区别
  • PHP类与对象
  • malloc函数及用法
  • SQL基础操作指令
  • IP首部格式[转载]
  • Cisco配置VLAN+DHCP中继代理+NAT转发上网
  • 77. Combinations
  • CSS 三角实现
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Linux快速复制或删除大量小文件
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • php ci框架整合银盛支付
  • React16时代,该用什么姿势写 React ?
  • Ruby 2.x 源代码分析:扩展 概述
  • spring boot 整合mybatis 无法输出sql的问题
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 基于游标的分页接口实现
  • 前端临床手札——文件上传
  • 软件开发学习的5大技巧,你知道吗?
  • 手写一个CommonJS打包工具(一)
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 用Python写一份独特的元宵节祝福
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 在Unity中实现一个简单的消息管理器
  • #define与typedef区别
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • #在 README.md 中生成项目目录结构
  • (3)STL算法之搜索
  • (day 12)JavaScript学习笔记(数组3)
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)Oracle存储过程编写经验和优化措施
  • .gitignore文件—git忽略文件
  • .Net Memory Profiler的使用举例
  • .Net 应用中使用dot trace进行性能诊断
  • .NET成年了,然后呢?
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • @EnableConfigurationProperties注解使用
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...