个人博客传送门


一. 权限体系描述

权限体系做为系统工程中比较重要的基础模块,因此一套完善和灵活的权限体系方案可以更好的为系统的安全赋能。完善的权限体系,需要依赖于一套完备的解决方案,在整个体系的建立过程中可以分为两个部分(认证和鉴权)实现,并且这两个部分没有强依赖性,可以根据业务的不同选择不同的类型进行组合。

  • 认证(身份识别)
    • 认证方式(账号密码、手机验证码、第三方账号登录等)
    • 认证协议(cas、jwt、oauth2等)
  • 鉴权(访问行为管控)
    • 权限模型(RBAC、ABAC、DAC、MAC)
    • 鉴权模型(shrio、casbin、access list)

二. 认证

认证过程(登录)是一个系统工程的门户也是访问的第一步,只有进行认证过的浏览器才可以进行后续的操作,但是很多时候会将认证的方式和认证的协议搞混,其实这里可以看到认证的方式可以多种多样的(甚至可以进行组合成认证链),而且认证的协议也可以是多种多样的,不管是独立的认证还是进行单点登录的认证都可以根据自己的业务进自由组合。

2.1 认证方式

认证方式(登录方式),随着越来越多的业务场景和一些复杂的环境的要求,诞生出来不同的登录方式,在不同的业务场景下可以进行自主的选择和叠加,分为独立认证方式和叠加认证两种方式。

2.1.1 独立认证
  • 账号密码登录

    ​ 目前最常使用,但是安全性也是最低的一种认证方式,因此一般会采用一些措施保证登录安全和帐号安全。

    • 检测长时间使用同一密码进行强制修改密码操作
    • 对登录过程中的数据进行加密传输
    • 对数据的存储进行加随机盐等安全的密码方式进行脱敏存储(防止撞库)
  • 手机验证码登录

    ​ 手机验证码有着快速登录认证的特点,因此会有一部分系统选择使用手机验证码进行登录,但是也会存在一定的风险。

    • 短信验证码防盗刷
    • 短信验证码超时机制
  • 第三方登录(运营商、微信、支付宝等)

    ​ 越来越多的第三方登录方式(微信为主),由第三方进行认证的主要流程,然后应用后端进行认证结果的判断,例如微信传入openId,应用后端就需要进行账号和openId的关联。

2.1.2 叠加认证(认证链)

由于单一的认证场景下并不能保证认证过程的安全性,因此可以根据不同的业务场景进行认证方式的组合和叠加。

  • 账号密码+短信验证码
  • 账号密码+邮箱验证

2.2 认证协议

认证的协议是认证结果完成之后认证票据的表达形式,也是认证过程中的一部分,因此需要了解不同的认证协议所应对的不同的认证场景,可以在不同的场景下选择合适的认证协议。

2.2.1 CAS

单点登录的协议的一种,通过SSO进行认证的登录操作

浏览器 前端 服务器后端 SSO 访问 访问 返回CAS认证地址 访问 无全局会话,重定向到登录页面 携带登录信息进行登录操作 检验登录信息并且生成TGT 将TGT写入cookie中并且将页面重定向到前端地址 访问 访问 返回CAS认证地址 访问 校验TGT并且生成ST 携带ST返回后端 验证当前的ST信息并且获得用户信息 将token写入到浏览器中 浏览器 前端 服务器后端 SSO
2.2.2 JWT

一种简单的认证协议,因为无状态和服务器无关性,因此具有较好的使用基础,但是也会有一些相应的问题

浏览器 前端 服务器后端 SSO 访问 访问 返回SSO认证地址 访问 无全局会话,重定向到登录页面 携带登录信息进行登录操作 检验登录信息并且生成全局会话 将全局会话写入cookie中并且将页面重定向到前端地址 访问 访问 返回SSO认证地址 访问 校验全局会话并且生成jwt token 携带token返回后端 验证当前的token信息并且获得用户信息 将token写入到浏览器中 浏览器 前端 服务器后端 SSO

三. 鉴权

做为权限体系的组成部分,鉴权也是至关重要的。再认证完成之后,接下来的访问操作我们都需要根据之前生成的认证结果进行权限的校验和判断,这部分的设计也可以分为两部分:权限模型鉴权模型

3.1 权限模型

权限模型的选择也需要去根据具体的业务进行选择,主流的权限模型分为四种:

自主访问控制(DAC,Discretionary Access Control)

强制访问控制 (MAC,Mandatory Access Control)

基于角色访问控制 (RBAC,Role-based Access Control)

基于属性访问控制 (ABAC,Attribute-based Access Control)

比较常用的则是后面两种,我们就后面两种的使用场景进行讲解。

3.1.1 RBAC(基于角色访问控制)

最常使用的一种访问控制模型,基于角色进行授权,将权限关联到角色上,通过角色的授权进行用户的权限管理,这样有利于进行权限的管理,只需要维护角色的权限即可,不用去关心用户的属性。需要注意单个用户拥有多个角色的时候需要进行权限的合并。

权限管控体系
角色和菜单关联表
菜单表
用户和角色关联表
角色表
用户表
3.1.2 ABAC(基于属性访问控制)

基于属性访问控制模型,将权限分裂到不同的属性上,可以针对不同的属性分配不同的权限,适合权限体系多样性的系统,并且可以实时动态变更权限的系统。

权限管控体系
属性和菜单关联表
菜单表
用户和属性关联表
属性表
用户表

