海报说,如果我们不使用客户端SSL认证服务器,就不知道它与谁交谈。
这不是我说:)这就是我说的:
除非您使用 TLS 客户端身份验证,否则 SSL 本身不是 REST API 的可行身份验证机制。
单独是这里的关键词。也:
如果您不使用 TLS 客户端身份验证,则需要使用基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 甚至 HTTP 基本身份验证(但仅通过 SSL)之类的内容。
换句话说,TLS 客户端身份验证是对 REST API 客户端进行身份验证的一种方法。因为最初的SO问题是关于SSL的,所以我提到TLS客户端身份验证是唯一的“内置”身份验证形式,如果你只依靠TLS。因此,如果您使用的是 TLS,并且未利用 TLS 客户端身份验证,则必须使用其他形式的身份验证来对客户端进行身份验证。
有许多方法可以对 REST 客户端进行身份验证。TLS客户端身份验证只是其中之一(TLS唯一的“内置”版本,通常非常安全)。但是,TLS是一种网络级协议,大多数人认为它对于许多最终用户来说太复杂而无法配置。因此,大多数REST API产品选择更易于使用的应用程序级协议,如HTTP,因为它对大多数人来说更容易使用(例如,只需设置一个HTTP标头)。
因此,如果您要采用 HTTP 标头路由,则必须使用标头值对 REST 客户端进行身份验证。
在 HTTP 身份验证中,您有一个标头 、及其值(标头名称非常不幸,因为它通常用于身份验证,而不是经常用于访问控制(即授权)。标头值是服务器用于执行身份验证的内容,它由三个令牌组成(通常)Authorization
Authorization
- HTTP 身份验证方案名称,后跟
- 空格(几乎总是空格字符),后跟
- 方案特定的文本值。
一种常见的HTTP身份验证方案是该方案,它非常...井。。。基本:)。方案特定的文本值只是以下计算值:Basic
String concatenated = username + ":" + raw_password;
String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray());
因此,您可能会看到相应的标头如下所示:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
服务器知道如何解析该值。它说“嘿,我知道这个方案,所以我要取尾随文本值,base64解码它,然后我将拥有用户名和提交的密码。然后,我可以看到这些值是否与我存储的值匹配。Basic
这本质上是身份验证。由于此方案特别包括提交的原始密码 base64 编码,因此除非您使用 TLS 连接,否则它不被认为是安全的。TLS保证(大多数情况下)窥探者无法拦截标头(例如,通过数据包检查)并查看密码是什么。这就是为什么您应该始终将 TLS 与 HTTP 基本身份验证结合使用的原因。即使在公司内部网环境中也是如此。Basic
当然,还有其他更安全的HTTP身份验证方案。例如,任何使用基于摘要的身份验证的方案。
基于摘要的身份验证方案更好,因为它们的方案文本值不包含提交的密码。相反,计算某些数据(通常是其他标头字段和值)的基于密码的哈希值,并将结果放入标头值中。服务器使用本地存储的密码计算相同的基于密码的哈希。如果服务器的计算值与请求的标头值匹配,则服务器可以认为请求已通过身份验证。Authorization
这就是为什么这种技术更安全的原因:只传输哈希值 - 而不是原始密码本身。这意味着这种技术甚至可以通过明文(非TLS)连接来验证请求(但只有在请求数据本身不敏感的情况下,您才需要这样做)。
一些基于摘要的身份验证方案:
亚马逊和其他类似的公司对REST来说比OAuth 1.0a更安全,因为它们总是对整个请求进行身份验证 - 包括请求实体有效负载(即HTTP标头后面的所有内容)。OAuth 1.0a 仅对与使用或有效负载的 REST API 无关的内容执行此操作(这些 API 是当今大多数 REST API)。application/x-www-form-urlencoded
application/xml
application/json
有趣的是,OAuth2不是基于摘要的 - 它使用了我认为不太安全的东西,称为“不记名令牌”(老实说,在许多情况下都很好,但仍然不如银行,军事和政府通信中使用的摘要方案)。