java HTTP 基本身份验证而不是 TLS 客户端认证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14043397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTTP Basic Authentication instead of TLS client certification
提问by Spring
The answer below is from thisquestion;
下面的答案来自这个问题;
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).
获奖答案实际上根本没有解决问题。它仅在数据传输的上下文中提及 SSL,实际上并未涵盖身份验证。
您确实在询问安全地对 REST API 客户端进行身份验证。除非您使用 TLS 客户端身份验证,否则单独的 SSL 不是 REST API 的可行身份验证机制。没有客户端身份验证的 SSL 仅对服务器进行身份验证,这与大多数 REST API 无关。
如果您不使用 TLS 客户端身份验证,则需要使用诸如基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 或什至 HTTP 基本身份验证(但仅通过 SSL)之类的东西。
So considering I will use HTTPS without client certificationmy question here is poster says if we dont use client SSL certificationserver does not really know whom its talking to. What I understand here is if I use a authentication-token to access to authenticate the client against the server. Then server does not know whom is sending the token evenif that token is paired with a user id in my servers database.
因此,考虑到我将在没有客户端认证的情况下使用HTTPS,我的问题是海报说如果我们不使用客户端 SSL 认证服务器真的不知道它在与谁交谈。我在这里理解的是,如果我使用身份验证令牌来访问以针对服务器对客户端进行身份验证。然后服务器不知道谁在发送令牌,即使该令牌与我的服务器数据库中的用户 ID 配对。
First of all
首先
1-is this a real problem? If I especialy use Https?(without TLS client authentication)
1-这是一个真正的问题吗?如果我特别使用 Https?(没有 TLS 客户端身份验证)
2- and most important, assuming that is an important security flaw; How can Http basic authentication help here as poster mentioned? Http basic authentication just sends encoded username password in a header. So when client receives a token (in return after he sends his username password)then for the rest of his requests he will use this token in this header instead of password, and everything is fine all of a sudden?
2- 最重要的是,假设这是一个重要的安全漏洞;如海报所述,Http 基本身份验证如何在此处提供帮助?Http 基本身份验证只是在标头中发送编码的用户名密码。因此,当客户端收到一个令牌(在他发送用户名密码后作为回报)时,对于他的其余请求,他将在此标头中使用此令牌而不是密码,突然一切都好了?
Still Server does not know from where the request is coming from, maybe server has a valid token with a matched user in its database but unknown who reallysendit. (while I still see this very hard that the token would be stolen over https and used by someone else!)
仍然服务器不知道请求来自哪里,也许服务器在其数据库中有一个匹配用户的有效令牌,但不知道是谁真正发送了它。(虽然我仍然很难看到令牌会通过 https 被盗并被其他人使用!)
Whenever I bring this subject I get replies.."Well..you send a token but server does not know whom send the token, not very secure" so I understand this as the browser keeps a sort of auth-certification and server knows where the request is coming from the right place THEN I can be sure that the paired user with that token (checked from my DB)is "really correct"
每当我提出这个主题时,我都会收到回复..“好吧..你发送了一个令牌,但服务器不知道是谁发送了令牌,不是很安全”所以我理解这一点,因为浏览器保留了某种身份验证,而服务器知道在哪里请求来自正确的地方然后我可以确定具有该令牌的配对用户(从我的数据库中检查)是“真正正确的”
Or maybe what am telling here is not correct
或者也许我在这里说的是不正确的
回答by Les Hazlewood
[the] poster says if we dont use client SSL certification server does not really know whom its talking to.
[the] 海报说如果我们不使用客户端 SSL 认证服务器真的不知道它在与谁交谈。
That's not what I said :) This is what I said:
那不是我说的:) 这是我说的:
Unless you're using TLS client authentication, SSL alone is NOT a viable authentication mechanism for a REST API.
除非您使用 TLS 客户端身份验证,否则单独的 SSL 不是 REST API 的可行身份验证机制。
alonebeing the key word here. Also:
唯一是这里的关键词。还:
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 客户端身份验证,则需要使用诸如基于摘要的身份验证方案(如 Amazon Web Service 的自定义方案)或 OAuth 甚至 HTTP 基本身份验证(但仅通过 SSL)之类的东西。
In other words, TLS client authentication is oneway of authenticating a REST API client. Because the original SO question was about SSL specifically, I was mentioning that TLS client authc is the only 'built in' form of authentication if you're relying on TLS alone. Therefore, if you're using TLS, and you don't leverage TLS client authc, you mustuse another form of authentication to authenticate your client.
换句话说,TLS 客户端身份验证是对 REST API 客户端进行身份验证的一种方式。因为最初的 SO 问题是专门关于 SSL 的,所以我提到 TLS 客户端身份验证是唯一的“内置”身份验证形式,如果您仅依赖 TLS。因此,如果您使用 TLS,并且不利用 TLS 客户端身份验证,则必须使用另一种身份验证形式来对您的客户端进行身份验证。
There are many ways to authenticate REST Clients. TLS client authc is just one of them (the only 'built in' one for TLS and usually very secure). However, TLS is a network-level protocol and is perceived by most to be too complicated for many end-users to configure. So most REST API offerings opt for an easier-to-use application-level protocol like HTTP because it is easier for most to use (e.g. just set an HTTP header).
有多种方法可以对 REST 客户端进行身份验证。TLS 客户端身份验证只是其中之一(TLS 的唯一“内置”身份验证,通常非常安全)。然而,TLS 是一种网络级协议,大多数人认为它太复杂,许多最终用户无法配置。因此,大多数 REST API 产品选择更易于使用的应用程序级协议,如 HTTP,因为它对大多数人来说更易于使用(例如,只需设置一个 HTTP 标头)。
So, if you're going the HTTP header route, you have to use a header value to authenticate a REST client.
因此,如果您要使用 HTTP 标头路由,则必须使用标头值来验证 REST 客户端。
In HTTP authentication, you have a header, Authorization
, and its value (the header name is rather unfortunate because it is usually used for authentication and not as often for access control, aka authorization). The Authorization
header value is what is used by the server to perform authentication, and it is composed (usually) of three tokens
在 HTTP 身份验证中,您有一个标头Authorization
和它的值(标头名称相当不幸,因为它通常用于身份验证而不是经常用于访问控制,也就是授权)。的Authorization
报头值是什么是由服务器使用以执行认证,并且它的三个令牌组成(通常)
- An HTTP authentication scheme name, followed by
- white space (almost always a space character), followed by
- The scheme-specific text value.
- HTTP 身份验证方案名称,后跟
- 空格(几乎总是一个空格字符),然后是
- 特定于方案的文本值。
One common HTTP authentication Scheme is the Basic
scheme, which is very... well... basic :). The scheme-specific text value is simply the following computed value:
一种常见的 HTTP 身份验证方案是Basic
方案,它非常......好吧......基本:)。特定于方案的文本值只是以下计算值:
String concatenated = username + ":" + raw_password;
String schemeSpecificTextValue = base_64_encode(concatenated.toCharArray());
So you might see a corresponding header look like this:
因此,您可能会看到相应的标题如下所示:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
The server knows how to parse the value. It says "Hey, I know the Basic
scheme, so I'm going to take the trailing text value, base64 decodeit, and then I'll have the username and submitted password. Then I can see if those values match what I have stored."
服务器知道如何解析该值。它说“嘿,我知道这个Basic
方案,所以我将采用尾随文本值,base64解码它,然后我将获得用户名和提交的密码。然后我可以看看这些值是否与我存储的值匹配.”
And that's essentially Basic
authentication. Because this scheme in particular includes the submitted rawpassword base64 encoded, it is not considered secure unlessyou use a TLS connection. TLS guarantees (mostly) that prying eyes can't intercept the headers (e.g. via packet inspection) and see what the password is. This is why you should neveruse HTTP Basic authentication unless it is over a TLS connection. Always- even in company intranet environments.
这本质上是Basic
身份验证。因为这个方案特别包括提交的原始密码 base64 编码,除非您使用 TLS 连接,否则它不被认为是安全的。TLS 保证(主要是)窥探者无法拦截标头(例如通过数据包检查)并查看密码是什么。这就是为什么你应该从来不使用HTTP基本身份验证,除非它是通过TLS连接。始终- 即使在公司内部网环境中。
There are other even more secure HTTP Authentication schemes of course. An example is any scheme that that uses digest-based authentication.
当然还有其他更安全的 HTTP 身份验证方案。一个示例是使用基于摘要的身份验证的任何方案。
Digest-based authentication schemes are better because their scheme text value does notcontain the submitted password. Instead, a password-based-hash of certain data (often other header fields and values) is calculated and the result is put in the Authorization
header value. The server calculates the same password-based-hash using the password it has stored locally. If the server's computed value matches the request's header value, the server can consider the request authenticated.
基于摘要身份验证方案更好,因为他们的方案文本值并没有包含在提交的密码。相反,计算某些数据(通常是其他标头字段和值)的基于密码的哈希,并将结果放入Authorization
标头值中。服务器使用它在本地存储的密码计算相同的基于密码的哈希。如果服务器的计算值与请求的标头值匹配,则服务器可以认为请求已通过身份验证。
Here's why this technique is more secure: only a hash is transmitted - not the raw password itself. That means this technique can be used to authenticate requests even over clear-text (non TLS) connections (but you would only want to do this if the request data itself is not sensitive of course).
这就是为什么这种技术更安全的原因:只传输散列 - 而不是原始密码本身。这意味着该技术甚至可以用于通过明文(非 TLS)连接对请求进行身份验证(当然,如果请求数据本身不敏感,您只会希望这样做)。
Some digest-based authentication schemes:
一些基于摘要的身份验证方案:
- OAuth 1.0a, aka RFC 5849.
- HTTP Digest Accessauthentication (used by browsers natively).
- Stormpath's custom scheme(full disclosure, I'm Stormpath's CTO).
- Amazon AWS's custom scheme.
- OAuth 1.0a,又名 RFC 5849。
- HTTP 摘要访问身份验证(由浏览器本机使用)。
- Stormpath 的自定义方案(完全公开,我是 Stormpath 的 CTO)。
- 亚马逊 AWS 的自定义方案。
Stormpath's and Amazon's are more secure for REST than OAuth 1.0a because they alwaysauthenticate the request entity payload. OAuth 1.0a only does this for application/x-www-form-urlencoded
content which isn't relevant for REST APIs that use application/xml
or application/json
payloads (which appears to be most REST APIs these days).
Stormpath 和 Amazon 的 REST 比 OAuth 1.0a 更安全,因为它们始终对请求实体有效负载进行身份验证。OAuth 1.0a 仅对application/x-www-form-urlencoded
与使用的 REST APIapplication/xml
或application/json
有效负载(目前似乎是大多数 REST API)无关的内容执行此操作。
Interestingly, OAuth2 is notdigest based - it uses something I consider less secure, called 'bearer tokens', which is in my opinion symptomatic of OAuth 2's various problems.
有趣的是,OAuth2不是基于摘要的——它使用我认为不太安全的东西,称为“承载令牌”,在我看来,这是 OAuth 2各种问题的症状。
Finally, and yes, this is a shameless plug, but if you don't want to worry about this stuff, just use Stormpath(many use cases are free). We automate this stuff so your apps don't have to.
最后,是的,这是一个无耻的插件,但是如果您不想担心这些东西,只需使用Stormpath(许多用例都是免费的)。我们将这些东西自动化,因此您的应用程序不必这样做。
回答by Ilmari Karonen
When we talk about "authenticating a user", what we really mean is "checking that the user knows something nobody else should know". That "something" might be a password, a certificate, a hardware security token or even the user's retinal pattern, but in all cases it's the access to that information that we're really checking, not the identity of the user (whatever that really means) as such.
当我们谈论“对用户进行身份验证”时,我们真正的意思是“检查用户是否知道其他人不应该知道的事情”。那个“东西”可能是密码、证书、硬件安全令牌,甚至是用户的视网膜模式,但在所有情况下,我们真正检查的是对信息的访问,而不是用户的身份(不管那是什么)意味着)。
The point is that, in principle, allthese authenticators could be stolen and used to impersonate the user. A password could be logged, a certificate could be copied from the disk it's stored on, a hardware token could be stolen (and possibly reverse engineered and cloned) and even the user's retinal pattern could, in principle, be scanned, recorded and faked. the best we can do is, in each case, to try to make this as "very hard" as possible.
关键是,原则上,所有这些身份验证器都可能被窃取并用于冒充用户。可以记录密码,可以从存储它的磁盘复制证书,可以窃取硬件令牌(并且可能进行逆向工程和克隆),原则上甚至可以扫描、记录和伪造用户的视网膜模式。我们能做的最好的事情就是,在每种情况下,尽量使这变得“非常困难”。
回答by cschneid
Maybe I'm misunderstanding the question.
也许我误解了这个问题。
The answer you have quoted says to me that if you don't use someform of authentication, whether it is client certificates, HTTP BASICAUTH, or something else, the server doesn't know with whom it is communicating.
您引用的答案对我说,如果您不使用某种形式的身份验证,无论是客户端证书、HTTP BASICAUTH 还是其他什么,服务器都不知道它正在与谁进行通信。
(Maybe that's okay for your application, maybe it isn't, only you can answer that.)
(也许这对您的应用程序没问题,也许不是,只有您可以回答。)
Stated in other terms, if you do use some form of authentication, the server does know with whom it is communicating; it is communicating with the "person" to whom the authenticated credentials belong.
换句话说,如果您确实使用某种形式的身份验证,服务器确实知道它正在与谁通信;它正在与经过身份验证的凭据所属的“人”进行通信。
In this context, authentication is the process of establishing identity via some credentials.
在这种情况下,身份验证是通过某些凭据建立身份的过程。
Authentication does not guarantee that the credentials have not been stolen. SSL assures (I wouldn't go so far as to say it "guarantees") the credentials are secure in transit between client and server.
身份验证并不能保证凭据未被窃取。SSL 确保(我不会说它“保证”)凭据在客户端和服务器之间传输时是安全的。
When you use GMail, you're using SSL, how does Google know it's talking to you?
当您使用 GMail 时,您使用的是 SSL,Google 如何知道它在与您交谈?