微服务认证与授权

  • 一、有状态VS无状态
  • 二、微服务认证方案
  • 1、处处安全方案:
  • 2、外部无状态、内部有状态方案(实际项目中,很多企业会使用)
  • 3、网关认证授权,内部裸奔方案
  • 4、内部裸奔改进方案
  • 三、访问控制模型(授权)
  • 四、JWT(json web token)
  • 五、认证代码实现
  • 六、授权代码实现


一、有状态VS无状态

1、有状态,如单体架构

微服务之间如何知道用户是否在线 微服务 有状态_微服务


2、无状态,即服务器不去记录用户的登录状态,更直观讲,即服务器不再维护session

微服务之间如何知道用户是否在线 微服务 有状态_服务器_02


(1)对比有状态

  • 为了获取session,所有的应用都要访问session store,若此服务器挂了,所有的应用都无法正常运行,鸡蛋又放到一个篮子里,与微服务相悖
  • session store 服务器若要迁移,十分困难,将影响所有的应用使用
  • session store 服务器若达到容量或性能瓶颈,都得想办法扩容
    无状态,服务器端只做解密、校验,由客户端浏览器去存储
    (2)无状态缺点
  • 一旦token颁发给用户,如给某个用户的token失效是7天,若想该用户失效,就难以实现;反观session,可以直接修改tomcat的过期时间

微服务之间如何知道用户是否在线 微服务 有状态_微服务_03

二、微服务认证方案

1、处处安全方案:

微服务之间如何知道用户是否在线 微服务 有状态_后端_04


微服务之间如何知道用户是否在线 微服务 有状态_微服务_05


优缺点总结:安全性好,实现的成本比较高,从业务流程即可看出,另外由于存在多出的token交换,以及多次认证,所以带来了性能的开销

2、外部无状态、内部有状态方案(实际项目中,很多企业会使用)

微服务之间如何知道用户是否在线 微服务 有状态_后端_06


(1)概述:网关使用无状态,微服务应用使用有状态;初步一看,既没有用上session(有状态)的优点(无法控制用户),也没有用上无状态的有点(微服务都访问同一台session服务器),还比单存的有状态无状态方案复杂,简直就是吃力不讨好

(2)使用场景:针对庞大复杂的系统,既有传统的架构,又有微服务架构,团队想要重构,即可采用此方案

微服务之间如何知道用户是否在线 微服务 有状态_后端_07

3、网关认证授权,内部裸奔方案

微服务之间如何知道用户是否在线 微服务 有状态_代码实现_08


网关解密token,放到HTTP 头部(header)进行转发,微服务拿到请求,就可以拿到用户信息

优缺点:实现非常简单,性能很好;一旦网关认证被攻破,就是大写的尴尬了

4、内部裸奔改进方案

微服务之间如何知道用户是否在线 微服务 有状态_服务器_09


概述:降低网关的复杂度,网关不再需要关注用户是谁这种业务强的东西了,不再去解密token,解析token,而只做转发,此次,提升了安全性,让系统避免了裸奔的尴尬,当然,这种方案也不是绝对的安全,由于token需要使用密钥解密,微服务越多,知道密钥的人也越多,泄密的风险也越大,再此方案,需要避免密钥泄露,可定期修改密钥,或者不然开发能够直接看到密钥本身

优缺点:实现不复杂,并且降低网关复杂度;缺点是一旦密钥泄露,就玩完了,但此问题可以解决,借助后边的配置管理,就可以实现

方案对比与选择

微服务之间如何知道用户是否在线 微服务 有状态_后端_10

三、访问控制模型(授权)

微服务之间如何知道用户是否在线 微服务 有状态_后端_11


主流使用模型:RABC模型

微服务之间如何知道用户是否在线 微服务 有状态_后端_12

四、JWT(json web token)

1、定义:就是一个字符串,用base64对header、payload、signature进行加密并进行拼接

微服务之间如何知道用户是否在线 微服务 有状态_微服务之间如何知道用户是否在线_13


2、组成

微服务之间如何知道用户是否在线 微服务 有状态_服务器_14


注意:payload存放信息必须是非敏感信息

3、公式

微服务之间如何知道用户是否在线 微服务 有状态_服务器_15

五、认证代码实现

① 登录逻辑:

微服务之间如何知道用户是否在线 微服务 有状态_微服务之间如何知道用户是否在线_16


② 登录状态检查

微服务之间如何知道用户是否在线 微服务 有状态_微服务之间如何知道用户是否在线_17


③ feign传统token

微服务之间如何知道用户是否在线 微服务 有状态_微服务_18

  • @RequestHeader示例
    controller层接收头部X-token信息并传递给token
  • 微服务之间如何知道用户是否在线 微服务 有状态_微服务_19

  • feign客户端传出带X-token的头部信息
  • 微服务之间如何知道用户是否在线 微服务 有状态_服务器_20

  • service调用feign 客户端接口并传入token
  • 微服务之间如何知道用户是否在线 微服务 有状态_后端_21

  • feign拦截器有两种设置,默认使用全局设置
  • 微服务之间如何知道用户是否在线 微服务 有状态_代码实现_22

  • ④ RestTemplate传递token
  • 微服务之间如何知道用户是否在线 微服务 有状态_微服务_23

  • exchange实例
  • 微服务之间如何知道用户是否在线 微服务 有状态_后端_24

  • 拦截器全局配置
  • 微服务之间如何知道用户是否在线 微服务 有状态_服务器_25

六、授权代码实现

  • 土方法:方法内部使用if…else…判断是否有权限
  • spring aop

@Retention注解作用