一文讲透认证授权的那些事

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战

权限管理一直都是初级程序员学习的一大重点,也是一大难点,有单点登录,有联合登录,有session有Token,有各种权限框架,还有什么是RBAC,以及分布式下如何做权限管理。

1 联合登录与单点登录

image.png

联合登录:

联合登录,就是通过开放认证平台由第三方应用做身份担保,使用户可以活得本系统的相关权限,最常见的身份担保平台就是微信、QQ,当然阿里系的一些应用,支付宝,淘宝也可以为用户做身份担保。

下文中我也将介绍如何基于OAuth 2.0协议做开放认证平台。

单点登录:

单点登录,英文名叫做:Single Sign On,所以也被称为SSO。日常,我们登录了淘宝,再去访问天猫的网站,我们就会发现我们没有登录但是也会保持已登录的状态,这就是所谓的单点登录。

单点登录一般都是集中存储登录状态,我们在访问淘宝需要权限的资源时,会去访问SSO服务,发现没有登录会跳转登录页,当我们登录后访问天猫,天猫会到SSO服务确认我们有没有登录,如果登录了,直接返回天猫,并带上令牌。


联合登录与单点登录区别主要就是: 联合登录是第三方提供身份担保,单点登录是通过统一认证中心确认登录状态。

本质上单点登录的各个系统是完全互信的,联合登录是通过担保互信。

2 Token 与 传统Session 的区别

认证授权方案的产生根本原因是HTTP协议是无状态的,我们无法通过HTTP访问确认用户是否登录,我们只能借助Seeion,或者是Token这些方式去确认用户是否登录,是否具有某些资源的权限。

2.1 Token

现如今大部分系统都是通过Token去做用户的权限担保的,因为Token更适用于分布式系统中,Token本质是基于客户端存储用户身份信息的,服务端不需要存储,天然适用用分布式系统中,有更高的可扩展性。

我们可以通过JWT技术完成Token的生成,解析,服务端直接可以从Token中获取用户的所有有效信息。

但是这也带了一些弊端我们无法手动让Token失效,即使是我们修改密码、注销登录,原来生成的Token依旧是可以使用的,如果我们需要做注销,必须得在借助Redis等集中存储工具,做缓存或者黑名单。

2.2 Session

Session 是Web技术刚刚盛行时使用的一种技术手段,它是将会话存储在服务端的内存中的,如果同时登录的用户很多会极大的耗费服务器资源,并且由于其特性是存在服务端内存中,天然是不具备分布式的,如果我们是多态机器,就得想办法解决分布式Session的问题,一般是将其存储在分布式缓存Redis中。并且Session是依赖于Cookie进行身份识别的,如果cookie被截获,服务器就会受到跨站伪造攻击(CSRF)

3 什么是RBAC?

不论是基于角色的权限访问控制还是基于资源的权限访问控制,都是需要角色的

3.1 基于角色的权限访问控制(旧)

基于角色的权限访问控制RBAC(role-based access control)是以角色为中心进行的访问控制,基于角色的权限访问控制的角色与权限往往是多对多的关系,比如管理员具有增删改查权限,游客只具有查询权限,在做权限访问控制时,是通过判断用户是否有管理员角色,如果新增一个老板的角色,也具备增删改的权限时,就需要将原来的代码修改为是否有管理员或者老板的角色。

缺点:粒度过大,不利于扩展。

3.2 基于资源的权限访问控制(新)

基于资源的权限访问控制RBAC(resource-based access control)是以资源为中心进行的访问控制,基于资源的权限访问控制,资源和权限一对一关系比较常见,比如说用户是管理员,用户有增删改查的权限,而不是说管理员这个角色具有增删改查的权限。都是需要通过角色来分配权限,但是在做权限访问控制时只关心用户是否具备查权限,或者新增修改删除删除权限。

4 认证授权方案的迭代

我们一起看一下权限认证的发展历史。

4.1 单体应用

单体时代一般是单体项目,前后的不分离,大多通过session完成认证授权。

image.png

4.2 Nginx负载

时代发展,出现前后端分离,后端通过Nginx进行负载均衡,这时候Session的弊端逐渐显现,分布式Session,JWT新的替代方案也走上历史的舞台,一般的前后端分离项目都会使用Token做用户身份认证,当然很多都是结合Redis做有状态的权限认证,这样能够很好的完成登录注销操作,也能提升获取用户信息的速度。

image.png

4.3 微服务

大型分布式微服务项目一般采取OAuth2.0做认证授权中心,结合网关处理认证,对应服务管理各自资源的授权。

image.png

5 基于OAuth 2.0的认证授权中心

OAuth 2.0 是一种授权机制,主要用来向第三方颁发令牌(token),它具有四种授权方式授权码,隐藏式,密码式,凭证式。一般我们最常用的就是授权码模式。一般我们实现认证授权中心,可参照一下几种方式,信任度依次递增,信任度越高实现越容易,一般在微服务模式下我们都会采用简易版的权限认证方式,即第三种,第四种。

image.png

2.1 三方不互信

image.png

2.2 第三方信任客户端

image.png

2.3 三方互信

image.png

2.4 服务与服务之间互信

image.png

6 Shiro 与 Spring Security简单对比

Shiro 与 Spring Security 都具备两大主要功能认证与授权,他们都是Java生态下优秀的开源框架。

两者共同具备的条件

  • 简单易用的API
  • 身份认证,支持多种数据源
  • 基于角色、资源的权限控制
  • 简单加密API
  • 支持一级缓存,以提升应用程序的性能
  • 异构客户端会话访问

两者的差异

  • Shiro 不与任何容器框架绑定,可以独立运行
  • Shiro 较于 Spring Security 更加简单易用
  • Shiro 处理密码学有单独的模块
  • Spring Security 较于 Shiro 功能更加全面
  • Spring Security 较于 Shiro 与 Spring 框架融合性更强,但深度绑定也有缺点,脱离Spring基本无法使用
  • Spring Security 对OAuth、OpenID(通过 URI 认证用户身份)也有支持,Shiro则需要自己手动实现

一般Spring Security都是在微服务项目中结合OAuth 2.0 使用。

Guess you like

Origin juejin.im/post/7054706499968303118