836

在设计 REST API 或服务时,是否有任何既定的最佳实践来处理安全性(身份验证、授权、身份管理)?

在构建 SOAP API 时,您可以将 WS-Security 作为指南,并且有很多关于该主题的文献。我发现有关保护 REST 端点的信息较少。

虽然我理解 REST 故意没有类似于 WS-* 的规范,但我希望已经出现了最佳实践或推荐模式。

任何讨论或相关文件的链接将不胜感激。如果这很重要,我们将使用带有 POX/JSON 序列化消息的 WCF,用于使用 .NET Framework 的 v3.5 构建的 REST API/服务。

4

18 回答 18

302

正如tweakt 所说,Amazon S3 是一个很好的模型。他们的请求签名确实具有一些功能(例如包含时间戳),有助于防止意外和恶意请求重放。

HTTP Basic 的好处是几乎所有的 HTTP 库都支持它。当然,在这种情况下,您将需要 SSL,因为通过网络发送明文密码几乎是一件坏事。在使用 SSL 时,Basic 比 Digest 更可取,因为即使调用者已经知道需要凭据,Digest 也需要额外的往返来交换 nonce 值。使用 Basic,调用者只需在第一次发送凭据。

一旦确定了客户端的身份,授权实际上只是一个实现问题。但是,您可以将授权委托给具有现有授权模型的其他组件。同样,Basic 的好处是您的服务器最终得到了客户端密码的纯文本副本,您可以根据需要简单地将其传递给基础架构中的另一个组件。

于 2008-08-11T08:45:13.343 回答
117

除了 HTTP,REST 没有其他标准。那里已经建立了 REST 服务。我建议你看看它们,感受一下它们是如何工作的。

例如,我们在开发自己的 S3 REST 服务时借鉴了很多想法。但是我们选择不使用基于请求签名的更高级的安全模型。更简单的方法是基于 SSL 的 HTTP Basic auth。你必须决定什么最适合你的情况。

另外,我强烈推荐O'reilly的RESTful Web Services一书。它解释了核心概念并提供了一些最佳实践。您通常可以采用他们提供的模型并将其映射到您自己的应用程序。

于 2008-08-11T06:07:03.680 回答
72

您可能还想看看OAuth,这是一种新兴的开放协议,用于基于令牌的授权,专门针对 http api。

它与flickr采用的方法非常相似,并且记住了牛奶“rest” api(不一定是 restful api 的好例子,而是基于 token 方法的好例子)。

于 2008-09-18T02:55:07.493 回答
68

Github上有一个很棒的清单:

验证

  • 不要在身份验证、令牌生成、密码存储中重新发明轮子。使用标准。

  • 在登录中使用Max Retry和监禁功能。

  • 对所有敏感数据使用加密。

JWT(JSON 网络令牌)

  • 使用随机的复杂密钥(JWT Secret)使暴力破解令牌变得非常困难。

  • 不要从有效载荷中提取算法。在后端强制算法(HS256 或 RS256)。

  • 使令牌到期 ( TTL, RTTL) 尽可能短。

  • 不要在JWT有效载荷中存储敏感数据,它很容易被解码。

身份验证

  • 始终验证redirect_uri服务器端以仅允许列入白名单的 URL。

  • 始终尝试交换代码而不是令牌(不允许response_type=token)。

  • 使用带有随机散列的状态参数来防止CSRF身份OAuth验证过程。

  • 定义默认范围,并验证每个应用程序的范围参数。

使用权

  • 限制请求(限制)以避免 DDoS / 暴力攻击。

  • 在服务器端使用 HTTPS 来避免 MITM(中间人攻击)

  • 使用HSTS带有 SSL 的标头来避免 SSL Strip 攻击。

输入

  • 根据操作使用正确的 HTTP 方法:(GET读取)、POST(创建)、PUT/PATCH(替换/更新)和DELETE(删除记录),405 Method Not Allowed如果请求的方法不适合请求的资源,则响应。

  • 验证请求Accept标头上的内容类型(内容协商)以仅允许您支持的格式(例如application/xmlapplication/json等),406 Not Acceptable如果不匹配,则以响应响应。

  • 在您接受时验证已content-type发布的数据(例如application/x-www-form-urlencodedmultipart/form-dataapplication/json等)。

  • 验证用户输入以避免常见漏洞(例如 XSS、SQL 注入、远程代码执行等)。

  • 不要在 URL 中使用任何敏感数据(凭据、密码、安全令牌或 API 密钥),而是使用标准Authorization标头。

  • 使用 API Gateway 服务来启用缓存、Rate Limit策略(例如配额、Spike Arrest、并发速率限制)并动态部署 API 资源。

