授予的答案实际上根本没有解决这个问题。它仅在数据传输的上下文中提及 SSL,实际上并未涵盖身份验证。 您确实在询问安全地验证 REST API 客户端。除非您使用 TLS 客户端身份验证,否则单独的 SSL 不是 REST API 的可行身份验证机制。没有客户端身份验证的 SSL 仅对服务器进行身份验证,这与大多数 REST API 无关。 如果您不使用 TLS 客户端身份验证,则需要使用基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 甚至 HTTP 基本身份验证(但仅通过 SSL)。
授予的答案实际上根本没有解决这个问题。它仅在数据传输的上下文中提及 SSL,实际上并未涵盖身份验证。
您确实在询问安全地验证 REST API 客户端。除非您使用 TLS 客户端身份验证,否则单独的 SSL 不是 REST API 的可行身份验证机制。没有客户端身份验证的 SSL 仅对服务器进行身份验证,这与大多数 REST API 无关。
如果您不使用 TLS 客户端身份验证,则需要使用基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 甚至 HTTP 基本身份验证(但仅通过 SSL)。
所以考虑到我将在没有客户端认证的情况下使用 HTTPS, 我的问题是海报说如果我们不使用客户端 SSL 认证服务器并不真正知道它与谁交谈。我在这里理解的是,如果我使用身份验证令牌来访问以针对服务器对客户端进行身份验证。然后服务器不知道谁在发送令牌,即使该令牌与我的服务器数据库中的用户 ID 配对。
首先
1-这是一个真正的问题吗?如果我特别使用 Https?(没有 TLS 客户端身份验证)
2-也是最重要的,假设这是一个重要的安全漏洞;如海报所述,Http基本身份验证如何在这里提供帮助?Http 基本身份验证只是在标头中发送编码的用户名密码。因此,当客户端收到一个令牌(在他发送用户名密码后作为回报)然后对于他的其余请求,他将在此标头中使用此令牌而不是密码,并且一切都很好吗?
仍然服务器不知道请求来自哪里,也许服务器在其数据库中有一个有效令牌与匹配的用户,但不知道谁真正发送它。(虽然我仍然很难看到令牌会通过 https 被盗并被其他人使用!)
每当我提出这个主题时,我都会收到回复..“嗯..你发送了一个令牌,但服务器不知道谁发送了这个令牌,不是很安全”所以我理解这一点,因为浏览器保持一种身份验证,服务器知道在哪里请求来自正确的地方然后我可以确定具有该令牌的配对用户(从我的数据库中检查)是“真正正确的”
或者也许这里所说的不正确
[the] 海报说,如果我们不使用客户端 SSL 认证,服务器并不真正知道它在与谁交谈。
那不是我说的:) 这就是我说的:
除非您使用 TLS 客户端身份验证,否则单独的 SSL 不是 REST API 的可行身份验证机制。
单独是这里的关键词。还:
换句话说,TLS 客户端身份验证是对 REST API 客户端进行身份验证的一种方式。因为最初的 SO 问题是关于 SSL 的,所以我提到如果您仅依赖 TLS,TLS 客户端身份验证是唯一的“内置”身份验证形式。因此,如果您使用 TLS,并且不利用 TLS 客户端身份验证,则必须使用其他形式的身份验证来验证您的客户端。
有很多方法可以对 REST 客户端进行身份验证。TLS 客户端身份验证只是其中之一(TLS 的唯一“内置”身份验证,通常非常安全)。然而,TLS 是一种网络级协议,大多数人认为对于许多最终用户来说配置过于复杂。因此,大多数 REST API 产品选择更易于使用的应用程序级协议,例如 HTTP,因为它对大多数人来说更易于使用(例如,只需设置一个 HTTP 标头)。
因此,如果您要使用 HTTP 标头路由,则必须使用标头值来验证 REST 客户端。
在 HTTP 身份验证中,您有一个标头 ,Authorization和它的值(标头名称相当不幸,因为它通常用于身份验证,而不是经常用于访问控制,即授权)。标Authorization头值是服务器用来执行身份验证的值,它(通常)由三个令牌组成
Authorization
一种常见的 HTTP 身份验证方案是该Basic方案,它非常……嗯……基本 :)。特定于方案的文本值只是以下计算值:
Basic
String concatenated = username + ":" + raw_password; String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray());
因此,您可能会看到相应的标题如下所示:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
服务器知道如何解析该值。它说“嘿,我知道Basic方案,所以我将采用尾随文本值,base64对其进行解码,然后我将获得用户名和提交的密码。然后我可以查看这些值是否与我存储的值匹配。”
这本质上是Basic身份验证。因为这个方案特别包括提交的原始密码 base64 编码,所以除非您使用 TLS 连接,否则它不被认为是安全的。TLS 保证(大部分)窥探者无法拦截标头(例如通过数据包检查)并查看密码是什么。这就是为什么您应该始终将 TLS 与 HTTP 基本身份验证一起使用。即使在公司内部网环境中。
当然,还有其他更安全的 HTTP 身份验证方案。一个示例是使用基于摘要的身份验证的任何方案。
基于摘要的身份验证方案更好,因为它们的方案文本值不包含提交的密码。相反,计算某些数据(通常是其他标头字段和值)的基于密码的散列,并将结果放入Authorization标头值中。服务器使用它在本地存储的密码计算相同的基于密码的哈希值。如果服务器的计算值与请求的标头值匹配,则服务器可以认为请求已通过身份验证。
这就是为什么这种技术更安全的原因:只传输散列 - 而不是原始密码本身。这意味着即使通过明文(非 TLS)连接也可以使用此技术对请求进行身份验证(但如果请求数据本身当然不敏感,您只会希望这样做)。
一些基于摘要的身份验证方案:
亚马逊和其他喜欢它的 REST 比 OAuth 1.0a 更安全,因为它们总是对整个请求进行身份验证 - 包括请求实体有效负载(即 HTTP 标头之后的所有内容)。OAuth 1.0a 仅针对与使用或有效负载application/x-www-form-urlencoded的 REST API 无关的内容(目前大多数 REST API)执行此操作。application/xml``application/json
application/x-www-form-urlencoded
application/xml``application/json
有趣的是,OAuth2不是基于摘要的——它使用了我认为不太安全的东西,称为“不记名令牌”(在许多情况下确实很好,但仍然不如银行、军事和政府通信中使用的摘要方案)。