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和身份验证的新手,你能在答案中一步一步地解释你正在做什么和为什么。
2 个解决方案
#1
133
From my blog:
从我的博客:
This will explain in detail how this all works:
这将详细解释这一切是如何工作的:
Step 1 - Understanding Basic Authentication
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). In order to access headers and other HTTP properties in .NET (C#) you need to have access to the current Http Context:
“QWxhZGRpbjpvcGVuIHNlc2FtZQ ==”只是在Base64(http://en.wikipedia.org/wiki/Base64)中编码的“用户名:密码”。要在.NET(C#)中访问标头和其他HTTP属性,您需要有权访问当前的Http Context:
HttpContext httpContext = HttpContext.Current;
This you can find in System.Web namespace.
您可以在System.Web命名空间中找到它。
Step 2 - Getting the Header
Authorization header isn't the only only one in the HttpContext. In order to access the header, we need to get it from the request.
授权标头不是HttpContext中唯一的标头。为了访问标题,我们需要从请求中获取它。
string authHeader = this.httpContext.Request.Headers["Authorization"];
If you debug your code you will see that the content of that header looks similar to this:
如果您调试代码,您将看到该标头的内容与此类似:
Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==
Step 3 - Checking the header
You've already extracted the header now there are several things you need to do:
您已经提取了标题,因为您需要执行以下操作:
- Check that the header isn't null
- 检查标头是否为空
- Check that the Authorization/Authentication mechanism is indeed "Basic"
- 检查授权/认证机制是否确实“基本”
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.
现在您已经检查过您是否有从中提取数据的内容。
Step 4 - Extracting credentials
Removing "Basic " Substring
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:
有关详细信息,请参阅以下链接:
- http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/t97s7bs3(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/t97s7bs3(v=vs.110).aspx
Decoding Base64
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
Splitting 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!
现在您可以使用这些数据进行测试。祝你好运!
PS: the final code may look like this:
PS:最终代码可能如下所示:
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.");
}
#2
2
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:
如果你只想提取基本的auth信誉并依赖于.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
}
}
}
#1
133
From my blog:
从我的博客:
This will explain in detail how this all works:
这将详细解释这一切是如何工作的:
Step 1 - Understanding Basic Authentication
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). In order to access headers and other HTTP properties in .NET (C#) you need to have access to the current Http Context:
“QWxhZGRpbjpvcGVuIHNlc2FtZQ ==”只是在Base64(http://en.wikipedia.org/wiki/Base64)中编码的“用户名:密码”。要在.NET(C#)中访问标头和其他HTTP属性,您需要有权访问当前的Http Context:
HttpContext httpContext = HttpContext.Current;
This you can find in System.Web namespace.
您可以在System.Web命名空间中找到它。
Step 2 - Getting the Header
Authorization header isn't the only only one in the HttpContext. In order to access the header, we need to get it from the request.
授权标头不是HttpContext中唯一的标头。为了访问标题,我们需要从请求中获取它。
string authHeader = this.httpContext.Request.Headers["Authorization"];
If you debug your code you will see that the content of that header looks similar to this:
如果您调试代码,您将看到该标头的内容与此类似:
Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==
Step 3 - Checking the header
You've already extracted the header now there are several things you need to do:
您已经提取了标题,因为您需要执行以下操作:
- Check that the header isn't null
- 检查标头是否为空
- Check that the Authorization/Authentication mechanism is indeed "Basic"
- 检查授权/认证机制是否确实“基本”
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.
现在您已经检查过您是否有从中提取数据的内容。
Step 4 - Extracting credentials
Removing "Basic " Substring
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:
有关详细信息,请参阅以下链接:
- http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/t97s7bs3(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/t97s7bs3(v=vs.110).aspx
Decoding Base64
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
Splitting 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!
现在您可以使用这些数据进行测试。祝你好运!
PS: the final code may look like this:
PS:最终代码可能如下所示:
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.");
}
#2
2
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:
如果你只想提取基本的auth信誉并依赖于.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
}
}
}