来源:不止思考

应用程序的访问安全又是我们每一个研发团队都必须关注的重点问题。尤其是在我们采用了微服务架构之后,项目的复杂度提升了N个级别,相应的,微服务的安全工作也就更难更复杂了。并且我们以往擅长的单体应用的安全方案对于微服务来说已经不再适用了。我们必须有一套新的方案来保障微服务架构的安全。

在探索微服务访问安全之前,我们还是先来回顾一下单体应用的安全是如何实现的。

一、传统单体应用如何实现「访问安全」?

下图就是一个传统单体应用的访问示意图:

(图片来自WillTran在slideshare分享)

在应用服务器里面,我们有一个auth模块(一般采用过滤来实现),当有客户端请求进来时,所有的请求都必须首先经过这个auth来做身份验证,验证通过后,才将请求发到后面的业务逻辑。

通常客户端在第一次请求的时候会带上身份校验信息(用户名和密码),auth模块在验证信息无误后,就会返回Cookie存到客户端,之后每次客户端只需要在请求中携带Cookie来访问,而auth模块也只需要校验Cookie的合法性后决定是否放行。

可见,在传统单体应用中的安全架构还是蛮简单的,对外也只有一个入口,通过auth校验后,内部的用户信息都是内存/线程传递,逻辑并不是复杂,所以风险也在可控范围内。

那么,当我们的项目改为微服务之后,「访问安全」又该怎么做呢。

二、微服务如何实现「访问安全」?

在微服务架构下,有以下三种方案可以选择,当然,用的最多的肯定还是OAuth模式。

  • 网关鉴权模式(API Gateway)
  • 服务自主鉴权模式
  • API Token模式(OAuth2.0)

下面分别来讲一下这三种模式:

  1. 网关鉴权模式(API Gateway)
  1. (图片来自WillTran在slideshare分享)
  2. 通过上图可见,因为在微服务的最前端一般会有一个API网关模块(API Gateway),所有的外部请求访问微服务集群时,都会首先通过这个API Gateway,所以我们可以在这个模块里部署auth逻辑,实现统一集中鉴权,鉴权通过后,再把请求转发给后端各个服务。
  3. 这种模式的优点就是,由API Gateway集中处理了鉴权的逻辑,使得后端各微服务节点自身逻辑就简单了,只需要关注业务逻辑,无需关注安全性事宜。
  4. 这个模式的问题就是,API Gateway适用于身份验证和简单的路径授权(基于URL的),对于复杂数据/角色的授权访问权限,通过API Gateway很难去灵活的控制,毕竟这些逻辑都是存在后端服务上的,并非存储在API Gateway里。
  5. 服务自主鉴权模式
  1. (图片来自WillTran在slideshare分享)
  2. 服务自主鉴权就是指不通过前端的API Gateway来控制,而是由后端的每一个微服务节点自己去鉴权。
  3. 它的优点就是可以由更为灵活的访问授权策略,并且相当于微服务节点完全无状态化了。同时还可以避免API Gateway 中 auth 模块的性能瓶颈。
  4. 缺点就是由于每一个微服务都自主鉴权,当一个请求要经过多个微服务节点时,会进行重复鉴权,增加了很多额外的性能开销。
  5. API Token模式(OAuth2.0)
  1. (图片来自网络)
  2. 如图,这是一种采用基于令牌Token的授权方式。在这个模式下,是由授权服务器(图中Authorization Server)、API网关(图中API Gateway)、内部的微服务节点几个模块组成。
  3. 流程如下:
  4. 第一步:客户端应用首先使用账号密码或者其它身份信息去访问授权服务器(Authorization Server)获取 访问令牌(Access Token)。
  5. 第二步:拿到访问令牌(Access Token)后带着它再去访问API网关(图中API Gateway),API Gateway自己是无法判断这个Access Token是否合法的,所以走第三步。
  6. 第三步:API Gateway去调用Authorization Server校验一下Access Token的合法性。
  7. 第四步:如果验证完Access Token是合法的,那API Gateway就将Access Token换成JWT令牌返回。
  8. (注意:此处也可以不换成JWT而是直接返回原Access Token。但是换成JWT更好,因为Access Token是一串不可读无意义的字符串,每次验证Access Token是否合法都需要去访问Authorization Server才知道。但是JWT令牌是一个包含JOSN对象,有用户信息和其它数据的一个字符串,后面微服务节点拿到JWT之后,自己就可以做校验,减少了交互次数)。
  9. 第五步:API Gateway有了JWT之后,就将请求向后端微服务节点进行转发,同时会带上这个JWT。
  10. 第六步:微服务节点收到请求后,读取里面的JWT,然后通过加密算法验证这个JWT,验证通过后,就处理请求逻辑。
  11. 这里面就使用到了OAuth2.0的原理,不过这只是OAuth2.0各类模式中的一种。

