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

时间:2012-12-26 16:37:22

标签: java web-services security rest authentication

以下答案来自this问题;

  

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

     

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

     

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

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

首先

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

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

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

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

或者说这里说的不正确

3 个答案:

答案 0 :(得分:72)

  

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

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

  

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

单独

是关键词。也:

  

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

换句话说,TLS客户端身份验证是一种方式来验证REST API客户端。因为最初的SO问题是关于SSL的,所以我提到TLS客户端authc是唯一内置的'如果您仅依靠TLS,则需要进行身份验证。因此,如果您正在使用TLS,并且未充分利用TLS客户端身份验证,则必须使用其他形式的身份验证来验证您的客户端。

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

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

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

  1. HTTP身份验证方案名称,后跟
  2. 空白区域(几乎总是空格字符),然后是
  3. 特定于计划的文字值。
  4. 一种常见的HTTP身份验证方案是Basic方案,它非常......基本:)。特定于方案的文本值只是以下计算值:

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

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

    Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
    

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

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

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

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

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

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

    对于REST而言,Stormpath和Amazon比OAuth 1.0a更安全,因为他们总是对请求实体有效负载进行身份验证。 OAuth 1.0a仅针对application/x-www-form-urlencoded内容执行此操作,这与使用application/xmlapplication/json有效负载(目前似乎是大多数REST API)的REST API无关。 / p>

    有趣的是,OAuth2基于而非摘要 - 它使用我认为不太安全的东西,称为“承载令牌”,这在我看来是OAuth 2的症状various problems

    最后,是的,这是一个无耻的插件,但如果你不想担心这些问题,只需使用Stormpath(许多用例是免费的)。我们会自动执行这些操作,因此您的应用无需执行此操作。

答案 1 :(得分:10)

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

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

答案 2 :(得分:6)

也许我误解了这个问题。

您引用的答案告诉我,如果您不使用某种形式的身份验证,无论是客户端证书,HTTP BASICAUTH还是其他内容,服务器都不知道是谁在沟通。

(也许这对你的申请没问题,也许不是,只有你能回答。)

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

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

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

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