0

0

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

黄舟

黄舟

发布时间:2017-01-18 09:27:13

|

2425人浏览过

|

来源于php中文网

原创

授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限。 

如,判断一个用户有查看页面的权限,编辑数据的权限,拥有某一按钮的权限,以及是否拥有打印的权限等等。 

一、授权的三要素 

授权有着三个核心元素:权限、角色和用户。 

权限 

权限是apache shiro安全机制最核心的元素。它在应用程序中明确声明了被允许的行为和表现。一个格式良好好的权限声明可以清晰表达出用户对该资源拥有的权限。 

大多数的资源会支持典型的crud操作(create,read,update,delete),但是任何操作建立在特定的资源上才是有意义的。因此,权限声明的根本思想就是建立在资源以及操作上。 

而我们通过权限声明仅仅能了解这个权限可以在应用程序中做些什么,而不能确定谁拥有此权限。 

于是,我们就需要在应用程序中对用户和权限建立关联。 

通常的做法就是将权限分配给某个角色,然后将这个角色关联一个或多个用户。 

权限声明及粒度 

shiro权限声明通常是使用以冒号分隔的表达式。就像前文所讲,一个权限表达式可以清晰的指定资源类型,允许的操作,可访问的数据。同时,shiro权限表达式支持简单的通配符,可以更加灵活的进行权限设置。 

下面以实例来说明权限表达式。 

可查询用户数据 

user:view 

可查询或编辑用户数据 

user:view,edit 

可对用户数据进行所有操作 

user:* 或 user 

可编辑id为123的用户数据 

user:edit:123 

角色 

shiro支持两种角色模式: 

1、传统角色:一个角色代表着一系列的操作,当需要对某一操作进行授权验证时,只需判断是否是该角色即可。这种角色权限相对简单、模糊,不利于扩展。 

2、权限角色:一个角色拥有一个权限的集合。授权验证时,需要判断当前角色是否拥有该权限。这种角色权限可以对该角色进行详细的权限描述,适合更复杂的权限设计。 

下面将详细描述对两种角色模式的授权实现。 

二、授权实现 

shiro支持三种方式实现授权过程: 

编码实现
注解实现
jsp taglig实现

1、基于编码的授权实现 

1.1基于传统角色授权实现 

当需要验证用户是否拥有某个角色时,可以调用subject 实例的hasrole*方法验证。 

Subject currentUser = SecurityUtils.getSubject(); 

if (currentUser.hasRole("administrator")) { 

//show the admin button 

} else { 

//don't show the button? Grey it out? 

}

相关验证方法如下: 

Subject方法                             描述    

hasRole(String roleName)    当用户拥有指定角色时,返回true    

hasRoles(List roleNames)    按照列表顺序返回相应的一个boolean值数组    

hasAllRoles(Collection roleNames)    如果用户拥有所有指定角色时,返回true    

断言支持 

Shiro还支持以断言的方式进行授权验证。断言成功,不返回任何值,程序继续执行;断言失败时,将抛出异常信息。使用断言,可以使我们的代码更加简洁。 

Subject currentUser = SecurityUtils.getSubject(); 

//guarantee that the current user is a bank teller and 

//therefore allowed to open the account: 

currentUser.checkRole("bankTeller"); 

openBankAccount();

断言的相关方法: 

Subject方法                                    描述    

checkRole(String roleName)    断言用户是否拥有指定角色    

checkRoles(Collection roleNames)    断言用户是否拥有所有指定角色    

checkRoles(String... roleNames)    对上一方法的方法重载    

1.2 基于权限角色授权实现 

相比传统角色模式,基于权限的角色模式耦合性要更低些,它不会因角色的改变而对源代码进行修改,因此,基于权限的角色模式是更好的访问控制方式。 

它的代码实现有以下几种实现方式: 

1、基于权限对象的实现 

创建org.apache.shiro.authz.Permission的实例,将该实例对象作为参数传递给Subject.isPermitted()进行验证。 

Permission printPermission = new PrinterPermission("laserjet4400n", "print"); 

Subject currentUser = SecurityUtils.getSubject(); 

if (currentUser.isPermitted(printPermission)) { 

//show the Print button 

} else { 

//don't show the button? Grey it out? 

} 

