java - HTTP基本认证而不是TLS客户端认证

标签 java web-services security rest authentication

下面的答案来自this问题;

The awarded answer doesn't actually address the question at all. It only mentions SSL in the context of data transfer and doesn't actually cover authentication.

You're really asking about securely authenticating REST API clients. Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API. SSL without client authc only authenticates the server, which is irrelevant for most REST APIs.

If you don't use TLS client authentication you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth or even HTTP Basic authentication (but over SSL only).


因此,考虑到我将在没有客户端认证的情况下使用 HTTPS
我的问题是发布者说,如果我们不使用客户端SSL认证服务器并不真正知道与谁通话。我在这里了解的是,如果我使用身份验证 token 来访问以对服务器进行客户端身份验证。然后,如果该 token 与我的服务器数据库中的用户ID配对,则服务器不知道谁正在发送 token 甚至
首先
1-这是一个真正的问题吗?如果我特别使用Https?(无TLS客户端身份验证)
2-最重要的是,假设这是一个重要的安全漏洞;如海报所述,Http基本身份验证如何提供帮助? Http基本身份验证仅在 header 中发送编码的用户名密码。因此,当客户端收到 token (发送用户名密码后返回作为返回)时,那么对于其余请求,他将在此 header 中使用该 token 代替密码,突然之间一切都好了吗?
Still Server仍不知道请求来自何处,也许服务器在其数据库中具有与匹配用户的有效 token ,但未知谁是发送请求的。
(尽管我仍然非常困难地认为 token 将通过https被盗并被其他人使用!)
每当我提出这个主题时,我都会得到答复。“好吧。您发送了 token ,但是服务器不知道是谁发送了 token ,不是很安全”,所以我理解这一点,因为浏览器保留了某种身份验证证书,服务器知道了哪里请求来自正确的位置,然后我可以确定与该 token 配对的用户(从我的数据库中检查过)“确实正确”
也许这里所说的不正确

最佳答案

[the] poster says if we dont use client SSL certification server does not really know whom its talking to.



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

Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API.



这里是关键词。也:

If you don't use TLS client authentication, you'll need to use something like a digest-based authentication scheme (like Amazon Web Service's custom scheme) or OAuth or even HTTP Basic authentication (but over SSL only).



换句话说,TLS客户端认证是认证REST API客户端的一种方式。因为最初的SO问题是专门针对SSL的,所以我提到的是,如果仅依赖TLS,则TLS客户端authc是唯一的“内置”身份验证形式。因此,如果您使用的是TLS,并且未使用TLS客户端身份验证,则必须使用另一种身份验证形式来验证客户端。

有很多认证REST客户端的方法。 TLS客户端身份验证只是其中之一(TLS的唯一“内置”身份验证,通常非常安全)。但是,TLS是网络级协议(protocol),大多数人认为TLS太复杂,以至于许多最终用户无法配置。因此,大多数REST API产品都选择了易于使用的应用程序级协议(protocol)(例如HTTP),因为它对大多数人来说更易于使用(例如,只需设置HTTP header )。

因此,如果要使用HTTP header 路由,则必须使用 header 值来认证REST客户端。

在HTTP身份验证中,您具有 header Authorization及其值( header 名称非常不幸,因为它通常用于身份验证,而不是经常用于访问控制或授权)。 Authorization header 值是服务器用于执行身份验证的值,它(通常)由三个 token 组成
  • HTTP认证方案名称,后跟
  • 空格(几乎总是空格),然后是
  • 特定于方案的文本值。

  • 一种常见的HTTP身份验证方案是Basic方案,它非常……好……基本:)。特定于方案的文本值只是以下计算值:
    String concatenated = username + ":" + raw_password;
    String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray());
    

    因此,您可能会看到相应的标题如下:
    Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
    

    服务器知道如何解析该值。它说:“嘿,我知道Basic方案,所以我要获取尾随文本值,对它进行base64解码,然后我将获得用户名和提交的密码。然后我可以查看这些值是否与我的值匹配存储。”

    这本质上就是Basic身份验证。因为此方案特别包含提交的以base64编码的原始密码,所以除非您使用TLS连接,否则它不被认为是安全的。 TLS保证(主要是)窥视不会截获 header (例如通过封包检查)并查看密码是什么。这就是为什么除非通过TLS连接,否则永远不要使用HTTP Basic身份验证的原因。始终-即使在公司Intranet环境中。

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

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

    这就是为什么这种技术更安全的原因:仅传输哈希,而不传输原始密码本身。这意味着即使在明文(非TLS)连接上也可以使用此技术对请求进行身份验证(但是,如果请求数据本身当然不敏感,则只需要这样做)。

    一些基于摘要的身份验证方案:
  • OAuth 1.0a, aka RFC 5849
  • HTTP Digest Access身份验证(由浏览器本地使用)。
  • Stormpath's custom scheme(完整披露,我是Stormpath的CTO)。
  • Amazon AWS's custom scheme

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

    有趣的是,OAuth2不是基于摘要的-它使用了我认为不太安全的东西,称为“承载者 token ”,我认为这是OAuth 2的various problems的症状。

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

    关于java - HTTP基本认证而不是TLS客户端认证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14043397/

    相关文章:

    java - 如何将.md5和.sha1校验和文件上传到bintray?

    java - 使用 Google App Engine 的自定义 android 身份 validator

    python - Suds 性能 - client.factory.create() 需要超过 2 分钟

    javascript - 阻止在 Azure 中查看网站代码

    react-native - 如何处理内存中的 React Native 敏感字符串信息

    java - 从 CSS/JS 文件中访问 servlets web 应用程序上下文 URL

    java - build 者该如何曝光?

    linux - 服务器 composer install --no-dev killed

    c# - 将 URI 参数映射到参数对象的属性?

    再次进行 ASP.NET 重放攻击检测