? ? ? ? 用户认证就是判断一个用户的身份是否合法的过程,用户去访问系统资源时,系统要求验证用户的身份,身份合法才可以继续访问,身份不合法则拒绝访问,常见的用户认证方式有:用户名/密码、二维码登录、收集短信登录、邮箱登录、指纹认证、刷脸认证等。
? ? ? ? 21世纪是一个信息化的社会,各种PC端、APP端的应用层出不穷,极大地丰富了我们的日常生活,但是在丰富我们生活的同时,因信息安全出现的各种问题也随处可见。拿全民聊天软件微信来说,用户首次使用微信时,一般需要经历 下载===》注册===》登录 这3个流程,而在微信界面输入用户名密码的过程其实就是认证。
? ? ? ? 认证是为了保护系统的隐私数据和资源,用户的身份合法方可访问系统中的资源。
? ? ? ? 用户认证通过后,为了避免用户的每次操作都进行认证,可以将用户的信息保存在会话中。会话就是系统为了保持当前用户的登录状态所提供的机制,常见的有基于session方式、基于Token方式等。
? ? ? ? 用户认证成功后,在服务端生成用户相关的数据保存在session(当前会话)中,发给客户端的session_id保存到cookie中,这样用户客户端再次请求时带上session_id就可以验证服务端是否存在该用户的数据了,以此完成用户的额合法校验,当用户退出系统或者session过期销毁时,客户端的session_id也就无效了。原理图如下:
? ? ? ? 用户认证成功后,服务端生成一个token发给客户端,客户端收到这个token后可以将其放在cookie或者localStorage中,每次请求时带上这个token,服务端收到请求后校验token是否合法,进而验证用户身份。流程如下:
? ? ? ? 基于session的认证方式由Servlet规范定制,服务端要存储session信息会占用内存资源,而且客户端需要支持cookie;基于token的认证方式则一般不需要服务端存储token,并且不限制客户端的存储方式。在如今移动互联网的时代,更多类型的客户需要接入系统,系统多是采用前后端分离的架构进行实现,所以基于token的方式更加合适。
? ? ? ? 授权是用户认证通过后,根据用户的权限来控制用户访问资源的过程,拥有资源的访问权限则正常访问,没有权限则拒绝访问。
? ? ? ? 拿微信来说,用户首次登录成功后,某些功能是可以直接使用的,例如:给朋友发消息、分享动态至朋友圈、看朋友的动态等,而有些功能则需要开通相应的权限后才能进行,例如:发红包,没有绑定银行卡的用户是无法发送红包的,只有绑定银行卡的用户才能发红包,这个根据用户的权限来控制用户使用资源的过程就是授权。
? ? ? ? 认证是为了保护用户身份的合法性,授权则是为了更加细粒度的对隐私数据进行划分,授权是在认证通过后发生的,控制不同的用户能够访问不同的资源。
? ? ? ? 授权的数据模型可以用WWH来形容,即:Who对What【Which】进行How操作,详细解释如下:
Who:即主体(Subject),主体一般是指用户,也可以是程序,需要访问系统中的资源;
What:即资源(Resource),如系统菜单、页面、按钮、代码方法、系统商品信息、订单信息等都属于系统功能资源,对于web系统的每个功能资源通常都对应着一个URL;系统商品信? ? ? ? ? ? ? ? 息、订单信息都属于实体资源(由资源类型 + 资源实例组成),例如商品信息为资源信息,商品编号为100001的商品为资源实例;
How:权限/许可(Permission),规定了用户对资源的操作许可,权限离开资源没有任何意义,如用户查询权限、某个代码方法的调用权限、编号为20201101的用户的修改权限等,通过? ? ? ? ? ? ? ?权限可以知道用户对哪些资源有哪些操作许可。
主体、资源、权限相关的数据模型如下:
主体:用户id、账号、密码...
资源:资源id、资源名称、访问地址...
权限:权限id、权限标识、权限名称,资源id...
角色:角色id、角色名称..
角色权限关联关系:用户id、角色id...
主体(用户)角色关联关系:用户id、角色id...
主体(用户)+ 资源 + 权限关系:
通常情况下,企业开发中会将资源和权限表合并成为一张权限表,如下:
资源:资源id、资源名称、访问地址...
权限:权限id、权限标识、权限名称,资源id...
????????↓
权限:权限id、权限标识、权限名称,资源名称、访问地址...
流程图如下:
? ? ? ? RBAC是基于角色的访问控制(Role Based Access Control)和?基于资源的访问控制(Resource Based Access Control)的简写,具体区别如下:
????????基于角色的访问控制(Role Based Access Control),是按照角色进行授权,比如:主体的角色为总经理,可以查询企业运营报表、查询员工工资信息等,访问控制流程如下:
伪代码:
if (主体.hasRole("总经理角色id")) {
? ? ? ? 查询工资;
} else {
? ? ? ? 权限不足;
}
思考:上述流程存在的弊端是什么?如果需求变化了,部门经理也可以查询工资,那么逻辑就需要修改,修改如下:
if (主体.hasRole("总经理角色id") || 主体.hasRole("部门经理角色id")) {
? ? ? ? 查询工资;
} else {
? ? ? ? 权限不足;
}
弊端:根据上面的例子可知,当需要修改角色的权限时就需要修改授权相关的代码,系统扩展性差(灬? ?灬)!
????????基于资源的访问控制(Resource Based Access Control),是按照资源【权限】进行授权,比如:用户具有查询工资的权限才可以查询员工的工资信息,访问控制流程如下:
伪代码:
if (主体.hasPermission("查询工资权限标识")) {
? ? ? ? 查询工资;
} else {
? ? ? ? 权限不足;
}
优点:
? ? ? ? 系统设计时定义好查询工资的权限标识,即使查询工资所需要的角色变化为总经理和部门经理,也不需要修改授权代码,系统可扩展性强(*^▽^*)!