Permission printPermission = new PrinterPermission("laserjet4400n", "print"); 

Subject currentUser = SecurityUtils.getSubject(); 

if (currentUser.isPermitted(printPermission)) { 

//show the Print button 

} else { 

//don't show the button? Grey it out? 

}

相关方法如下: 

Subject方法    描述    

isPermitted(Permission p)    Subject拥有制定权限时,返回treu    

isPermitted(List perms)    返回对应权限的boolean数组    

isPermittedAll(Collection perms)    Subject拥有所有制定权限时,返回true    

2、 基于字符串的实现 

相比笨重的基于对象的实现方式,基于字符串的实现便显得更加简洁。 

Subject currentUser = SecurityUtils.getSubject(); 

if (currentUser.isPermitted("printer:print:laserjet4400n")) { 

//show the Print button 

} else { 

//don't show the button? Grey it out? 

}

使用冒号分隔的权限表达式是org.apache.shiro.authz.permission.WildcardPermission 默认支持的实现方式。 

这里分别代表了 资源类型:操作:资源ID 

类似基于对象的实现相关方法,基于字符串的实现相关方法: 

isPermitted(String perm)、isPermitted(String... perms)、isPermittedAll(String... perms) 

基于权限对象的断言实现 

Subject currentUser = SecurityUtils.getSubject(); 

//guarantee that the current user is permitted 

//to open a bank account: 

Permission p = new AccountPermission("open"); 

currentUser.checkPermission(p); 

openBankAccount();

基于字符串的断言实现 

Subject currentUser = SecurityUtils.getSubject(); 

//guarantee that the current user is permitted 

//to open a bank account: 

currentUser.checkPermission("account:open"); 

openBankAccount();

断言实现的相关方法 

Subject方法    说明    

checkPermission(Permission p)    断言用户是否拥有制定权限    

AISEO AI Content Detector
AISEO AI Content Detector

AISEO推出的AI内容检测器

下载

checkPermission(String perm)    断言用户是否拥有制定权限    

checkPermissions(Collection perms)    断言用户是否拥有所有指定权限    

checkPermissions(String... perms)    断言用户是否拥有所有指定权限

   

2、基于注解的授权实现 

Shiro注解支持AspectJ、Spring、Google-Guice等,可根据应用进行不同的配置。 

相关的注解: 

@ RequiresAuthentication 

可以用户类/属性/方法,用于表明当前用户需是经过认证的用户。 

@RequiresAuthentication 

public void updateAccount(Account userAccount) { 

//this method will only be invoked by a 

//Subject that is guaranteed authenticated 

... 

} 

@ RequiresGuest

表明该用户需为”guest”用户 

@ RequiresPermissions 

当前用户需拥有制定权限 

@RequiresPermissions("account:create") 

public void createAccount(Account account) { 

//this method will only be invoked by a Subject 

//that is permitted to create an account 

... 

} 

@RequiresRoles

当前用户需拥有制定角色 

@ RequiresUser 

当前用户需为已认证用户或已记住用户 

3、基于JSP TAG的授权实现 

Shiro提供了一套JSP标签库来实现页面级的授权控制。 

在使用Shiro标签库前,首先需要在JSP引入shiro标签: 

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

下面一一介绍Shiro的标签: 

guest标签 

验证当前用户是否为“访客”,即未认证(包含未记住)的用户 

 

Hi there! Please Login or Signup today! 

user标签 

认证通过或已记住的用户 

 

Welcome back John! Not John? Click here to login. 

authenticated标签 

已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。 

 

Update your contact information. 

 

notAuthenticated标签

未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。 

 

Please login in order to update your credit card information. 

principal 标签 

输出当前用户信息,通常为登录帐号信息 

Hello, , how are you today?

验证当前用户是否属于该角色 

 

Administer the system 

lacksRole标签 

与hasRole标签逻辑相反,当用户不属于该角色时验证通过 

 

Sorry, you are not allowed to administer the system. 

hasAnyRole标签 

验证当前用户是否属于以下任意一个角色。 

 

You are either a developer, project manager, or administrator. 

hasPermission标签 

验证当前用户是否拥有制定权限 

 

Create a new User 

lacksPermission标签 

与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过 

 

Create a new User 

三、Shiro授权的内部处理机制 