由于OAuth2.0目前最为常用,所以接下来我再来详细讲解一下OAuth2.0的原理和各类用法。

三、详解 OAuth2.0 的「 访问安全 」?

OAuth2.0是一种访问授权协议框架。它是基于Token令牌的授权方式,在不暴露用户密码的情况下,使 应用方 能够获取到用户数据的访问权限。

例如:你开发了一个视频网站,可以采用第三方微信登陆,那么只要用户在微信上对这个网站授权了,那这个网站就可以在无需用户密码的情况下获取用户在微信上的头像。

OAuth2.0 的流程如下图:

OAuth2.0 里的主要名词有:

  • 资源服务器:用户数据/资源存放的地方,在微服务架构中,服务就是资源服务器。在上面的例子中,微信头像存放的服务就是资源服务器。
  • 资源拥有者:是指用户,资源的拥有人。在上面的例子中某个微信头像的用户就是资源拥有者。
  • 授权服务器:是一个用来验证用户身份并颁发令牌的服务器。
  • 客户端应用:想要访问用户受保护资源的客户端/Web应用。在上面的例子中的视频网站就是客户端应用。
  • 访问令牌:Access Token,授予对资源服务器的访问权限额度令牌。
  • 刷新令牌:客户端应用用于获取新的 Access Token 的一种令牌。
  • 客户凭证:用户的账号密码,用于在 授权服务器 进行验证用户身份的凭证。

OAuth2.0有四种授权模式,也就是四种获取令牌的方式:授权码、简化式、用户名密码、客户端凭证。

下面来分别讲解一下:

  1. 授权码(Authorization Code)
  2. 授权码模式是指:客户端应用先去申请一个授权码,然后再拿着这个授权码去获取令牌的模式。这也是目前最为常用的一种模式,安全性比较高,适用于我们常用的前后端分离项目。通过前端跳转的方式去访问 授权服务器 获取授权码,然后后端再用这个授权码访问 授权服务器 以获取 访问令牌。
  1. 流程如上图。
  2. 第一步,客户端的前端页面(图中UserAgent)将用户跳转到 授权服务器(Authorization Server)里进行授权,授权完成后,返回 授权码(Authorization Code)
  3. 第二步,客户端的后端服务(图中Client)携带授权码(Authorization Code)去访问 授权服务器,然后获得正式的 访问令牌(Access Token)
  4. 页面的前端和后端分别做不同的逻辑,前端接触不到Access Token,保证了Access Token的安全性。
  5. 简化式(Implicit)
  6. 简化模式是在项目是一个纯前端应用,在没有后端的情况下,采用的一种模式。
  7. 因为这种方式令牌是直接存在前端的,所以非常不安全,因此令牌的有限期设置就不能太长。
  1. 其流程就是:
  2. 第一步:应用(纯前端的应用)将用户跳转到 授权服务器(Authorization Server)里进行授权,授权完成后,授权服务器 直接将 Access Token 返回给 前端应用,令牌存储在前端页面。
  3. 第二步:应用(纯前端的应用)携带 访问令牌(Access Token) 去访问资源,获取资源。
  4. 在整个过程中,虽然令牌是在前端URL中直接传递,但注意,令牌在HTTP协议中不是放在URL参数字段中的,而是放在URL锚点里。因为锚点数据不会被浏览器发到服务器,因此有一定的安全保障。
  5. 用户名密码(Resource Owner Credentials)
  1. 这种方式最容易理解了,直接使用用户的用户名/密码作为授权方式去访问 授权服务器,从而获取Access Token,这个方式因为需要用户给出自己的密码,所以非常的不安全性。一般仅在客户端应用与授权服务器、资源服务器是归属统一公司/团队,互相非常信任的情况下采用。
  2. 客户端凭证(Client Credentials)
  1. 这是适用于服务器间通信的场景。客户端应用拿一个用户凭证去找授权服务器获取Access Token。

以上,就是对微服务架构中「访问安全」的一些思考。

end:如果你觉得本文对你有帮助的话,记得点赞转发,你的支持就是我更新动力。

