Netflix如何解决身份验证问题?

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"本文最初发布于Netflix技术博客,由InfoQ中文站翻译并分享。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正如大多数开发人员可以证明的那样,处理安全协议和身份令牌,以及用户和设备身份验证都是很有挑战性的。想象一下,如果有多种协议、多个令牌、2亿多用户和数千种设备类型,那么问题的规模可能会急剧扩大。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"几年前,我们决定解决这种复杂性,并提出了一个新方案,最终形成一个新团队,我们将复杂的用户和设备身份验证以及各种安全协议和令牌的处理移到网络边缘,集中由一组服务和一个团队来管理。在此过程中,我们更改了服务网络中的端到端身份传播,从而使用一种密码验证的令牌无关的身份对象。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们是如何做到的:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"降低服务所有者的复杂性,他们不再需要了解并负责终止安全协议和处理无数的安全令牌"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过将令牌管理授权给具有领域专业知识的服务和团队来提高安全性"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"提高审计能力和取证分析能力"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"我们是如何做到的"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最初,Netflix是一个允许会员管理他们的DVD队列的网站。后来,网站增加了流媒体内容的功能。流媒体设备出现的时间稍晚一些,但这些设备最初的能力有限。随着时间推移,设备的性能和功能不断提高,以前只能在网站上访问,现在可以通过流媒体设备访问。Netflix服务的规模迅速增长,支持超过2000种设备类型。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在,支持这些功能的服务需要理解多个令牌和安全协议,以便识别用户和设备,并授权对这些功能的访问,这增加了服务的负担。整个系统相当复杂,并且开始变得脆弱。此外,边缘层的架构正在演变为PaaS(平台即服务)模型,我们需要做出一些艰难的决定,包括如何以及在何处进行身份令牌处理。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"复杂性:多个服务处理认证令牌"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"为了说明系统的复杂性,下图展示了在做出本文介绍的更改之前,用户的登录流程:"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/88\/88ea07d44f7a6b65fe2bb9e22562165a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从大的方面说,这个(大大简化的)流程涉及如下步骤:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"用户输入他们的凭据,Netflix客户端将凭据连同设备的ESN一起传送到边缘网关,即Zuul。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"Zuul 将用户调用重定向到API\/login端点。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"API服务器编排后端系统来验证用户。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"如果验证成功,API服务器就向上游发送一个cookie响应,包括customerId(一个Long值)、ESN(一个字符串)和一个过期指令。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"Zuul将cookie发回给Netflix客户端。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个模型有一些问题,比如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"外部有效的令牌是在验证栈的深处生成的,需要一直向上传播,这可能导致记录不当或管理不当。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上游系统必须重新打开令牌来识别用户登录,并可能管理多个并行的身份数据结构,这些数据结构很容易出现不同步。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"多个协议&令牌"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"上面的示例显示了一个处理一种协议(HTTP\/S)和一种令牌类型(cookie)的流。Netflix流媒体产品中使用了多种协议和令牌,汇总如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/80\/807bef00c4bf4cfb181f98bb5dd6a794.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这些令牌被Netflix流媒体生态系统中的多个系统消费,并可能被它们更改,例如:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/c3\/c353aa95f1b3421a08cd5bcce1149ca0.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"让情况变得更复杂的是,有多种方法可以将这些令牌或其中包含的数据从一个系统传输到另一个系统。在某些情况下,令牌被破解,身份数据元素被提取为简单的原语或字符串,用于API调用,或通过请求上下文头从一个系统传递到另一个系统,甚至作为URL参数。系统中没有适当的检查来确保令牌或其中包含的数据的完整性。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Netflix的规模"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"与此同时,Netflix的经营规模呈指数级增长。如今,Netflix拥有2亿多订阅用户,每月有数百万活跃设备。我们每秒处理超过250万个请求,其中很大一部分请求需要某种形式的身份验证。在旧有的架构中,每个请求都会导致一个API调用来进行验证,如下所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/61\/612f2a6d765a44a0b60ffa3123c28ea7.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"EdgePaas半路杀出"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"使情况进一步复杂化的是,Edge工程团队正在从旧的API服务器架构迁移到新的基于Paas的方法。当我们迁移到EdgePaaS时,前端服务从基于Java的API移到了BFF(为前端应用开发的后端),也就是NodeQuark,如下图所示:"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/35\/35027b724fbeb9713856d77d232a361f.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"这个模型使前端工程师能够在核心API框架之外拥有和操作他们自己的服务。然而,这又带来了另一层复杂性——这些NodeQuark服务将如何处理身份令牌?NodeQuark服务是用JavaScript编写的,终止像"},{"type":"link","attrs":{"href":"https:\/\/www.infoq.com\/news\/2014\/11\/netflix-msl\/?fileGuid=pqijKPaZWzE0UD55","title":"","type":null},"content":[{"type":"text","text":"MSL"}]},{"type":"text","text":"这样复杂的协议既困难又浪费,因为要复制令牌管理的所有逻辑。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"让我们总结一下"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总之,我们发现,我们用于处理大规模的身份验证和身份令牌的解决方案复杂而低效。我们有多种身份令牌类型和来源,每种都需要特殊处理,其逻辑被复制到不同的系统中。关键身份数据以不一致的方式在整个服务器生态系统中传播。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"边缘身份验证服务来救场"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们意识到,为解决这个问题,需要一个统一的身份模型。我们需要在更上游的地方处理身份验证令牌(和协议)。为此,我们将身份验证和协议终止移到网络边缘,并新建了一个具有完整性保护的、令牌无关的身份对象,它可以在整个服务器生态系统中传播。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"将身份验证移到边缘"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"考虑到我们的目标是提高安全性和降低复杂性,并最终提供更好的用户体验,我们的策略是将设备身份验证操作、用户身份识别和身份验证令牌管理集中到服务边缘。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从大的方面来说,Zuul(云网关)将成为令牌检查和有效负载加密\/解密的终止点。如果Zuul无法处理这些操作(一小部分),比如令牌不存在,需要更新,或者无效,Zuul会将这些操作委托给一套新的边缘身份验证服务来处理加密密钥交换和令牌创建或更新。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"边缘身份验证服务"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"边缘身份验证服务(EAS)既是一种将设备和用户身份验证和识别移至云边缘的架构概念,也是一套为处理每种令牌类型而开发的服务。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在功能上,EAS是一系列运行在Zuul中的过滤器,它可以调用外部服务来支持它们的域,例如,调用一个服务来处理MSL令牌,或调用另一个服务来处理Cookie。EAS还涵盖了令牌的只读处理(稍后详细介绍),以便用于创建Passport。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"EAS处理请求的基本模式如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/6c\/6cc53e4e25c562cb0aa1de8151893c3b.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对于进入Netflix服务的每个请求,Zuul中的EAS入站过滤器检查设备客户端提供的令牌,并将请求传递给Passport注入过滤器,或委托给一个边缘身份验证服务来处理。Passport注入过滤器生成一个与令牌无关的身份,向下传播到服务器生态系统的其余部分。在响应路径上,EAS出站过滤器根据需要,在边缘身份验证服务的帮助下,确定并生成发送回客户端设备所需的令牌。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在,系统的架构形式如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/7e\/7e6573aed385d21781ee1f700a02b79d.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"注意,令牌从未越过边缘网关\/ EAS边界。MSL安全协议在边缘终止,所有令牌都被破解打开,身份数据通过服务器生态系统以与令牌无关的方式传播。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"关于弹性的说明"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在基本路径上,Zuul能够处理大部分有效且未过期的令牌,而边缘身份验证服务处理其余的请求。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/51\/5108eb9d2e743a27b47da92a7ed4d422.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"根据设计,EAS服务有容错性,例如,当Zuul识别出Cookie有效但已经过期时,对EAS的更新调用会失败:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/ff\/ff28687d474de67f049b9a30010d1865.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在失败的情况下,Zuul中的EAS过滤器将放宽限制,允许传播已解析的标识,并指示在下一个请求上重新安排更新调用。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"令牌无关的身份(Passport)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"容易发生变化的身份结构是无法满足需求的,因为这意味着从一个服务传递到另一个服务时可信身份信息会减少。因此,需要一个与令牌无关的身份结构。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们引入了一个名为“Passport”的身份结构,它允许我们以统一的方式传播用户和设备的身份信息。Passport也是一种令牌,但是使用不同于外部令牌的内部结构有很多好处。不过,下游系统仍然需要访问用户和设备标识。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/f6\/f601b758759b2969100508c8f1ccd546.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Passport是在每个请求的边缘创建的短期身份结构,也就是说,它的作用域是请求的生命周期,它完全是在Netflix生态系统的内部。它们是通过一组身份过滤器在Zuul中生成的。Passport包含了用户和设备的身份信息,是protobuf格式的,并受到HMAC的完整性保护。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Passport结构"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如上所述,Passport被建模为协议缓冲区。Passport的定义如下:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"message Passport {\n Header header = 1;\n UserInfo user_info = 2;\n DeviceInfo device_info = 3;\n Integrity user_integrity = 4;\n Integrity device_integrity = 5;\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Header元素传递创建Passport的服务的名称。更有趣的是,传播的内容与用户和设备有关。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"用户&设备信息"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"UserInfo元素包含识别请求发起用户的所有信息,DeviceInfo元素包含用户访问Netflix所使用设备的必要信息:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"message UserInfo {\n Source source = 1;\n int64 created = 2;\n int64 expires = 3;\n Int64Wrapper customer_id = 4;\n … (some internal stuff) …\n PassportAuthenticationLevel authentication_level = 11;\n repeated UserAction actions = 12;\n}\nmessage DeviceInfo {\n Source source = 1;\n int64 created = 2;\n int64 expires = 3;\n StringValue esn = 4;\n Int32Value device_type = 5;\n repeated DeviceAction actions = 7;\n PassportAuthenticationLevel authentication_level = 8;\n … (some more internal stuff) …\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"UserInfo"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"DeviceInfo"}]},{"type":"text","text":"都携带请求的"},{"type":"codeinline","content":[{"type":"text","text":"Source"}]},{"type":"text","text":"和"},{"type":"codeinline","content":[{"type":"text","text":"PassportAuthenticationLevel"}]},{"type":"text","text":"。"},{"type":"codeinline","content":[{"type":"text","text":"Source"}]},{"type":"text","text":"列表是请求的分类,包含使用的协议和用于验证请求的服务。"},{"type":"codeinline","content":[{"type":"text","text":"PassportAuthenticationLevel"}]},{"type":"text","text":"是我们放在身份验证声明中的信任级别。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"enum Source {\n NONE = 0;\n COOKIE = 1;\n COOKIE_INSECURE = 2;\n MSL = 3;\n PARTNER_TOKEN = 4;\n …\n}\nenum PassportAuthenticationLevel {\n LOW = 1; \/\/ untrusted transport\n HIGH = 2; \/\/ secure tokens over TLS\n HIGHEST = 3; \/\/ MSL or user credentials\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下游应用程序可以使用这些值来做授权和\/或用户体验决策。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Passport Integrity"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Passport的完整性通过HMAC(基于哈希的消息验证码)来保护,HMAC是一种特定类型的MAC,涉及加密哈希函数和秘密加密密钥。它可用于同时验证消息的数据完整性和真实性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用户和设备完整性定义为:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"message Integrity {\n int32 version = 1;\n string key_name = 2;\n bytes hmac = 3;\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Integrity元素的版本1对HMAC使用SHA-256,它被编码为ByteArray。Integrity的未来版本可能会使用不同的哈希函数或编码。在版本1中,HMAC字段包含来自MacSpec.SHA_256的256位的值。完整性保护可以保证Passport的字段在创建后不会发生变化。在使用其中包含的任何值之前,客户端应用程序可以使用Passport Introspector检查Passport的完整性。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Passport Introspector"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Passport对象本身是不透明的;客户端可以使用Passport Introspector从报头中提取Passport,并检索其中的内容。Passport Introspector是Passport二进制数据的封装器。客户端通过工厂创建Introspector,然后访问基本的访问器方法:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"public interface PassportIntrospector {\n Long getCustomerId();\n Long getAccountOwnerId();\n String getEsn();\n Integer getDeviceTypeId();\n String getPassportAsString();\n …\n}\n"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"Passport Action"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在上面的Passport协议缓冲区定义中,还包含Passport Action的定义:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"plain"},"content":[{"type":"text","text":"message UserInfo {\n repeated UserAction actions = 12;\n …\n}\nmessage DeviceInfo {\n repeated DeviceAction actions = 7;\n …\n}\n"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Passport Action是下游服务在对用户或设备标识执行更新时显式发送的信号。EAS使用该信号来创建或更新相应类型的令牌。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"再谈登录流"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"让我们以一个所有这些解决方案一起工作的例子来做下总结。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着身份验证和协议终止移到边缘,以及Passport作为身份标识的引入,前面描述的登录流已经演变为下面这个样子:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/ac\/ac7ff4f6c5a534af3cdcc0616265e3bb.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"用户输入他们的凭据,Netflix客户端将凭据连同设备的ESN一起传送到边缘网关,也就是Zuul。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"运行在Zuul中的身份过滤器生成一个设备绑定的Passport,并将其传递给API\/login端点。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"API服务器将Passport传播到负责对用户进行身份验证的中间层服务。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":4,"align":null,"origin":null},"content":[{"type":"text","text":"在成功地验证所提供的声明后,这些服务创建一个Passport Action,并将其与原始的Passport一起发送到上游的API和Zuul。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":5,"align":null,"origin":null},"content":[{"type":"text","text":"Zuul调用Cookie服务来解析Passport和Passport Action,并将Cookie发回给Netflix客户端。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"主要的好处和经验"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"简化了授权"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"外部令牌流入下游系统的原因之一是,授权决策通常依赖于令牌中的身份验证声明以及与每种令牌类型相关联的信任。在我们的Passport结构中,我们为这种信任分配了级别,这意味着需要做授权决策的系统可以围绕Passport编写合理的规则,而不是在多个服务的代码中复制信任规则。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"显式、可扩展的身份模型"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"规范化的身份结构是非常有用的。传递标识原语的方案很脆弱,也很难调试。如果调用链中的客户身份从服务A到服务D更改了,是谁更改的呢?一旦身份结构通过所有关键系统,添加新的外部令牌类型、新的信任级别或表示身份的新方法就相对容易了。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"操作关注点和可见性"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"有了一个结构(如Passport),就可以定义服务写Passport,并定义其他服务验证它。当Passport在传播时,我们可以在日志中看到它,打开它,并验证它,从而知道其身份是什么。我们也知道Passport的来源,可以追溯到它在哪里进入的系统。这使得调试任何与身份相关的异常变得更加容易。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"减少下游系统复杂性&负载"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将统一的结构传递给下游系统,意味着这些系统可以使用内省库轻松地查找设备和用户标识。它们可以使用公共结构,而不是单独处理每种类型的外部令牌。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通过将令牌处理从这些系统转移到中心化的边缘身份验证服务,下游系统在CPU、请求延迟和垃圾收集方面的指标有了显著改善,所有这些都有助于减少集群占用的空间和云成本。以下这些收益的示例来自主API服务。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在之前的实现中,每个请求需要两次解密\/终止成本,因为我们需要有在边缘路由的能力,但也需要在下游服务中有多样性的协议终止。一些性能改进就是由于这种整合——现在只需要处理一次MSL请求。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"CPU与RPS比值"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"卸载令牌处理导致每个请求的CPU成本减少了30%,平均负载减少了40%。下图为CPU与RPS的比值,越低越好:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/1d\/1d52ceb5a922c3ff59a2cb630695ca4c.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"API响应时间"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"API服务上所有调用的响应时间都有了显著的改善,平均延迟减少了30%,99百分位延迟减少了20%:"}]},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/a9\/a94ee50a296cf7aa6c71e30ac9433457.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"垃圾收集"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"API服务也显著减少了GC压力和GC暂停时间,如Stop The World垃圾收集指标所示:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/07\/07e663d2c54b632a93d521bf6a0e9ae7.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"开发速度"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"将这些身份验证和身份相关的问题从微服务的开发人员身上抽离出来,意味着他们可以专注于自己的核心领域。这个领域的更改现在只需在一组专门的服务中完成一次,而不是分布在多个服务中。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"未来展望"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"(更)强大的身份验证"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们目前正在扩展边缘认证服务,以通过一个名为“Resistor”的新服务支持多因素认证。基于机器学习模型,我们有选择地引入了针对可疑连接的第二个因素。当引入新的流程时,我们也会引入新的因素,例如,发送到电子邮件或手机上的一次性密码(OTP)、向移动设备推送通知和第三方身份验证程序。对于希望增加账户安全性的用户,我们也在探索可选的多因素身份验证。"}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"灵活的授权"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"现在,既然已经有了流经系统的经过验证的身份,我们可以使用它作为授权决策的强信号。去年,我们开始探索一种新的产品访问策略(PACS),目前正致力于将其投入生产,为Netflix流媒体产品提供一些新的体验。最近,PACS为"},{"type":"link","attrs":{"href":"https:\/\/about.netflix.com\/en\/news\/streamfest-india?fileGuid=pqijKPaZWzE0UD55","title":"","type":null},"content":[{"type":"text","text":"Streamfest"}]},{"type":"text","text":"(Netflix在印度的免费周末)提供了体验访问控制。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文链接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https:\/\/netflixtechblog.com\/edge-authentication-and-token-agnostic-identity-propagation-514e47e0b602"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章