首页 > 技术文章 > 【认证与授权】1、基本概念

youngdeng 2020-05-11 14:13 原文

在互联网中我们一致都有提到或接触到关于认证和授权概念或名字,那到底什么是认证?什么是授权?他们两又有什么联系和区别呢?本系列将记录自己近一段时间学习和实践的过程,以便加深理解过程。

我们先来一起认识两个单词authentication和 authorization,有没有发现什么特点,我第一次接触到的时候,我一直都分不清楚这两个单词的意思(其实就是英语差)。直到后续学习的过程中经常会碰到它们,我才理解了这两个词的意思,在接下来的文章中,你也可能会经常看见它们。

1|01.1 什么是认证

在互联网中,我们每天都会使用到各种各样的APP和网站,在使用过程中通常还会遇到需要注册登录的情况,输入你的用户名和密码才能正常使用,也就是说成为这个应用的合法身份才可以访问应用的资源,这个过程就是认证。当然认证的方式有很多,常见的账号密码登录,手机验证码登录,指纹登录,刷脸登录等等。

2|01.2 什么是会话

当一个用于认证通过以后,为了避免用户的每次操作都进行认证,这个时候就需要保持一个用户认证状态的会话,常见的认证会话机制有很多,例如session认证,token认证等。

基于session的认证方式

用户认证成功后,在服务端生成用户相关的数据保存在当前会话session中,发给客户端的 SesssionId会存放到 cookie 中,这样用户客户端请求时带上 SesssionId 就可以验证服务器端是否存在 session 数 据,以此完成用户的合法校验,当用户退出系统或session过期销毁时,客户端的SesssionId也就无效了。

Session.jpg

基于token的认证方式

用户认证成功后,服务端生成一个token发给客户端,客户端可以放到 cookie 或 localStorage等存储中,每次请求时带上 token,服务端收到token通过验证后即可确认用户身份。

token.jpg

基于session的认证方式由Servlet规范定制,服务端要存储session信息需要占用内存资源,客户端需要支持cookie;

基于token的方式则一般不需要服务端存储token,并且不限制客户端的存储方式。如今移动互联网时代 更多类型的客户端需要接入系统,系统多是采用前后端分离的架构进行实现,所以基于token的方式更适合。

3|01.3 什么是授权

授权是用户认证通过根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则正常访问,没有 权限则拒绝访问。例如视频网站的VIP用户,可以查看到普通用户看不到的资源信息。

4|01.4 授权的数据模型

授权过程中,我们需要知道如何对用户访问的资源进行控制,需要了解一些简单的授权数据模型。

授权可以非常简单的理解成谁(Who)对什么(What)进行怎么样(How)的操作。

  • Who 即主体(Subject),一般指用户,也可以是应用程序
  • What 即资源(Resource),例如商品信息,订单信息,页面按钮或程序中的接口等信息。
  • How 即权限(Permission),规定了用户或程序对资源操作的许可。例如普通用户只能查看订单,管理员可修改或删除订单,这是因为普通用户和管理员用户对订单资源的操作权限不一样。

通常主体、资源、权限相关的数据模型通常会包含以下几个部分

  • 主体Subject(用户ID,账号,密码...)
  • 资源Resource(资源ID,资源名称,访问地址...)
  • 权限Permission(权限ID、权限标识、权限名称,对应的资源ID...)
  • 角色Role(角色ID,角色名称...)

授权模型1.jpg

你会发现权限中包含了一个资源ID,多个权限可指向一个资源,我们是否可以直接在权限信息中把资源信息包含进来呢?当然,这也是很多企业开发中的做法,将权限和资源合并为 权限(权限ID、权限标识、权限名称、资源名称、资源访问地址、...)

授权模型2.jpg

5|01.4 RBAC设计模型

5|11.4.1 基于角色的访问控制

RBAC基于角色的访问控制(Role-Based Access Control)是按角色进行授权。

例如当用户角色为总经理时,他就可以查询公司的某员工的工资情况,用伪代码的方式我们可以这样表示

if(Subject.hasRole("总经理角色ID")){ // 查询员工工资 }

现在突然来了个需求,要求公司的部门经理也可以查看员工的工资情况,怎么做呢?再加一个判断就好了嘛

if(Subject.hasRole("总经理角色ID") || Subject.hasRole("部门经理角色ID")){ // 查询员工工资 }

这时候我们发现了一个问题,当哪天修改角色的权限时,就需要修改授权相关的代码,系统可扩展性较差。

5|21.4.2 基于资源的访问控制

RBAC基于资源的访问控制(Resource-Based Access Control)是按资源(或权限)进行授权。

同样是上面的需求,这时候我们的代码变成了

if(Subject.hasPermission("查询员工工资的权限标识")){ // 查询员工工资 }

当哪天行政主管角色的用户需要查询员工的工资时,我们只需要为行政主管的角色添加一个查询员工工资的权限即可,不需要去修改授权相关的代码,系统的可扩展性增强了。

推荐阅读