加工

  • 检查是否所有端点都受到身份验证的保护,以避免身份验证过程中断。

  • 应避免使用用户自己的资源 ID。使用 /me/orders 而不是 /user/654321/orders。

  • 不要自动增加 ID。请改用 UUID。

  • 如果您正在解析 XML 文件,请确保未启用实体解析以避免 XXE(XML 外部实体攻击)。

  • 如果您正在解析 XML 文件,请确保未启用实体扩展,以避免通过指数实体扩展攻击引发的 Billion Laughs/XML 炸弹。

  • 使用 CDN 进行文件上传。

  • 如果您正在处理大量数据,请尽可能使用Workers和Queues在后台处理并快速返回响应以避免HTTP阻塞。

  • 不要忘记关闭调试模式。

输出

  • 发送X-Content-Type-Options: nosniff标头。

  • 发送X-Frame-Options: deny标头。

  • 发送Content-Security-Policy: default-src 'none'标头。

  • 删除指纹标头 - X-Powered-ByServerX-AspNet-Version

  • 强制content-type您的响应,如果您返回,application/json那么您的响应内容类型为application/json.

  • 不要返回敏感数据,如凭据、密码、安全令牌。

  • 根据操作完成返回正确的状态码。(例如200 OK, 400 Bad Request, 401 Unauthorized,405 Method Not Allowed等)。

于 2017-11-08T20:29:14.780 回答
43

我有点惊讶尚未提及带有客户端证书的 SSL。当然,这种方法只有在您可以依靠证书识别的用户社区时才真正有用。但是许多政府/公司确实将它们发给了他们的用户。用户不必担心创建另一个用户名/密码组合,并且在每个连接上都建立了身份,因此与服务器的通信可以完全是无状态的,不需要用户会话。(不暗示提到的任何/所有其他解决方案都需要会话)

于 2009-09-25T19:39:38.080 回答
40

这些答案中的每个人都忽略了真正的访问控制/授权。

例如,如果您的 REST API/Web 服务是关于发布/获取医疗记录的,您可能需要定义访问控制策略,了解谁可以访问数据以及在什么情况下访问数据。例如:

  • 医生可以获取与他们有护理关系的患者的病历
  • 没有人可以在练习时间以外发布医疗数据(例如 9 到 5 点)
  • 最终用户可以获取他们拥有的医疗记录或他们作为监护人的患者的医疗记录
  • 护士可以更新与护士属于同一单位的患者的病历。

为了定义和实现这些细粒度的授权,您需要使用一种名为 XACML 的基于属性的访问控制语言,即可扩展访问控制标记语言。

此处的其他标准适用于以下内容:

  • OAuth:身份证。联合和授权委托,例如让一个服务代表我代表另一个服务(Facebook 可以发布到我的 Twitter)
  • SAML:身份联合/Web SSO。SAML 非常关注用户是谁。
  • WS-Security / WS-* 标准:这些标准侧重于 SOAP 服务之间的通信。它们特定于应用程序级消息传递格式 (SOAP),它们处理消息传递的各个方面,例如可靠性、安全性、机密性、完整性、原子性、事件……没有一个涉及访问控制,所有这些都特定于 SOAP。

XACML 与技术无关。它可以应用于 Java 应用程序、.NET、Python、Ruby... Web 服务、REST API 等。

以下是有趣的资源:

于 2013-09-24T22:22:33.730 回答
25

我已经使用过几次 OAuth,并且还使用了一些其他方法(BASIC/DIGEST)。我全心全意地建议 OAuth。以下链接是我见过的关于使用 OAuth 的最佳教程:

http://hueniverse.com/oauth/guide/

于 2009-01-09T21:25:56.060 回答
17

我遇到过的关于与 REST 相关的安全性的最佳帖子之一已在1 RainDrop 结束。MySpace API 还使用 OAuth 来保证安全性,您可以完全访问 RestChess 代码中的自定义通道,我对此进行了很多探索。这是在 Mix 上演示的,你可以在这里找到帖子。