微服务鉴权_百度技术架构师总结:微服务架构之访问安全相关推荐

  1. springcloud 微服务鉴权_我对微服务、SpringCloud、k8s、Istio的一些杂想

    一.微服务与SOA "微服务"是一个名词,没有这个名词之前也有"微服务",一个朗朗上口的名词能让大家产生一个认知共识,这对推动一个事务的发展挺重要的,不然你叫微 ...

  2. BCrypt加密怎么存入数据库_第6天 密码加密与微服务鉴权JWT(下)

    上篇: Gavin:第6天 密码加密与微服务鉴权JWT(上)​zhuanlan.zhihu.com 能够使用BCrypt密码加密算法实现注册与登陆功能 能够说出常见的认证机制 能够说出JWT的组成部分 ...

  3. 密码加密与微服务鉴权JWT

    密码加密与微服务鉴权JWT ## 学习目标 1.用户注册时候,对数据库中用户的密码进行加密存储(使用 SpringSecurity). 2.使用 JWT 鉴权认证. 一.BCrypt 密码加密 任何应 ...

  4. 架构师图谱·微服务消息队列篇

    1. 概述 "架构师图谱"是一个很宏大的命题,特别是优秀的架构师自身也是"由点到面再到图",一点点成长积累起来,尝试写这系列文章的目的更多的是结合自身的一些经验 ...

  5. 【Dubbo3高级特性】「提升系统安全性」通过令牌进行服务验证及服务鉴权控制实战指南

    系列文章目录 如果你看到了这里,那么接下来你将会认识Dubbo3的诞生将如何引领微服务领域更进一步,从而迈入云原生的领域,这当然不仅仅是Dubbo3,之前也介绍了Java生态另外一个云原生领域的技术Q ...

  6. mysql ip鉴权_网站登录鉴权的实现

    什么是网站鉴权,目的是什么? 一般来说,一个网站不可能只有一种操作权限.举个例子,可能存在未登录的操作权限,登录的操作权限,以及管理 员的操作权限等.网站鉴权的目的就是用户在进行操作前,对用户的身份进 ...

  7. 文件服务器鉴权,服务鉴权

    使用kmse实现服务的权限校验 通过一个简单的实例说明开发者如何通过kmse进行服务间的权限校验. 一.准备客户端和服务端两个demo 这里演示如何快速实践服务鉴权功能.假如现在有两个微服务 auth ...

  8. java鉴权_一个开箱即用的高效认证鉴权框架,专注于restful api的认证鉴权动态保护...

    作者:tomsun28 来源:SegmentFault 思否 写在开头 看了看这个专栏的最近一篇文章已经是两年前了,时间过得好快.应该是出学校后时间就很快了.两年前因为用shiro后,自己就按着想法开 ...

  9. 百度开放云首席架构师徐串:架构师对架构的理解

    百度开放云首席架构师徐串:架构师必须理解程序员的痛 时间 2016-05-18 13:19:49  CSDN 原文  http://geek.csdn.net/news/detail/74783 主题 ...

  10. 阿里P8架构师谈:分布式架构设计12精讲

    分布式架构设计包含: 分布式缓存 分布式消息中间件 分库分表.读写分离 单点登录等 想成为阿里160万年薪的P8架构师?你必须掌握如下6大技能体系! 阿里P8架构师谈:分布式架构系统拆分原则.需求.微 ...

最新文章

  1. Matlab R2018a 64位安装教程
  2. Android之判断时间戳是不是今天
  3. c语言递归求塔移动次数,c语言递归调用汉诺塔
  4. java火焰纹章攻略女神之剑_《火焰纹章风花雪月》白云之章-女神再生仪式图文攻略...
  5. 图像分类——EfficientNet的学习笔记
  6. AD显示隐藏管脚——谈mos管封装的一个坑处
  7. 问题四十八:怎么用ray tracing画superhyperboloid(超级双曲面)
  8. go map二维数据追加
  9. [现代控制理论]8_LQR控制器_simulink
  10. java 数学库_数学库
  11. 52个数据可视化图表鉴赏
  12. 【三年面试五年模拟】算法工程师的独孤九剑秘籍(第十式)
  13. 快递面单成信息泄露重灾区,隐私面单成“必选项”
  14. 【应用统计学】几种常见的概率分布
  15. S2-052的POC测试
  16. 政务云公共服务区与资源共享区数据交换的方式
  17. 一文详解:为什么隐私智能合约是Web3的未来
  18. 统计学习第十四周-方差分析
  19. 关于OSPF 5类LSA中Forwarding Address
  20. MQTT协议详解 三、MQTT控制包(CONNECT)

热门文章

  1. 从副总裁做”表哥“说起
  2. 18. Window createPopup() 方法
  3. fopen()和fgetl()打开问件,读取内容
  4. [bzoj1510][POI2006]Kra-The Disks_暴力
  5. C语言中函数中传入一个数组,并且返回一个数组
  6. 基于Docker布署伪分布式hadoop环境(一)
  7. AndroidMenifest.xml file missing 报错
  8. mysql函数之二:left,right,substring,substring_index MySQL截取字符串函数方法
  9. Java Beanutils 配置
  10. (转)详解HTML网页源码的charset格式