JWT对SpringCloud进行系统认证和服务鉴权

一、为什么要使用jwt?
在微服务架构下的服务基本都是无状态的,传统的使用session的方式不再适用,如果使用的话需要做同步session机制,所以产生了了一些技术来对微服务架构进行保护,例如常用的鉴权框架Spring Security OAuth2和用Jwt来进行保护,相对于框架而言,jwt较轻,且可以自包含一些用户信息和设置过期时间,省去了Spring Security OAuth2繁琐的步骤。

二、什么是JWT?
jwt(JSON WEB TOKEN)是一种用来在网络上声明某种身份的令牌(TOKEN),它的特点是紧凑且自包含并且基于JSON,通过一些常用的算法对包含的主体信息进行加密,安全性很高。它通常有三个部分组成:头信息(Header),消息体(Payload),签名(Signature)。
Header通常用来声明令牌的类型和使用的算法,Payload主要用来包含用户的一些信息,Signature部分则是将Base64编码后的Header和Payload进行签名。

三、在Spring Cloud 下如何使用 jwt?
在SC(Spring Cloud简称,以下将都采用这种方式)下通常使用需要安全保护的有两处,分别为系统认证和服务内部鉴权。
1系统认证
(1)基本流程
jwt基本使用方式如下图

用户在提交登录信息后,服务器校验数据后将通过密钥的方式来生成一个字符串token返回给客户端,客户端在之后的请求会把token放在header里,在请求到达服务器后,服务器会检验和解密token,如果token被篡改或者失效将会拒绝请求,如果有效则服务器可以获得用户的相关信息并执行请求内容,最后将结果返回。
在微服务架构下,通常有单独一个服务Auth去管理相关认证,为了安全不会直接让用户访问某个服务,会开放一个入口服务作为网关gateway,只允许外网网关,所有请求首先访问gateway,有gateway将请求路由到各个服务,spring cloud下通常使用zuul来实现网关,整个基本过程如下图所示

客户端请求网关后,网关会根据路径过滤请求,是登录获取token操作的路径则直接放行,请求直接到达auth服务进行登录操作,之后进行JWT私钥加密生成token返回给客户端;是其他请求将会进行token私钥解密校验,如果token被篡改或者失效则直接拒绝访问并返回错误信息,如果验证成功经过路由到达请求服务,请求服务响应并返回数据。
(2)如何实现登录、刷新、注销等?
登录比较简单,在验证身份信息后可以使用工具包例如jjwt根据用户信息生成token并设置有效时长,最后将token返回给客户端存储即可,客户端只需要每次访问时将token加在请求头里即可,然后在zuul增加一个filter,此filter来过滤请求,如果是登录获取token则放行,其他的话用公钥解密验证token是否有效。
如果要实现刷新,则需要在生成token时生成一个refreshKey,在登录时和token一并返回给客户端,然后由客户端保存定时使用refreshKey和token来刷新获取新的有效时长的token,这个refreshKey可自定义生成,为了安全起见,服务器可能需要缓存refreshKey,可使用redis来进行存储,每次刷新token都将生成新的refreshKey和token,服务器需要将老refreshKey替换,客户端保存新的token和refreshKey来进行之后的访问和刷新。
如果要实现注销,并使得旧的token即便在有效期内也不能通过验证,则需要修改登录、刷新、和优化zuul的filter。首先在登录时生成token和refreshKey后,需要将token也进行缓存,如果通过redis进行缓存可以直接放一个Set下,此Set存储所有未过期的token。其次,在刷新时在这个Set中删除旧的token并放入新的。最后对zuulFilter进行优化,在解密时先从redis里存放token的Set查找此token是否存在(redis的Set有提供方法),如果没有则直接拒绝,如果有再进行下一步解密验证有效时长,验证有效时长是为了防止刷新机制失效、没有刷新机制、网络异常强行退出等事件出现,在这种情况下旧的token没有被删除,导致了旧的token一直可以访问(如果只验证是否token是否在缓存中)。在注销时只需要删除redis中Set的token记录就好,最后写个定时器去定时删除redis中Set里面过时的token,原因也是刷新机制失效、没有刷新机制、网络异常强行退出等事件出现导致旧的token没有被删除。

四、JWT存在的问题
jwt第一次生成token 的时候会比较慢,而且因为采用了加密算法保证安全,所以比较耗CPU,在高并发的情况下需要考虑CPU占用问题。还有一个问题,jwt生成的token比较长,可能需要考虑流量问题。

————————————————
原文链接:https://blog.csdn.net/qq_36236890/article/details/79954647

最新文章

  1. Symbols
  2. Vijos1392拼拼图的小衫[背包DP|二维信息DP]
  3. MySQL的分页
  4. PHY
  5. Nutch 2.2+MySQL+Solr4.2实现网站内容的抓取和索引
  6. POP动画引擎中Layer与CALayer的一点区别
  7. [.NET | 發佈] 如何指定固定的目錄給程式調用的外部DLL?
  8. 编译的时候出现 usr/bin/ld: cannot find -lxxx 的错误
  9. Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
  10. Vue语法学习第二课——指令
  11. 关于VS Code使用注意
  12. 【代码笔记】Web-JavaScript-Javascript对象
  13. 淘淘商城之SSM框架整合概要
  14. ASP.NET Core 实现用户登录验证的最低配置
  15. win10 在任务栏添加 desktop 快捷图标
  16. oracle 分页 where 三层
  17. [iOS] UICollectionView实现图片水平滚动
  18. 【转】 CRC循环冗余校验码
  19. 计蒜客 NOIP 提高组模拟竞赛第一试 补记
  20. 企业证书安装App

热门文章

  1. 品优购商城项目(六)CAS客户端与SpringSecurity集成
  2. Webpack 4 SplitChunksPlugin配置方案(转)
  3. WeQuant教程—1.4 实践教学:比特币量化定投
  4. Navicat连接Mysql8.0.11出现1251错误
  5. docker swarm集群搭建及使用Portainer、shipyard
  6. 晶体管放大电路与Multisim仿真学习笔记
  7. Kubernetes+Istio
  8. 90% 前端开发者都不知道的 JavaScript 实用小技巧
  9. JAVA–利用Filter和session防止页面重复提交
  10. 【LeetCode】 #7:反转整数 C语言