30

下面的答案来自这个问题;

授予的答案实际上根本没有解决这个问题。它仅在数据传输的上下文中提及 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 被盗并被其他人使用!)

每当我提出这个主题时,我都会收到回复..“嗯..你发送了一个令牌,但服务器不知道谁发送了这个令牌,不是很安全”所以我理解这一点,因为浏览器保持一种身份验证,服务器知道在哪里请求来自正确的地方然后我可以确定具有该令牌的配对用户(从我的数据库中检查)是“真正正确的”

或者也许这里所说的不正确

4

3 回答 3

77

[the] 海报说,如果我们不使用客户端 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头值是服务器用来执行身份验证的值,它(通常)由三个令牌组成

  1. HTTP 身份验证方案名称,后跟
  2. 空格(几乎总是一个空格字符),后跟
  3. 特定于方案的文本值。

一种常见的 HTTP 身份验证方案是该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)连接也可以使用此技术对请求进行身份验证(但当然,如果请求数据本身不敏感,您只想这样做)。

一些基于摘要的身份验证方案:

Amazon 和其他类似的 REST 比 OAuth 1.0a 更安全,因为它们始终验证整个请求 - 包括请求实体有效负载(即 HTTP 标头之后的所有内容)。OAuth 1.0a 仅针对与使用或有效负载application/x-www-form-urlencoded的 REST API 无关的内容(目前大多数 REST API)执行此操作。application/xmlapplication/json

有趣的是,OAuth2不是基于摘要的——它使用了我认为不太安全的东西,称为“不记名令牌”(在许多情况下确实很好,但仍然不如银行、军事和政府通信中使用的摘要方案)。

于 2012-12-26T21:37:07.863 回答
10

当我们谈论“验证用户”时,我们真正的意思是“检查用户是否知道其他人不应该知道的事情”。那个“东西”可能是密码、证书、硬件安全令牌甚至是用户的视网膜图案,但在所有情况下,我们真正检查的是对这些信息的访问,而不是用户的身份(不管那是真的指)本身。

关键是,原则上,所有这些身份验证器都可能被窃取并用于冒充用户。可以记录密码,可以从存储它的磁盘复制证书,可以窃取硬件令牌(并且可能进行逆向工程和克隆),原则上甚至可以扫描、记录和伪造用户的视网膜图案。我们能做的最好的事情是,在每种情况下,都尽量让这件事变得“非常困难”。

于 2012-12-26T17:13:06.153 回答
6

也许我误解了这个问题。

您引用的答案对我说,如果您不使用某种形式的身份验证,无论是客户端证书、HTTP BASICAUTH 还是其他方式,服务器都不知道它正在与谁通信。

(也许这对您的应用程序没问题,也许不是,只有您可以回答。)

换句话说,如果您确实使用某种形式的身份验证,服务器确实知道它正在与谁通信;它正在与经过身份验证的凭据所属的“人”进行通信。

在这种情况下,身份验证是通过某些凭据建立身份的过程。

身份验证不能保证凭据没有被盗。SSL 保证(我不会说它“保证”)凭据在客户端和服务器之间的传输是安全的。

当您使用 GMail 时,您使用的是 SSL,Google 怎么知道它在与交谈?

于 2012-12-26T17:10:59.200 回答