登录和鉴权应该是一个完整的系统中几乎必不可少的部分,虽然现在已经有越来越多的框架帮我们简化了这部分工作量,大公司更是有自己专门的登录和权限控制系统,比如阿里的BUC和ACL,开发者仅需要通过简单的步骤便可接入功能完备的登录和权限控制系统,这部分通用能力下沉成为中间件,但没有开源,对小公司而言,登录和鉴权还是得依赖开源的框架,所以在此盘点一下当下最常用的几款登录和鉴权框架:spring-security,apache-shiro,outh2.0.
本专题共分为上下两篇,上篇讲理论,下篇实战.
花絮:什么是RBAC?
开篇前有必要先说一下RBAC,因为目前99%的登录和权限控制框架都是基于RBAC的,RBAC是基于角色的访问控制(Role-Based Access Control
)在RBAC中,权限与角色相关联,用户通过成为适当角色的成员而得到这些角色的权限。这就极大地简化了权限的管理。这样管理都是层级相互依赖的,权限赋予给角色,而把角色又赋予用户,这样的权限设计很清楚,管理起来很方便。
1.Spring-security
SpringSecurity在前几年似乎并没有今天用的人这么多,因为框架比较重,而且配置繁琐,直到springboot出现,局势开始扭转,现在使用Spring全家桶才是主流.SpringSecurity是通过一系列filter过滤器来实现登录和权限的控制,这么说可能比较笼统.引用一张网图(出处见水印)来描述整个SpringSecurity的登录和鉴权过程:
没看懂?没关系,我简化一下上面的步骤,分为两个过程,登录和鉴权:
登录:用户输入账号和密码,发送表单至服务器,服务器通过对用户输入的密码按照创建时相同的加密方式加密,然后与数据库中的账号密码比对,如果一致就通过登录,否则提示用户,这步比较简单.
重点来看鉴权:
由于SpringSecurity和Shiro都是基于RBAC的,所以原理都如这两张图所示,先获取当前用户的角色,然后根据角色获取权限列表,然后逐个判断是否包含所访问内容的权限.
这样看来是不是非常简单?没错,这正是RBAC的强大之处.
聊完了原理再来看看SpringSecurity的几个核心类:
Authentication
Authentication是一个接口,用来表示用户认证信息的,在用户登录后会将用户权限等信息封装进去,然后 保存在SecurityContextHolder 所持有的 SecurityContext 上下文中,供后续调用.
SecurityContextHolder
其实也没啥好说的,但它比较重要,还是啰嗦一下,它就是一个线程安全的Holder,里面用ThreadLocal hold了SecurityContext,提供了静态方法供调用者获取SecurityContext.
AuthenticationManager 和 AuthenticationProvider
AuthenticationManager 是一个用来处理认证请求的接口,如果认证成功后会返回一个包含用户权限等详细信息的Authentication对象,AuthenticationProvider其实就是AuthenticationManager的一个默认实现类,认证成功后的Authentication 对象将会保存在当前的 SecurityContext 中.
Authentication
UserDetailsService中定义了一些可以获取用户名、密码、权限等与认证相关的信息的方法,Authentication对象里的内容其实来源于UserDetails.当然最终还是来源于数据库.
关于SprigSecurity的理论部分就啰嗦这么多,下面看看shiro.
2.Apache-Shiro
Shiro因为其轻量,使用简单,也受到众多开发者青睐,麻雀虽小,五脏俱全.
Shiro的工作过程如图所示:
Subject:主体,可以狭义的理解为当前要登录的对象.
SecurityManager:安全管理器,即所有与安全有关的操作都会与 SecurityManager 交互,管理所有的主体.
Realm:域,泛指从数据库中获取到的如用户、角色、权限等关联信息.
没啥好解释的,shiro本身就比较简单清晰,结合RBAC理论就更好理解了.
完整的工作流程如下图:
①获取主体Suject->②委托给Security Manager去处理->③实际执行者为Autherticator->④选择指定的认证策略->⑤通过Realm(一般是JDBC Realm)去底层数据库拉取用户及角色和权限信息
3.Oauth2.0
Oauth应该是继单点登录以后最大的一个实用功能了,可以极大的提高用户体验.
Oauth是一种协议,开源的协议,举个实际的例子,各位都应该不陌生,我想登录慕课网,但我并不想注册账号,这时候就可以通过
点击这里,比如我点了QQ,就可以通过QQ账号授权给慕课网,避免我再注册个慕课网的账号
授权以后就可以像注册用户一样体验慕课网的全部功能,这种方式真的体验很好,所以Oauth在稍微大一点的系统都会有集成.
关于Oauth的原理我直接引用阮一峰老师的原话:简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用.
单点登录:说简单粗暴一点就是在多个应用系统中只需要登录一次,就可以访问所有彼此信任的系统. 比如我登录了支付宝可以不用再输入账号密码也可以访问淘宝,天猫.
理论部分就啰嗦这么多,有这些基础之后,结合代码就比较好理解了,文中若有不正之处欢迎各路神仙留言斧正.