OpenAPI规范中的安全性

OpenAPI规范中的安全性

了解在API开发的设计阶段,OpenAPI 2.0和3.0如何将API安全提升和强调为首要问题。

不再是一个谜,API正在吞噬世界。 如今,有许多公司提供其API作为与系统进行交互的主要媒介,而用户界面仅作为副产品提供,或者在任何情况下都不作为主要产品出售。 Stripe和Twilio等公司在2012年引领了这一运动的先锋。

考虑到这种转变(顺便说一句,这种转变仍在发生),API已经变得越来越复杂,因此API开发过程也需要发展。 API已经成为一种产品,因此,所有典型的团队成员和方法都已被采用来使该产品成功。

基于API的产品的相关性不断提高,需要新的工具来支持用于实施该产品的人员和方法。 您将如何设计API,以便在真正构建之前可以对其进行检查和迭代? 设计移动应用程序时,您可以使用一些工具轻松创建模型,以确保组织中的每个人都在同一页面上,然后再投入资源来创建真实应用程序。

多年来,对于API而言,这已经不是问题了。 直到OpenAPI规范(以及其他一系列标准)问世。

在本文中,我们将从安全的角度回顾OpenAPI可以提供的功能,如何在今天使用这些功能,并展示一些在此领域做得非常出色的公司!

OpenAPI历史记录:什么,为什么,何时

OpenAPI(以前称为Swagger)于2010年作为用于设计RESTful API的简单,开放源代码规范而开始,尽管随后几年出现了其他API规范格式(例如RAML和APIBlueprint),但Swagger项目成为了最大的项目受欢迎的。

在2015年,Swagger项目捐赠给Linux Foundation,并更名为OpenAPI Specification,Microsoft和IBM加入该基金会,以帮助推动格式向前发展。 他们的第一个版本是OpenAPI 2.0,无非就是更名后的原始Swagger格式。 几年后,OpenAPI 3.0进行了重要更新。

如今,OpenAPI计划包括十多家公司,这些公司认识到联合努力以产生描述API的标准化文档的高价值和重要性。

OpenAPI 2.0

格式概述

OpenAPI 2.0只不过是捐赠给Linux Foundation之后更名的老式Swagger格式。

OpenAPI 2.0文档可以写为JSON或YAML文件,它们使您可以定义暴露的API的外观,包括端点,接受和返回的有效负载,媒体类型,返回的状态代码以及该API可以使用的服务器达到。

我们将不在这里讨论所有这些部分。 相反,我们将专注于规范提供的安全功能。

OpenAPI 2.0的安全功能

OpenAPI 2.0提供了一个专用部分来声明您的API的安全功能和要求,然后在您的路径和操作中酌情使用它们。

https://gist.github.com/01e78b4c3e70102063a8ce3ca1f70459

在此示例中,我们声明了2个安全性定义:第一个将在指定的标头(在本例中为api_key)中查找API**,而第二个将声明隐式的oAuth2流,这需要某些特定的作用域。

OpenAPI 2.0支持另一种称为basic的安全性定义类型,该类型本质上是旧的纯HTTP身份验证格式。

OpenAPI 2.0没有其他内置的安全性定义,并且如果不使用供应商提供的扩展,则无法定义自定义定义。 尽管这三个选项涵盖了大量实际用例,但对于特殊情况而言可能还不够。

OpenAPI 3.0

格式概述和对OpenAPI 2.0的改进

OpenAPI 3.0于2017年发布,旨在解决2.0版所遭受的一些缺陷和限制。

我们不会专注于OpenAPI 3.0规范,而是着重介绍两种格式之间的所有差异:Internet上有很多链接,详细介绍了更改。 相反,我们将重点关注此新版本规范中引入的安全性更改。

OpenAPI 3.0的安全功能

以相同的方式,OpenAPI 2.0在文档中有一个专用部分来声明安全性定义,OpenAPI 3.0也有一个。 区别在于OpenAPI 3.0已将术语更改为“安全方案”。 规范还标准化了声明规范的所有部分的方法,这些部分可以在多个路径上重用。 尽管以前共享的组件留给了开发人员常识,但现在它们都归为组件键之下。

此外,还添加了OpenID Connect支持以及安全性定义包括多个oAuth2流的功能(这是当今普遍使用的功能)。

为了让您了解如何将安全声明从OAS2.0更改为OAS 3.0,这是我们之前为OAS3编写的示例:

https://gist.github.com/728cfd90abf698b9b62f774ed3954831

您可以看到,oAuth2定义现在支持多个流,这些流由安全性部分中的新**定义。

动手:设计安全的API

现在,我们动手尝试创建一个表示将在公共互联网上公开的API的文档。 我们将经历设计阶段-以及实施代码和合同测试。

由于围绕OpenAPI的大多数工具仍坚持使用2.0版本,因此我们将使用该版本。 但是,我们今天将在此处展示的所有概念仍然有效。

创建一个OpenAPI规范

OpenAPI规范文档不过是YAML或JSON文件。 尽管这有效地降低了愿意编写文档的人(每个人都可以编写JSON或YAML文档)的障碍,但这隐藏了规范本身的复杂性。 这是视觉设计师或其他工具真正可以方便使用的地方。

