使用Shiro和token进行无状态登录

使用Shiro和token进行无状态登录

        我们之前可以使用shiro实现登录,但这些都是基于session或是cookie实现的,这些只能用于单机部署的服务,或是分布式服务共享会话,显然后者开销极大,所以JWT(JSON Web Token)应运而生,JWT是一套约定好的认证协议,通过请求携带令牌来访问那些需鉴权的接口。

        我们在这里使用token,原理类似,但是规则更为简单,没有形式上的约束,只是在请求Head或是body中添加token用于校验用户身份,token是可以和会话共存的,此处我们使用Shiro的会话登录结合JWT来实现无状态登录,从而实现扫码登录和一般的接口访问授权。

        项目中,需要实现无状态登录(单点登录,SSO),但是同时也要保持Shiro本身自带的会话登录。

有关token

     此文中有关token和SSO的叙述比较粗略,只是大意阐释了流程和部分相关概念。

 token一般的校验流程

 长token与短token

        此处采用OAuth2.0的标准,多数服务都是客户端(浏览器)与服务端后台分离的令牌,前端用于确认用户身份的是短token(通常称access token),而实际保存用户信息(包含用户基本信息、角色、权限等)的是长token(通常称refresh token),只存在后台,以短token映射长token实现用户身份和权限校验。

        这里的长与短,不仅指token所存信息量的多少或是token文本的长度,还指token的有效时间,一般短token对应着会话,存活时间较短,临近过期若用户仍未登出会进行刷新。使用长短token的模式其实近似于 sessionid/uuid+内存或是nosql存储用户实体对象 的处理方案。

 JWT、token

        token相比之下是一个很广泛的定义,一切表示令牌的内容都可以称作是token,jwt算是token中相对很经典、适用范围很广的一套规范,它将用户访问令牌封装在Json格式的数据中,包含在每次请求中。java中相关的实现为auth0的包。

无状态登录与单点登录

        前文中所述的无状态登陆与单点登录还是有所不同的,常见安全框架(例如Shiro)的默认行为是有状态登录,他在cookie中存储了sessionId,同时后台中保存了sessionId对应的用户映射,这样对于每一个sessionId后台都记录了对应的登录信息,有状态的登录缺憾是在集群环境下需要进行session共享,而且功能的实际实现一般都是集成了安全框架,对外不可见,也不便于扩展(扩展可以尝试使用Spring Security安全框架,但是相较Shiro上手门槛较高)。

        而无状态登录就是本文中所说的token验证方式,相比于有状态登录信息默认存储在服务本地内存中,无状态的用户信息(token与信息映射)存储在服务公有资源中,服务的横向扩展是毫无压力的,同时也解决了服务多节点跳动的sessionId变化问题,但是需要考虑token的安全存储。

        总而言之,有状态服务的特点和优缺点为:

为什么需要SSO

        前文中所说的此网站扫码登录需要用到SSO,凭此将用户的登录状态由手机客户端转移至浏览器中,但是这种情况下的登录状态转移是SSO的落地实现,并不能很好的解释为什么要通过SSO实现它。例如,我们也可以将用户名和密码加密后直接传入扫码网站实现登录,但这么做显然是不合时宜的,主要因为:

  1. 安全性没有保障,不使用单点登录就要求用户端留存相关密码密钥,这样一来很容易直接泄露不更改便永久有效的密码,而不是一段会过期的token;

  2. 有些使用登录中心的应用跟客户端(浏览器)并不互相信任,例如对接第三方平台(QQ、微信等)实现登陆,第三方肯定不能将用户的全部信息传回,他们反而把整个登陆过程承包了下来,返回给我们的只是用户能对外公开的基本信息,或是一段id,每次都要请求第三方再校验;

业务处理

 假定的一般实现:不使用框架

        假如实现登录功能不使用框架(Shiro),而只在后台使用生成jwt的相关依赖,我们需要一片能被所有服务访问的公共存储维护用户的在线信息,最佳手段是采取诸如nosql的k-v存储,此处假定采用redis实现,那么需要在redis中存储如下数据:

        但是因为需要将用户的token存在前端,参考上文中的长短token,我们还需要存储用户到短token的映射,可将上面的用户标识直接更正为短token(或者可以使用自定义的sessionId,注意务必确保全局唯一)。

 流程设计

    基于以上的思想,设计使用Shiro的单点登录,整体方案的实施需要两个主要的模块,身份认证和安全控制,本篇身份认证采用jwt,安全控制采用Shiro框架。

流程设计如下:


2019-10-15鱼鱼

{{blog.title}}

创建于 {{blog.createTimeStr}}   created  by  {{blog.author}} {{tag}}
最后修改于 {{blog.timelineStr}}
修改文档