01 什么是认证
用户认证主要目的就是验证用户身份是否合法,通过验证才能进一步访问系统数据和资源,否则拒绝访问。常见用户身份认证方式,包括用户名密码登录、二维码登录、手机短信登录和指纹认证等方式。
02 什么是会话
用户通过认证后,使用会话保存登录信息避免用户每次操作进行认证。会话,就是系统为了保持当前用户登录状态所提供的机制,常见有基于Session和Token方式。
2.1 Session认证方式
Session认证交互流程,也就是服务端用户认证成功生成用户数据保存到当前会话Session,客户端接收SesssionId存储到Cookie,客户端请求时携带SessionId就可以验证服务器端是否存在Session数据,以此完成用户合法校验。当用户退出系统或Session过期销毁时,客户端SessionId也就无效了。
2.2 Token认证方式
Token认证交互流程是,服务端用户认证成功生成Token发给客户端,客户端接收到Token认证数据存储到Cookie或LocalStorage。客户端每次请求携带Token,服务端接收到Token通过验证后即可确认用户身份。
2.3 总结
Session认证方式是基于Servlet规范定制,服务端存储Session需要占用内存资源,同样客户端也需要支持Cookie才能存储会话。然而,Token认证方式一般不需要服务端存储Token,并且不限制客户端存储方式。如今,移动互联网时代更多类型客户端需要接入系统,系统多是采用前后端分离架构进行实现,所以基于Token认证方式更适合。
03 什么是授权
认证目的为了保证用户身份合法性,授权则是基于认证通过后,根据认证用户权限控制资源访问过程,拥有资源的访问权限则正常访问,没有权限则拒绝访问,从而实现更细粒度控制数据访问权限。比如,用户微信登录成功后,即可使用添加好友、微信聊天和发朋友圈等功能。但是,如果用户没有绑定银行卡,则无法使用红包功能。
总而言之,授权就是定制化用户访问权限,然后根据访问权限控制是否能够访问系统两大维度资源,包括功能和数据两个资源。
3.1 授权数据模型
授权数据模型解决如何控制用户资源访问,也就是谁(Who)对资源(What/Which)进行怎样(How)操作。
| 模型组件 | 组件解释 |
|---|---|
| Who | 也就是主体(Subject),一般是用户,也可以是程序,需要访问系统资源。 |
| What | 也就是资源(Resource),包括功能资源和数据资源。 其中,功能资源包括系统菜单、页面和按钮等,对应系统通常就是一个URL。然而,数据资源包括系统商品信息、系统订单信息,都属于实体资源。实体资源由资源类型和资源实例组成,比如商品编号为001的商品为资源实例。 |
| How | 也就是权限/许可(Permission),规定用户访问资源的操作许可。权限需要要依赖资源进行约定,否则没有意义。 |
3.1.1 授权完整数据模型
主体目的就是根据权限访问对应资源,所以为了控制资源访问就引入了授权数据模型,主要包括主体、资源、权限和角色核心组件,以及组件之间关系通过单独表约束。
| 模型组件 | 内容 |
|---|---|
| 主体(用户) | 用户ID、账号、密码、盐... |
| 资源 | 资源ID、资源名称、访问地址... |
| 权限 | 权限ID、权限标识、权限名称、资源ID... |
| 角色 | 角色ID、角色名称... |
| 主体和角色关系 | 用户ID、角色ID... |
| 角色与权限关系 | 角色ID、权限ID... |
| 权限与资源关系 | 权限ID、资源ID... |
3.1.2 授权简化数据模型
简化模型融合资源 + 权限=权限表,简化模型之间关联关系。
| 模型组件 | 内容 |
|---|---|
| 主体(用户) | 用户ID、账号、密码、盐... |
| 资源权限 | 资源ID、资源名称、访问地址、权限ID、权限标识、权限名称... |
| 角色 | 角色ID、角色名称... |
| 主体和角色关系 | 用户ID、角色ID... |
| 角色与权限关系 | 角色ID、权限ID... |
3.2 RBAC
如何实现授权?业界通常基于RBAC实现授权。
3.2.1 基于角色访问控制
RBAC基于角色访问控制(Role-Based Access Control)是按角色进行授权,比如主体角色为总经理可以查询企业运营报表、查询员工工资信息等。
if(主体.hasRole("总经理角色")) {
查询薪资
} else {
throw new AccessControlException("没有访问权限");
}
用户需要访问资源就需要和角色进行绑定,缺点就是会导致角色膨胀,每个用户访问系统资源需要绑定很多角色,营运专员可维护性差。
3.2.2 基于资源访问控制
RBAC基于资源访问控制(Resource-Based Access Control)是按资源(或权限)进行授权,比如用户必须具有查询工资权限才可以查询员工工资信息。
if(主体.hasPermission(("查询薪资权限标准")) {
查询薪资
} else {
throw new AccessControlException("没有访问权限");
}
基于授权模型进行设计,系统仅需定义功能访问权限标识,用户如果需要访问某个资源进行维护角色权限列表即可,增加可扩展性。