个人对微服务身份认证与鉴权的认识

发展史和背景

从单体应用架构到分布式应用架构再到微服务架构,应用的架构通过不停的改进升级的方式满足不断扩大的业务需求。随着应用架构的改变,身份认证的方式也在发生变化,为了适应架构的变化、需求的变化,身份认证与鉴权方案也需要不断的变革。

在传统单体应用架构中,身份认证从来都不是问题,简单粗暴的通过一个权限的拦截器,配合session基本都解决了!(这里简单说说session, 因为Http协议是一种无状态协议,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录;session的主要目的就是为了弥补Http的无状态特性。简单的说,就是服务器可以利用session存储客户端在同一个会话期间的一些操作记录。)

在于分布式应用架构中,也有很多处理方式,最流行无非以下几种:

  1. session绑定:即将同一用户的所有请求都分发到同一台服务器上
    优点:简单,不需要对session做任何处理
    缺点:缺乏容错性,如果当前访问的服务器发生故障,用户被转移到第二个服务器上时,它的session信息都将失效。
  2. session复制:任何一个服务器上的session发生改变(增删改),该节点会把这个session的所有内容序列化,然后广播给所有其他节点,不管其他服务器需不需要session,以此来保证session同步。
    优点:可容错,各个服务器间session能够实时响应。
    缺点:会对网络负荷造成一定压力,如果session量大的话,可能会造成网络堵塞,拖慢服务器性能。
  3. session共享:将原本储存在内存中的session,放入一个公共的缓存当中(如redis、memcached),服务器根据请求去缓存中读取session
    优点:可容错,服务器不需要存储session减少内存占用,也是目前最为流行的使用方式

接下主要聊聊在微服务架构中的一些方案和个人理解

微服务架构中的身份认证服务

一、首先说说 David Borsos 在伦敦的微服务大会上提出的四种方案:

1. 单点登录(SSO)

采用单点登录方案,意味着每个面向用户的服务都必须与认证服务交互,这会产生大量非常琐碎的网络流量,同时这个防范实现起来也相当的复杂,同时重构相当麻烦,因为需要兼容所有系统。在其他方面,选择SSO方案安全性会很好,用户登录状态是不透明的,可防止攻击者从状态中推断任何有用的信息。

2. 分布式session

分布式会话方案原理主要是将关于用户认证的信息存储在共享存储中,且通常由用户会话作为 key 来实现的简单分布式哈希映射。当用户访问微服务时,用户数据可以从共享存储中获取。在某些场景下,这种方案很不错,用户登录状态是不透明的。同时也是一个高可用且可扩展的解决方案。这种方案的缺点在于共享存储需要一定保护机制,因此需要通过安全链接来访问,这时解决方案的实现就通常具有相当高的复杂性了。

3. 客户端 Token

令牌在客户端生成,由身份验证服务进行签名,并且必须包含足够的信息,以便可以在所有微服务中建立用户身份。令牌会附加到每个请求上,为微服务提供用户身份验证,这种解决方案的安全性相对较好,但身份验证注销是一个大问题,缓解这种情况的方法可以使用短期令牌和频繁检查认证服务等。对于客户端令牌的编码方案,Borsos 更喜欢使用 JSON Web Tokens(JWT),它足够简单且库支持程度也比较好。

4. 客户端 Token 与 API 网关结合

这个方案意味着所有请求都通过网关,从而有效地隐藏了微服务。 在请求时,网关将原始用户令牌转换为内部会话 ID 令牌。在这种情况下,注销就不是问题,因为网关可以在注销时撤销用户的令牌。

二、个人理解的方案实现 JWT + Zuul + Redis :

其实就是 客户端 Token 与 API 网关结合 的变相实现
因为大部分微服务内部直接调用都默认不用再次验证,因此没有必要再搞一个内部的token,直接将数据取出来简单粗暴的进行交互!
但对于一些特殊的应用,服务与服务之间的调用也设计了权限,像这种情况生成内部token还是确实有必要的!

若对过期要求不高的场景,可以不使用Redis,直接使用 JWT 的过期时间即可
登录流程:

个人对微服务身份认证与鉴权的认识_第1张图片

用户登录,网关判断是不是登录请求
如果是,则访问跳转至认证微服务。在认证微服务验证验证通过后,生成JWT(包括有效器,权限信息或者是转义后的权限信息等)返回,同时将一些隐私信息(包括用户联系方式、权限信息等)存入redis并设置过期时间(略大于 JWT 有效期即可),前端存储JWT,以后的所有请求都需携带 JWT
如果不是,则进行验证流程

验证流程:


个人对微服务身份认证与鉴权的认识_第2张图片

检查用户请求是否携带token,因为是 JWT ,网关可以判断token是否有效,无效则直接返回未登录,有效则向认证微服务请求验证,认证微服务从redis获取该token对应的隐私信息(主要是权限信息,这里因为隐私信息的有效是大于JWT的)认证通过后将隐私信息返回给网关,网关携带隐私信息再访问其它微服务

关键点描述说明
  1. 服务端如何控制token失效?
    当用户修改密码后,直接将redis中的该用户的隐私信息删除掉即可!
    当用户的权限被修改后,直接修改存储在redis中的权限即可,当用户下一次请求过来时,后端自动若发现权限变化了,则自动再生成一个token返回给前端,前端重新存储下token。这样用户既可以不用重新登录,而且权限又得到了很好的控制!
  2. 为什么要将权限存入redis?
    有人可能会说,JWT中已经有权限信息了,为什么我们还需要在redis中保存?JWT不是基本上可以默认为是无法被篡改的吗?这个主意是考虑到用户的权限可能会发生变化,JWT中的权限只是在前端用来控制UI元素显示或是否可点击的,因为我方案是要求Token失效是后台可以随意掌控的,不管权限放不放redis,每次的token验证都是必须查redis的,因此将权限放入redis还可以动态改变!

你可能感兴趣的:(个人对微服务身份认证与鉴权的认识)