HTTP基本身份validation而不是TLS客户端认证

以下答案来自这个问题;

获奖答案实际上并未解决问题。 它仅在数据传输的上下文中提及SSL,并不实际涵盖身份validation。

您真的要求安全地validationREST API客户端。 除非您使用TLS客户端身份validation,否则SSL本身不是REST API的可行身份validation机制。 没有客户端authc的SSL仅对服务器进行身份validation,这与大多数REST API无关。

如果您不使用TLS客户端身份validation,则需要使用类似基于摘要的身份validation方案(如Amazon Web Service的自定义方案)或OAuth甚至HTTP Basic身份validation(但仅限SSL)。

因此,考虑到我将使用没有客户端认证的HTTPS我的问题是海报说如果我们不使用客户端SSL认证服务器并不真正知道它与谁交谈。 我在这里理解的是,如果我使用身份validation令牌来访问服务器对客户端进行身份validation。 然后, 即使该令牌与我的服务器数据库中的用户ID配对,服务器也不知道谁正在发送令牌。

首先

1 – 这是一个真正的问题吗? 如果我特别使用Https?(没有TLS客户端身份validation)

2-而且最重要的是,假设这是一个重要的安全缺陷; 如海报所述,Http基本身份validation如何帮助? Http基本身份validation只是在标头中发送编码的用户名密码。 因此,当客户端收到令牌( 在他发送用户名密码后作为回报),然后对于其余的请求,他将在此标头中使用此令牌而不是密码,一切都很好吗?

仍然服务器不知道请求来自何处,也许服务器在其数据库中具有匹配用户的有效令牌但未知谁真正发送它。 (虽然我仍然很难看到令牌会被https窃取并被其他人使用!)

每当我带这个主题时,我都会得到答复。“嗯..你发送一个令牌,但服务器不知道谁发送令牌,不是很安全”所以我理解这一点,因为浏览器保持一种认证,服务器知道哪里请求来自正确的地方然后我可以确定与该令牌配对的用户(从我的数据库检查)是“非常正确”

或者也许在这里讲的是不正确的

[海报]说如果我们不使用客户端SSL认证服务器并不真正知道它与谁交谈。

那不是我说的:)这就是我说的:

除非您使用TLS客户端身份validation,否则SSL本身不是REST API的可行身份validation机制。

孤独是这里的关键词。 也:

如果您不使用TLS客户端身份validation,则需要使用类似基于摘要的身份validation方案(如Amazon Web Service的自定义方案)或OAuth甚至HTTP基本身份validation(但仅限于SSL)。

换句话说,TLS客户端身份validation是validationREST API客户端的一种方法。 因为最初的SO问题是关于SSL的,所以我提到如果你单独依赖TLS,那么TLS客户端authc是唯一的“内置”身份validationforms。 因此,如果您正在使用TLS,并且未使用TLS客户端身份validation,则必须使用其他forms的身份validation来validation您的客户端。

有许多方法可以对REST客户端进行身份validation。 TLS客户端authc只是其中之一(唯一的’内置’用于TLS,通常非常安全)。 但是,TLS是一种网络级协议,大多数人认为它太复杂,无法配置许多最终用户。 因此,大多数REST API产品都选择了易于使用的应用程序级协议,如HTTP,因为大多数人都可以使用它(例如,只需设置HTTP标头)。

因此,如果您要使用HTTP标头路由,则必须使用标头值来validationREST客户端。

在HTTP身份validation中,您有一个标头, Authorization及其值(标头名称相当不幸,因为它通常用于身份validation,而不是通常用于访问控制,即授权)。 Authorization标头值是服务器用于执行身份validation的值,它由(通常)三个令牌组成

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

一种常见的HTTP身份validation方案是Basic方案,它非常……很好……基本:)。 特定于方案的文本值只是以下计算值:

 String concatenated = username + ":" + raw_password; String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray()); 

所以您可能会看到相应的标题如下所示:

 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== 

服务器知道如何解析该值。 它说“嘿,我知道Basic方案,所以我将采用尾随文本值,base64 解码它,然后我将拥有用户名和提交的密码。然后我可以看到这些值是否与我的相符存储“。

这基本上是Basic身份validation。 由于此方案特别包括提交的原始密码base64编码,因此除非您使用TLS连接, 否则不会将其视为安全。 TLS保证(大多数情况下)窥探眼睛不能拦截标题(例如通过数据包检查)并查看密码是什么。 这就是为什么除非通过TLS连接,否则不应使用HTTP基本身份validation。 始终 – 即使在公司内部网环境中也是如此

当然还有其他更安全的HTTP身份validation方案。 一个示例是使用基于摘要的身份validation的任何方案。

基于摘要的身份validation方案更好,因为它们的方案文本值不包含提交的密码。 相反,计算某些数据(通常是其他标题字段和值)的基于密码的哈希值,并将结果放入Authorization标头值中。 服务器使用本地存储的密码计算相同的基于密码的哈希。 如果服务器的计算值与请求的标头值匹配,则服务器可以认为该请求已通过身份validation。

这就是为什么这种技术更安全的原因:只传输一个哈希 – 而不是原始密码本身。 这意味着即使在明文(非TLS)连接上,这种技术也可用于validation请求(但如果请求数据本身当然不敏感,您只想这样做)。

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

  • OAuth 1.0a,又名RFC 5849 。
  • HTTP摘要访问身份validation(本机浏览器使用)。
  • Stormpath的定制方案 (完全披露,我是Stormpath的首席技术官)。
  • 亚马逊AWS的自定义方案 。

Stormpath和Amazon对于REST比OAuth 1.0a更安全,因为它们始终对请求实体有效负载进行身份validation。 OAuth 1.0a仅针对application/x-www-form-urlencoded内容执行此操作,该内容与使用application/xmlapplication/json有效负载的REST API无关(现在看起来似乎是大多数REST API)。

有趣的是,OAuth2 不是基于摘要的 – 它使用我认为不太安全的东西,称为“持票人令牌”,这在我看来是OAuth 2的各种问题的症状。

最后,是的,这是一个无耻的插件,但如果你不想担心这些东西,只需使用Stormpath (许多用例是免费的)。 我们自动化这些东西,所以你的应用程序不必。

当我们谈论“认证用户”时,我们真正的意思是“检查用户是否知道其他人不应该知道的事情”。 那些“东西”可能是密码,证书,硬件安全令牌,甚至是用户的视网膜模式,但在所有情况下,它都是我们真正检查的信息的访问权限,而不是用户的身份(无论是真的意味着)。

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

也许我误解了这个问题。

你引用的答案告诉我,如果你不使用某种forms的身份validation,无论是客户端证书,HTTP BASICAUTH还是其他什么,服务器都不知道它与谁通信。

(也许这对你的应用来说没问题,也许不是,只有你能回答。)

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

在此上下文中,身份validation是通过某些凭据建立身份的过程。

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

当您使用GMail时,您使用的是SSL,Google如何知道它正在与交谈?