于 2008-09-18T20:53:16.903 回答
15

感谢您的出色建议。我们最终使用自定义 HTTP 标头将身份令牌从客户端传递到服务,以准备将我们的 RESTful API 与即将推出的 Microsoft 采尔马特身份框架集成。我在这里描述了问题我们的解决方案。我还接受了tweakt的建议并购买了RESTful Web Services——如果你正在构建任何类型的RESTful API,这是一本非常好的书。

于 2008-09-17T20:30:10.570 回答
14
于 2014-02-24T18:41:39.710 回答
7

我会推荐 OAuth 2/3。您可以在http://oauth.net/2/找到更多信息

于 2013-03-14T00:59:38.470 回答
6

我搜索了很多关于 restful ws 安全性的内容,最后我们还通过 cookie 从客户端到服务器使用令牌来验证请求。我使用 spring security 来授权服务中的请求,因为我必须根据已经在 DB 中的指定安全策略对每个请求进行身份验证和授权。

于 2012-05-15T10:36:28.137 回答
6
于 2013-11-21T14:19:04.320 回答
4

REST 本身没有提供安全标准,但像 OAuth 和 SAML 这样的东西正在迅速成为这个领域的标准。但是,身份验证和授权只是您需要考虑的一小部分。许多与 Web 应用程序相关的已知漏洞非常适用于 REST API。您必须考虑输入验证、会话破解、不适当的错误消息、内部员工漏洞等。这是一个很大的课题。

于 2012-10-12T08:22:50.130 回答
4

我想添加(与 stinkeymatt 一致),最简单的解决方案是将 SSL 证书添加到您的站点。换句话说,请确保您的网址是 HTTPS://。这将涵盖您的运输安全(物有所值)。使用 RESTful url,想法是保持简单(与 WS* 安全/SAML 不同),您可以使用oAuth2/openID 连接甚至基本身份验证(在简单的情况下)。但是您仍然需要 SSL/HTTPS。请在此处检查 ASP.NET Web API 2 安全性:http ://www.asp.net/web-api/overview/security (文章和视频)

于 2014-03-01T01:04:58.197 回答
3

正如@Nathan 最终得到的是一个简单的 HTTP 标头,有些人说 OAuth2 和客户端 SSL 证书。它的要点是……您的 REST API 不必处理安全性,因为这实际上应该超出 API 的范围。

相反,应该在其之上放置一个安全层,无论是 Web 代理后面的 HTTP Header(一种常见的方法,如 SiteMinder、Zermatt 甚至 Apache HTTPd),还是像 OAuth 2 一样复杂。

关键是请求应该在没有任何最终用户交互的情况下工作。所需要做的就是确保与 REST API 的连接经过身份验证。在 Java EE 中,我们有一个userPrincipal可以在HttpServletRequest. 它还在部署描述符中进行管理,即 URL 模式可以是安全的,因此 REST API 代码不再需要检查。

在 WCF 世界中,我将使用它ServiceSecurityContext.Current来获取当前的安全上下文。您需要将应用程序配置为需要身份验证。

我上面的陈述有一个例外,那就是使用随机数来防止重播(可能是攻击或某人只是提交了两次相同的数据)。那部分只能在应用层处理。

于 2014-07-17T15:08:57.343 回答
3

对于 Web 应用程序安全,您应该查看 OWASP ( https://www.owasp.org/index.php/Main_Page ),它为各种安全攻击提供了备忘单。您可以采用尽可能多的措施来保护您的应用程序。关于 API 安全性(授权、身份验证、身份管理),已经提到了多种方法(Basic、Digest 和 OAuth)。OAuth1.0存在漏洞,所以可以使用OAuth1.0a(OAuth2.0由于规范问题没有被广泛采用)

于 2014-10-06T06:05:08.970 回答
2

已经有一段时间了,但这个问题仍然是相关的,尽管答案可能已经改变了一点。

API 网关将是一种灵活且高度可配置的解决方案。我对KONG进行了相当多的测试和使用,并且非常喜欢我所看到的。KONG 提供了自己的管理 REST API,您可以使用它来管理用户。

Express-gateway.io是更新的,也是一个 API 网关。

于 2017-08-11T21:51:08.757 回答