微服务的用户认证与授权

一、有状态 VS 无状态

用户认证有两种模式,一种是服务器端存储用户登录状态,比如使用session store,这种方式叫有状态,另外一种无状态就是用户登录后,服务器端会传送给客户端一个token,token里面包含了过期时间,用户信息等一些不太敏感的信息,客户端要用接口时将token传递给服务器端,服务器端将token解密之后就能得到当前用户的信息,并通过判断过期时间来知晓当前状态是否过期,两种方式各有优缺点,以下是两种方式的比较:
微服务的用户认证与授权_第1张图片

二、微服务认证方案01-“处处安全”方案

基于OAuth2.0协议,使用SpringCloud Security认证授权;

三、微服务认证方案02-外部无状态,内部有状态方案

客户端传递JSESSIONID和Token给服务器端,服务器端拿到了Token确还使用session来认证授权,这是为什么呢?因为有些老的项目刚开始是用session来认证授权的,但是随着技术的更新,想要将session这种有状态方式转变为Token的无状态方式,但是重构又不是一蹴而就的,所以造成了有些子项目使用无状态方式,有些子项目又使用有状态方式;
微服务的用户认证与授权_第2张图片

四、微服务认证方案03-“网关认证授权,内部裸奔”方案

用户的登陆授权全部都在网关完成,网关接收到Token之后,就将Token解密解析出对应的用户信息,比兔下图的user_id和username,然后在将解密解析后的信息传递给微服务,微服务拿到用户信息之后就开始自身的业务逻辑,这里有一个弊端,微服务只能完全的信任网关,如果网关被攻破,那就有点尴尬了;当然也有优点,实现比较简单,性能较好;
微服务的用户认证与授权_第3张图片

五、 微服务认证方案04-“内部裸奔”改进方案

该方案是上个方案的改进版,网关不再进行认证和授权操作,也不进行解密解析Token操作,只用作单纯的转发,用户的认证授权、解密解析Token全都交给微服务来实现,这样一来项目就更加的安全,性能和上个方案对比也不差;
微服务的用户认证与授权_第4张图片

六、微服务认证方案05-方案对比与选择

推荐使用内部裸奔改进版,实现简单,安全性高,测试难度中等,比较折中;
微服务的用户认证与授权_第5张图片

七、JWT是什么?

JWT由Header、Payload和Signature组成,以下为这三部分的作用及其示例:
微服务的用户认证与授权_第6张图片
JWT其实就是Token,并且是被加密的,以下为加密的公式:

Token=Base64(Header).Base64(Payload).Base64(Signature)

示例:aaaa.bbbb.cccc

Signature=Header指定的签名算法(Base64(Header).Base64(Payload),密钥)

示例:HS256(“aaaa.bbbb”,密钥)

当然,这些都是有现成的工具类的,不需要我们自己去手写,如何使用工具类,详见该手记:http://www.imooc.com/article/290892

八、Feign实现Token传递

当微服务认证方案使用内部裸奔改进版时,在微服务之间的调用就需要传递Token,所以这里介绍一下Feign如何实现Token传递;

一、直接Feign接口上修改:
首先在Controller接口上加上token参数并附带@RequestHeader注解,这表示将前端请求的头部中名为X-Token的值赋值给token;
微服务的用户认证与授权_第7张图片
接着在FeignClient中为接口也添加上@RequestHeader注解和token参数,这个意思是在调用member微服务中getMemberInfo接口时,会将token塞在Header中以X-Token为命名传递过去;
微服务的用户认证与授权_第8张图片
这种方式的缺点比较明显,当调用其他微服务的接口量大时,需要修改的工作量就很大,所以接下来在介绍另外一种方式;
二、使用Feign拦截器
首先定义拦截器:
微服务的用户认证与授权_第9张图片
接着配置该拦截器即可,博主使用的是配置文件方式配置,并且直接配置成全局的:
微服务的用户认证与授权_第10张图片
这样拦截器就配置好了,非常的方便;

九、RestTemplate实现Token传递

延伸第八节的介绍,咱们继续讲解一下RestTemplate传递Token的方式;
一、RestTemplate调用微服务时添加token:
微服务的用户认证与授权_第11张图片
二、使用RestTemplate拦截器:
首先实现一个拦截器:
微服务的用户认证与授权_第12张图片
接着配置这个拦截器:
微服务的用户认证与授权_第13张图片
这样RestTemplate传递Token的两种方式就介绍完啦!

PS:本博客所有手记均转载自慕课网大目老师;

你可能感兴趣的:(SpringCloud,java,jwt,spring)