305.png

1、在应用程序中调用授权验证方法(Subject的isPermitted*或hasRole*等) 

2、Sbuject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,会委托应用程序设置的securityManager实例调用相应的isPermitted*或hasRole*方法。 

3、接下来SecurityManager会委托内置的Authorizer的实例(默认是ModularRealmAuthorizer 类的实例,类似认证实例,它同样支持一个或多个Realm实例认证)调用相应的授权方法。 

4、每一个Realm将检查是否实现了相同的 Authorizer 接口。然后,将调用Reaml自己的相应的授权验证方法。 

当使用多个Realm时,不同于认证策略处理方式,授权处理过程中: 

1、当调用Realm出现异常时,将立即抛出异常,结束授权验证。 

2、只要有一个Realm验证成功,那么将认为授权成功,立即返回,结束认证。

以上就是Apache Shiro 使用手册(三)Shiro 授权的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
微信文件过期恢复教程
微信文件过期恢复教程

本专题整合了微信文件过期恢复方法、技巧教程,阅读专题下面的文章了解更多详细内容。

0

2026.02.04

抖音网页版入口与视频观看指南 抖音官网视频在线访问
抖音网页版入口与视频观看指南 抖音官网视频在线访问

本专题汇总了抖音网页版的入口链接、官方登录页面以及视频观看入口,帮助用户快速访问抖音网页版,提供免登录访问方式和直接进入视频播放页面的方法,确保顺利浏览和观看抖音视频。

63

2026.02.04

学习通网页版入口与在线学习指南 学习通官网登录与使用方法
学习通网页版入口与在线学习指南 学习通官网登录与使用方法

本专题详细汇总了学习通网页版入口与登录方法,提供学习通官方网页端入口、学生登录平台、网页版使用指南等内容,帮助用户快速稳定地登录学习通官网,顺利进入学习平台,提升学习效率和体验。

9

2026.02.04

Python Web 框架 Django 深度开发
Python Web 框架 Django 深度开发

本专题系统讲解 Python Django 框架的核心功能与进阶开发技巧,包括 Django 项目结构、数据库模型与迁移、视图与模板渲染、表单与认证管理、RESTful API 开发、Django 中间件与缓存优化、部署与性能调优。通过实战案例,帮助学习者掌握 使用 Django 快速构建功能全面的 Web 应用与全栈开发能力。

9

2026.02.04

Java 流式处理与 Apache Kafka 实战
Java 流式处理与 Apache Kafka 实战

本专题专注讲解 Java 在流式数据处理与消息队列系统中的应用,系统讲解 Apache Kafka 的基础概念、生产者与消费者模型、Kafka Streams 与 KSQL 流式处理框架、实时数据分析与监控,结合实际业务场景,帮助开发者构建 高吞吐量、低延迟的实时数据流管道,实现高效的数据流转与处理。

3

2026.02.04

Golang 容器化与 Docker 实战
Golang 容器化与 Docker 实战

本专题深入讲解 Golang 应用的容器化与 Docker 部署,涵盖 Docker 基础概念、容器构建与镜像管理、Go 应用的 Dockerfile 编写、跨平台容器部署与优化、Docker Compose 和 Kubernetes 部署工具。通过实际案例,帮助学习者掌握 如何将 Golang 应用容器化并实现高效部署与管理,提升系统的可扩展性与运维效率。

3

2026.02.04

全国统一发票查询平台入口合集
全国统一发票查询平台入口合集

本专题整合了全国统一发票查询入口地址合集,阅读专题下面的文章了解更多详细入口。

59

2026.02.03

短剧入口地址汇总
短剧入口地址汇总

本专题整合了短剧app推荐平台,阅读专题下面的文章了解更多详细入口。

110

2026.02.03

植物大战僵尸版本入口地址汇总
植物大战僵尸版本入口地址汇总

本专题整合了植物大战僵尸版本入口地址汇总,前往文章中寻找想要的答案。

56

2026.02.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
RunnerGo从入门到精通
RunnerGo从入门到精通

共22课时 | 1.8万人学习

尚学堂Mahout视频教程
尚学堂Mahout视频教程

共18课时 | 3.2万人学习

Linux优化视频教程
Linux优化视频教程

共14课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号