4A 安全之授权:编程的门禁,你能解开吗?
概述
在安全管理系统里面,授权(Authorization)的概念常常是和认证(Authentication)、账号(Account)和审计(Audit)一起出现的,并称之为 4A。就像上一文章提到的,对于安全模块的实现,最好都遵循行业标准和最佳实践,授权也不例外。
作为安全系统的一部分,授权的职责如下:
- 确保授权过程的可控:常见的参考标准有 OAuth2、SAML2、CAS 等协议
- 确保授权结果的可控:常见的参考标准有 RBAC、ABAC 等授权模型
对于大多数应用来说,主流的做法是基于 OAuth2 + RBAC 的组合搭配实现授权。下面就从这两个方向展开聊聊。
RBAC
RBAC(角色基础访问控制)是一种常见的权限管理方式。在这种模型中,系统根据用户的角色来分配权限,而不是直接分配给单个用户。这样可以简化权限管理和配置的复杂性。避免频繁的对用户进行权限操作。如下:
participant U as 用户
participant R as 角色
participant P as 权限
participant Rsrc as 资源
U->>R: 请求分配角色
R->>P: 拥有权限
P->>Rsrc: 访问资源
note right of U: 用户通过角色获得权限
note right of R: 角色通过权限访问资源
如果还有更复杂的访问控制需求,则可以在 RBAC0 的基础上可以扩展 RBAC1 (层次化 RBAC,角色之间有继承关系)和 RBAC2(受约束的 RBAC,角色之间有互斥关系)来提高系统的安全性和管理的便利性。还有 RBAC 3 等等。
对于大多数应用来说,通常都无需自己去实现这些理论的模型,应用遇到的安全问题大多都是相同的,具有普遍性,所以可以抽象到框架层面来解决,例如著名的 Spring Security 框架就提供 RBAC 模型的授权实现。
不过,需要特别说明的是,与具备通用性的访问控制权限相比,对于数据权限的控制则显的困难的多,用户能访问的数据权限通常与业务高度关联,具体到不同部门,不同角色,甚至指定人员可以访问的数据权限都不尽相同。完全不具备通用性,所以无法通过框架层面解决,就连 Spring Security 框架也未能提供数据权限的相关控制。只能有业务系统结合实际情况各自在业务层实现,这也是目前无法解决的问题。
OAuth 2
OAuth2 是一种业界标准的授权协议,允许用户授权第三方应用程序访问他们在其他服务提供者上的资源,而无需分享用户名和密码,它定义了四种授权交互模式,适用于各种应用场景:
- 授权码模式
- 隐式授权
- 用户模式
- 应用模式
OAuth2 通过发放访问令牌(Access Token)和刷新令牌来实现对受保护资源的访问控制。通过创新的使用访问令牌 Token 替代了用户密码,避免用户凭证的泄露。
授权码
授权码模式可以说是最安全的授权模式,综合考虑了各种风险和防范措置,但相对也是最复杂的授权协议,适合有服务端可以存储密钥(ClientSecret)的场景,授权流程如下:
participant 用户 as 用户
participant 客户端 as 客户端应用
participant 授权服务器 as 授权服务器
participant 资源服务器 as 资源服务器
用户->>+客户端: 访问客户端应用
客户端->>+授权服务器: 请求授权码
授权服务器->>+用户: 请求登录和授权
用户->>+授权服务器: 提供凭证并授权
授权服务器->>+客户端: 返回授权码
客户端->>+授权服务器: 使用授权码请求访问令牌
授权服务器->>+客户端: 发放访问令牌和刷新令牌
客户端->>+资源服务器: 使用访问令牌请求用户数据
资源服务器->>+客户端: 返回用户数据
看完授权码的过程,你可能会觉得好奇:为什么授权服务器要返回授权码,而不直接返回令牌呢 ?
返回授权码而不是直接返回令牌的设计主要是为了提高安全性,原因如下:
- 即使授权码被截获,攻击者因为没有客户端密钥无法获取访问令牌,客户端密钥只在服务器端保存,不会通过前端暴露。
- 在重定向回客户端应用的过程中,授权码会通过浏览器传输。如果直接传输访问令牌,一旦泄露,就会带来更高的安全风险。授权码则可以进行严格的限制(如一次性使用,很短的有效期),所以即使泄露也难以被利用。
- 在客户端使用授权码请求访问令牌时,授权服务器可以验证请求中包含的客户端密钥和重定向 URI 等信息,确保令牌的请求合法
另外令牌颁发的策略上,授权码模式下也使用长刷新令牌 + 短访问令牌的双令牌策略,来最大化减少 JWT 令牌无状态难回收的问题。因此,在服务端可以存储令牌的前提下,授权码模式可以说是大多数场景下的首选。
隐式授权
隐式授权模式对于实在没有服务端存储 ClientSecret 的纯前端应用提供接入支持。接入流程也比较简单,如下:
participant 用户 as 用户
participant 客户端 as 客户端应用
participant 授权服务器 as 授权服务器
participant 资源服务器 as 资源服务器
用户->>+客户端: 访问客户端应用
客户端->>+授权服务器: 请求授权码
授权服务器->>+用户: 请求登录和授权
用户->>+授权服务器: 提供凭证并授权
授权服务器->>+客户端: 发放访问令牌
客户端->>+资源服务器: 使用访问令牌请求用户数据
资源服务器->>+客户端: 返回用户数据
该模式下用户认证通过后授权服务器就直接向客户端返回令牌,无需应用提供 ClientSecret 和通过授权码获取令牌的步骤。但是代价是安全等级降低,令牌有可能在重定向的时候暴露给攻击者。
为了挽救安全等级的问题,OAuth 2 也尽可能做了最大的努力,例如:
- 限制第三方应用的回调 URI 地址必须与注册时提供的域名一致
- 在隐式模式中明确禁止发放刷新令牌
- 令牌必须是 “通过 Fragment 带回” 的(意味着只能通过 Script 脚本来读取,具体参考 RFC 3986)
可以看到隐式授权已经尽最大努力地避免了令牌泄漏出去的可能性。也并非主流的 OAuth 2 接入方式,若非迫不得已,大多数场合不推荐使用。
密码模式
主要是用于一些非浏览器的接入场景,如果要采用密码模式,那“第三方”属性就必须弱化,把“第三方”视作是系统中与授权服务器相对独立的子模块,在物理上独立于授权服务器部署,但是在逻辑上与授权服务器仍同属一个系统,这样将认证和授权一并完成的密码模式才会有合理的应用场景:
participant User as 用户
participant Client as 客户端
participant Server as 授权服务器
User->>Client: 提供用户名和密码
Client->>Server: 请求访问令牌(用户名和密码)
Server->>Client: 返回访问令牌
Client->>Server: 使用访问令牌请求受保护的资源
Server->>Client: 提供受保护的资源
密码模式非常简单,就是拿着用户名和密码向授权服务器换令牌而已。在密码模式下 OAuth2 不负责保障安全,只能由用户和第三方应用来自行提供安全保障。
客户端模式
以应用为主体的授权模式,不涉及到用户的登录行为,是客户端模式是指第三方应用以自己的名义,向授权服务器申请许可凭证。用来访问受保护资源,如下:
participant Client as 客户端
participant Server as 授权服务器
Client->>Server: 提供客户端凭据(客户端ID和密钥)
Server->>Client: 验证凭据并返回访问令牌
Client->>Server: 使用访问令牌请求受保护的资源
Server->>Client: 提供受保护的资源
客户端模式通常是用于微服务之间的访问,例如一些定时任务,应用之间访问授权的操作。在微服务架构并不提倡同一个系统的各服务间有默认的信任关系,所以服务之间调用也需要先进行认证授权,然后才能通信。例如应用层常见的微服务框架 Spring Cloud
就是采用该方案保证服务间的合法调用。
4A 安全之授权:编程的门禁,你能解开吗?的更多相关文章
- RFID Hacking①:突破门禁潜入FreeBuf大本营
某天,偶然间拿到了FreeBuf Pnig0s同学的工卡信息,终于有机会去做一些羞羞的事情了 引子 以下故事纯属虚构,如有雷同,纯属巧合. 我应聘了一个大型IT公司的"网络攻击研究部经理&q ...
- Azure 进阶攻略 | 上云后的系统,「门禁」制度又该如何实现?
各位办公室白领们,不妨回想一下自己每天去公司上班时的一些细节. 为避免「闲杂人等」进入工作场所,我们需要证明自己是这家公司的员工才能进入,对吧!所有员工,无论所属部门或职位,都必须先证明自己身份,例如 ...
- RFID Hacking④:使用ProxMark3 破解门禁
文中提及的部分技术可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使用! 0×00 前言 国际黑客大会Defcon传统之一:开锁!因为黑客认为锁也是一种安全挑战.我们在黑客题材电影.电视剧中也常常 ...
- 手机NFC模拟门禁卡
楼主所在的某电子科技类大学,从宿舍楼到实验楼到图书馆办公楼,全部都有门禁,前两天突然在某安软件市场看到一个可以模拟门禁卡的软件,然而可能是我的手机系统太6了,竟然模拟不了,无奈自己动手,从根本上解决问 ...
- Java 并发专题 : CyclicBarrier 打造一个安全的门禁系统
继续并发专题~ 这次介绍CyclicBarrier:看一眼API的注释: /** * A synchronization aid that allows a set of threads to all ...
- CCF系列之门禁系统(201412-1)
试题编号:201412-1试题名称:门禁系统时间限制: 2.0s内存限制: 256.0MB 问题描述 涛涛最近要负责图书馆的管理工作,需要记录下每天读者的到访情况.每位读者有一个编号,每条记录用读者的 ...
- 大华门禁SDK二次开发(二)-SignalR应用
经过与大华技术支持的沟通,门禁服务程序已经开发好了,可以正常接收门禁开关事件,可以发送开门命令.基于项目实时性要求,这里使用SignalR实现门禁状态.控制命令的实时传送. 几种场景需求 根据Sign ...
- 大华门禁SDK二次开发(一)-技术沟通
项目中需要能够查询门禁信号和控制门禁设备,因此需要基于大华门禁SDK进行二次开发,开发语言C#.门禁开发中遇到了一些问题,经过与大华技术的邮件沟通也一一解决.做这个开发的时候,发现网上的资料比较少,想 ...
- CCF CSP 201412-1 门禁系统
题目链接:http://118.190.20.162/view.page?gpid=T21 问题描述 试题编号: 201412-1 试题名称: 门禁系统 时间限制: 1.0s 内存限制: 256.0M ...
- 利用nexus5伪造一张门禁卡
0×00 前言 我租住的杭州一个老小区一年前出现了所谓的“出租房杀人事件”,事件过后民警叔叔们给小区的每个单元都装上了门禁,所有住户都需要在物业处登记,物业的工作人员会让你提供身份证或者公交卡用来注册 ...
随机推荐
- Python(上机题) 通俗易懂的基础题目解析
python 题目 文章目录 python 题目 题目一:幸运数对 题目二:lambda 函数找最大值 题目三:n个数前后互换 (切片) 题目四:字符串相减(删除指定字符) 方法一:可以用空字符来替换 ...
- apt-get upgrade 和apt-get dist-upgrade区别
kali linux系统或者 debian等系统 以及centos 在系统升级后经常会出现系统无法启动,或者启动之后GUI功能没有的问题: 笔记: 区别这两种用法 apt-get update ...
- 全面解析 Redis 持久化:RDB、AOF与混合持久化
前言: 每次你在游戏中看到玩家排行榜,或者在音乐应用中浏览热门歌单,有没有想过这个排行榜是如何做到实时更新的?当然,依靠 Redis 即可做到. 在技术领域,我们经常听到「键值存储」 这个词.但在 R ...
- C#移除List中特定元素
在List里面移除其中一个元素之后,原有的索引以及索引对应的值会发生改变,如果按照原有的索引值删除,就会误删除其它元素. 1.实现思路 原始List为A,将需要删除的元素放到一个List B里面,遍历 ...
- 单词本z develop vel = 到上面 从下面到上面的一种过程 抽象是相对从无到有
单词本z develop vel = 到上面 从下面到上面的一种过程 抽象是相对从无到有 develop 发展 开发 de = down 下面 velop 这里 vel 就是 lev的反写 op = ...
- .vscode/extensions.json 是项目用到的 插件 推荐列表,项目应该将此配置 写入用到的插件
.vscode/extensions.json 是项目用到的 插件 推荐列表,项目应该将此配置 写入用到的插件 .vscode/extensions.json { "recommendati ...
- k8s中port-forward 、service的nodeport与ingress区别
在Kubernetes中,port-forward.Service的NodePort和Ingress都是用于将外部流量引入集群内部的方法,但它们在使用场景.实现方式和功能上有所不同. port-for ...
- 基于R语言的raster包读取遥感影像
本文介绍基于R语言中的raster包,读取单张或批量读取多张栅格图像,并对栅格图像数据加以基本处理的方法. 1 包的安装与导入 首先,我们需要配置好对应的R语言包:前面也提到,我们这里选择基于 ...
- 大端(big endian) 小端(little endian) --- 在多字节存储 和 多字节通信中的含义(我还是太年轻了)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- Java博客大汇总
目录介绍 01.Java基础[30篇] 02.面向对象[15篇] 03.数据结构[27篇] 04.IO流知识[11篇] 05.线程进程[9篇] 06.虚拟机[12篇] 07.类的加载[7篇] 08.反 ...