3.2 鉴权模型

在鉴权体系中,在确定了权限模型之后,那就需要考虑鉴权模型的建立,通过选择不同的鉴权模型进行权限数据的维护和校验。模型在选择的过程中可以根据不同的需求和权限模型进行选择,目前比较主流的下列三种:

shrio

casbin

access list

3.2.1 shrio

一个Apache开源的安全框架,可以很好的和spring代码进行融合,但是由于shrio在做权限的时候,依赖于接口层面的一些注解(不够灵活),再加上微服务体系中可能会集成进来的别的语言编写的代码,因此在纯java体系并且权限校验的接口变化不频繁的场景下可以选择shrio

3.2.2 casbin

一个支持多种权限模型的框架,可以通过自行配置一些系统的权限规则模型进行权限的校验。因其支持多种不同的模型并且支持鉴权接口的动态配置,再加上语言的无关性,所以有不错的使用基础,但是由于模型配置的问题,导致需要提前预置模型规则

3.2.3 access list

一个基于访问控制列表延申出来的一套方案,通过自行去维护访问的授权列表,来进行权限的校验。由于其只依赖于外部存储和需要预先配置的权限数据,因此不同的体系和不同的资源类型都可以通过这种方式进行配置。

四. 应用

目前的权限体系都是基于边界防护的策略进行落地,即有一个网关进行边界防护进行登录状态的判断和访问权限的校验,通过之后可以进行接口的访问,未通过则返回到登录或者401页面。这个体系下部署的时候需要注意只能暴露出网关的端口别的服务不需要暴露,需要绕过鉴权的接口可以通过配置白名单或者openApI的方式进行访问。

4.1 认证

基于微服务网关进行认证状态的判断,系统的认证状态不依赖于前端进行判断,访问系统所有的请求流量全部打到网关,通过网关进行判断:

白名单: 放行

正常接口: 校验认证结果

  • 已登录:解析结果并且将用户信息set都header中
  • 未登录:返回401或者重定向要前端进行登录操作
4.1.1 方式

采用帐号密码登录的方式进行认证,对传输的过程进行加密传输,对存储的敏感信息(密码)进行加盐加密处理

4.1.2 协议
  • 自行认证

    • 采用jwt协议
  • 单点登录

    单点登录时候需要做到jwt协议和cas协议的通用处理,需要依赖微服务网关的配合

    • jwt协议
    • cas协议
浏览器 前端 服务器后端 SSO redis 访问 init接口获取当前的认证方式(sso/自行认证) 返回SSO认证地址 访问 无全局会话,重定向到登录页面 携带登录信息进行登录操作 检验登录信息并且生成全局会话 将全局会话写入cookie中并且将页面重定向到前端地址 访问 访问 返回SSO认证地址 访问 校验全局会话并且生成ticket 携带ticket返回后端 验证当前的ticket信息并且获得用户信息 通过对解析出来的信息加当前时间戳进行签名生成token 验证当前的jwt token信息并且获得用户信息 alt [sso协议] [jwt协议] 返回当前系统的index地址 携带帐号密码访问后端 通过对解析出来的信息加当前时间戳进行签名生成token alt [sso] [自行认证] 将生成的票据存入到redis中 将token写入到浏览器中 浏览器 前端 服务器后端 SSO redis

4.2 鉴权

基于微服务网关进行权限的校验,首先对用户的登录状态进行判断,然后从获取到的用户的关键信息,通过用户的关键信息和访问的资源进行访问权限的控制。

4.2.1 模型

RBAC(基于角色访问控制),基于角色进行授权,将权限关联到角色上,通过角色的授权进行用户的权限管理,这样有利于进行权限的管理,只需要维护角色的权限即可,不用去关心用户的属性。

4.2.2 方案

采用access list的方式进行权限的校验,将资源分为:菜单、按钮、接口三个维护的资源进行配置

  • 菜单

    ​ 前后端分离的情况下,不能完全依赖于后端去进行菜单权限的校验,可能会出现一些重放菜单url攻击的行为,或者伪造请求路径的行为。登录完成之后能够获取到当前用户拥有的菜单列表,接下来的每次菜单url切换前端可以和之前获取的列表进行比对,在列表内才可访问,不然返回401。

    ​ 通过配置角色的访问菜单列表,通过返回当前用户对应的角色的菜单列表进行访问菜单权限的判断。

  • 按钮

    ​ 通过配置角色的访问菜单和按钮资源,通过返回当前用户对应的角色的菜单和按钮资源进行页面和按钮的加载。

  • 接口

    ​ 不在需要前端传入x-path进行菜单和接口的访问判断,通过referer传入当前访问的代理人的地址,通过该值可以进行跨域访问的拦截和接口访问的控制。

客户端 gateway redis openApI 后端服务 携带请求token访问网关 1.对body体的请求进行重写 通过携带的票据查询redis 返回的结果 2.根据不同的认证协议校验当前的token 将解析出的user_id和adminName放入http的header中 3.对当前用户和访问的资源进行权限校验 4.对openApI进行签名验签等操作 访问指定OpenApI接口 访问指定OpenApI接口 401没有访问权限 alt [验签成功] [验签失败] 401没有访问权限 alt [合法] [非法] 401 alt [redis存在] [不存在] 客户端 gateway redis openApI 后端服务

长按二维码进行关注,获取更多的学习材料。
在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