[英]How can I retrieve Basic Authentication credentials from the header?
I am trying to write some simple tests User Authentication mechanism which uses Basic Authentication.我正在尝试编写一些使用基本身份验证的简单测试用户身份验证机制。 How can I retrieve the credentials from the header?
如何从标题中检索凭据?
string authorizationHeader = this.HttpContext.Request.Headers["Authorization"];
Where do I go from here?我从这里去哪里? There are several tutorials but I new to .NET and authentication, could you explain in your answer exactly step-by-step the what and why you are doing.
有几个教程,但我是 .NET 和身份验证的新手,您能否在答案中逐步解释您正在做什么以及为什么这样做。
From my blog:来自我的博客:
This will explain in detail how this all works:这将详细解释这一切是如何工作的:
Whenever you use Basic Authentication a header is added to HTTP Request and it will look similar to this:每当您使用基本身份验证时,都会在 HTTP 请求中添加一个标头,它看起来类似于:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
授权:基本 QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Source: http://en.wikipedia.org/wiki/Basic_access_authentication来源: http : //en.wikipedia.org/wiki/Basic_access_authentication
"QWxhZGRpbjpvcGVuIHNlc2FtZQ==" is just "username:password" encoded in Base64( http://en.wikipedia.org/wiki/Base64 ). “QWxhZGRpbjpvcGVuIHNlc2FtZQ==”只是以Base64( http://en.wikipedia.org/wiki/Base64 )编码的“用户名:密码”。 In order to access headers and other HTTP properties in .NET (C#) you need to have access to the current Http Context:
为了访问 .NET (C#) 中的标头和其他 HTTP 属性,您需要访问当前的 Http 上下文:
HttpContext httpContext = HttpContext.Current;
This you can find in System.Web namespace.您可以在 System.Web 命名空间中找到它。
Authorization header isn't the only only one in the HttpContext.授权标头并不是 HttpContext 中唯一的标头。 In order to access the header, we need to get it from the request.
为了访问标头,我们需要从请求中获取它。
string authHeader = this.httpContext.Request.Headers["Authorization"];
(Alternatively you may use AuthenticationHeaderValue.TryParse as suggested in pasx's answer below ) (或者,您可以按照下面 pasx 的回答中的建议使用AuthenticationHeaderValue.TryParse )
If you debug your code you will see that the content of that header looks similar to this:如果您调试代码,您将看到该标头的内容类似于以下内容:
Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
基本 QWxhZGRpbjpvcGVuIHNlc2FtZQ==
You've already extracted the header now there are several things you need to do:您已经提取了标题,现在您需要做几件事:
Like so:像这样:
if (authHeader != null && authHeader.StartsWith("Basic")) {
//Extract credentials
} else {
//Handle what happens if that isn't the case
throw new Exception("The authorization header is either empty or isn't Basic.");
}
Now you have check that you are have something to extract data from.现在您已检查是否有可从中提取数据的内容。
You can now attempt to get the values for username and password.您现在可以尝试获取用户名和密码的值。 Firstly you need to get rid of the "Basic " substring.
首先,您需要摆脱“基本”子字符串。 You can do it like so:
你可以这样做:
string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
See the following links for further details:有关详细信息,请参阅以下链接:
Now we need to decode back from Base64 to string:现在我们需要从 Base64 解码回字符串:
//the coding should be iso or you could use ASCII and UTF-8 decoder
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
Now username and password will be in this format:现在用户名和密码将采用以下格式:
username:password
In order to get username and password we can simply get the index of the ":"为了获得用户名和密码,我们可以简单地获得“:”的索引
int seperatorIndex = usernamePassword.IndexOf(':');
username = usernamePassword.Substring(0, seperatorIndex);
password = usernamePassword.Substring(seperatorIndex + 1);
Now you can use these data for testing.现在您可以使用这些数据进行测试。 Good luck!
祝你好运!
The final code may look like this:最终代码可能如下所示:
HttpContext httpContext = HttpContext.Current;
string authHeader = this.httpContext.Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic")) {
string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string usernamePassword = encoding.GetString(Convert.FromBase64String(encodedUsernamePassword));
int seperatorIndex = usernamePassword.IndexOf(':');
var username = usernamePassword.Substring(0, seperatorIndex);
var password = usernamePassword.Substring(seperatorIndex + 1);
} else {
//Handle what happens if that isn't the case
throw new Exception("The authorization header is either empty or isn't Basic.");
}
Just adding to the main answer, the best way to get rid of the "Basic" substring is to use AuthenticationHeaderValue Class :只是添加到主要答案中,摆脱“基本”子字符串的最佳方法是使用AuthenticationHeaderValue Class :
var header = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
var credentials = header.Parameter;
It will throw a FormatException if the content of the header is not valid, eg: the "Basic" part is not present.如果标头的内容无效,它将抛出 FormatException,例如:“基本”部分不存在。
Alternatively if you do not want to have exception, use AuthenticationHeaderValue.TryParse或者,如果您不想出现异常,请使用AuthenticationHeaderValue.TryParse
Awesome answer from @DawidO.来自@DawidO 的精彩回答。
If you are just looking to extract the basic auth creds and rely on the .NET magic given you have HttpContext, this will also work:如果您只是想提取基本的身份验证凭证并依赖 .NET 魔法,因为您有 HttpContext,这也将起作用:
public static void StartListener() {
using (var hl = new HttpListener()) {
hl.Prefixes.Add("http://+:8008/");
hl.AuthenticationSchemes = AuthenticationSchemes.Basic;
hl.Start();
Console.WriteLine("Listening...");
while (true) {
var hlc = hl.GetContext();
var hlbi = (HttpListenerBasicIdentity)hlc.User.Identity;
Console.WriteLine(hlbi.Name);
Console.WriteLine(hlbi.Password);
//TODO: validater user
//TODO: take action
}
}
}
Remember, using strings can be less secure.请记住,使用字符串可能不太安全。 They will remain in memory untill they are picked by GC.
它们将保留在内存中,直到它们被 GC 选中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.