市场上有很多这些。 刹车灯蜂房SwaggerHub 选择哪一个取决于您和您的需求。 无论如何,他们都提供免费计划,因此您无需付费即可上手。

我们将只写一个简单的API,它是PetStore著名示例的修整版。 该API是OAS2 .0和3.0中官方示例的一部分。 由于内容本身的简单性,我选择了此选项。

编写代码

在API的世界中,编写代码确实是最琐碎的部分。 构建API不仅是概念性工作,而且是协作工作,而不是在存储库中提交内容。

因此,我们将坚持一个非常基本的示例,其代码托管在Glitch上 对于那些不知道的人,Glitch是NodeJS应用程序的免费托管服务。 非常适合以非常快速的方式进行原型设计和运输小型应用程序。

测试您的API

现在,我们真正想要做的就是在开发服务器时不断检查我们刚刚编写的实现是否与我们存储库中的规范文档保持同步。 这就是合同测试工具发挥作用的地方。 它们启动服务器实例,并通过处理OpenAPI文档,将HTTP请求发送到服务器,以检查状态代码以及返回的有效负载。 如果其中任何一个都不匹配,将使CI / CD步骤失败,并且将不会部署API。 您也可以将其视为TDD开发,最初您只有一个OpenAPI文档,所有测试均失败,因为您没有任何代码。

在开发API并添加越来越多的终结点时,您将开始看到测试的更多部分通过,直到您获得绿色为止(这意味着您涵盖了OpenAPI文档中声明的整个API表面)。

在我们刚才做的示例中,我决定选择Prism,但可以使用Dredd 它们都支持OpenAPI 2.0,但不幸的是,这些都不支持OpenAPI 3.0。

这些工具的设置通常很简单,不需要任何特殊的工作。

我们要做的第一件事是在机器上下载Prism服务器:

curl -L https://github.com/stoplightio/prism/releases/download/v2.0.16/prism_linux_amd64 -o prism && chmod +x ./prism

完成后,我们需要在本地启动我们的应用程序服务器,然后运行Prism并提供侦听URL以将请求发送到,并将OpenAPI文档用作真相来源:

https://gist.github.com/c62745e77453b74ef6b40150f1a7737c

Prism现在将读取OpenAPI规范文件,遍历所有路径,并按照提供的示例开始编写HTTP请求,或使用JSON模式作为参考创建有效负载,并将其发送到您的应用程序服务器。 收到响应后,Prism将验证状态码以及响应的形状与声明的形状匹配。 如果这些都不匹配,则服务器将报告并出错,并将测试标记为失败。

注意:这些命令在CI / CD环境中也应该适用。

将您的OpenAPI安全规范集成到Auth0中

现在我们有了一个其设计规范与实现相匹配的API,是时候部署它了。 我们很可能希望保护API,而Auth0显然是选择之一。

Auth0当前不支持所有流。 以下是当前情况的细分:

  • oAuth2 :所有流都受支持,通常是处理身份验证/授权的推荐方法。 还可以发出基于JSON的令牌而不是不透明的令牌,从而启用其他方案(例如,在Web应用程序周围传递令牌)
  • openIdConnectAuth0支持所有标准声明
  • basic / http :作为特定类型的oAuth 2.0流支持。 任何具有客户端密码的客户端都可以使用HTTP基本身份验证方案发送该密码。 公平地说,这是一种发送客户端密码的方式,而不是对该方案的完全支持。 因为您在尝试到达目标路径时不会在浏览器上看到任何提示
  • apiKey :不支持。 本身并没有任何形式的正式形式,但这是在网络上发送预共享证书的常用方法。 与API**相似的最接近的身份验证方法是使用客户端凭据授予请求。

您会看到,只要使用oAuth2.0或openIdConnect,就没有什么可担心的了。 如果您要坚持使用某些可以在一定程度上模拟的“较旧”方法,则可能会遇到麻烦。

运行时集成

在此阶段, 我们有一个后端服务器,用于实现我们的API和一个身份提供程序 (在本例中为Auth0),该提供程序存储了我们所有的用户,并提供了必要的基础结构来在我们的平台中进行身份验证和授权。 我们错过了两者之间的纽带:愿意在我的应用程序中进行身份验证的用户如何重定向到Auth0的服务?

您可以在应用程序代码中执行此操作,但是在那种情况下,它不再是声明性的,并且有关安全性要求的OpenAPI文档更改也将要求代码更改。

在API网关的帮助下,可以自动完成此阶段。 鉴于通常以声明性的方式配置此软件,并且大多数情况下您的OpenAPI文档与公开的API相匹配,因此规范与API Gateway配置之间几乎是完美匹配。 不幸的是,直到今天,市场上的网关还没有达到这种集成水平。

对于对此主题感兴趣的人,我于去年12月发表了一个演讲,其视频在线发布

结论

我们已经研究了OpenAPI 2.0和3.0规范中的安全功能,它们可以帮助API用户和开发人员在使用和构建API时明确设定期望。 然后,我们进入了API生命周期的一点,正如您可能已经注意到的那样,它更多地是关于通信,在同一页面上以及关于要公开的内容,而不是简单地编写代码。 这只是整个过程的一个步骤。 最后,我们探讨了尚未与Identity Provider进行运行时集成的机会。

From: https://hackernoon.com/security-in-your-openapi-specification-94d081603950