如何从标头中检索基本身份验证凭据?

47 .net c# authentication basic-authentication

我正在尝试编写一些使用基本身份验证的简单测试用户身份验证机制.如何从标题中检索凭据?

string authorizationHeader = this.HttpContext.Request.Headers["Authorization"];
Run Code Online (Sandbox Code Playgroud)

我从哪里开始?有几个教程,但我是.NET和身份验证的新手,你能在答案中一步一步地解释你正在做什么和为什么.

Daw*_*d O 176

来自我的博客:

这将详细解释这一切是如何工作的:

第1步 - 了解基本身份验证

每当您使用基本身份验证时,都会向HTTP请求添加一个标头,它将类似于:

授权:基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

资料来源:http://en.wikipedia.org/wiki/Basic_access_authentication

"QWxhZGRpbjpvcGVuIHNlc2FtZQ =="只是在Base64(http://en.wikipedia.org/wiki/Base64)中编码的"用户名:密码" .要在.NET(C#)中访问标头和其他HTTP属性,您需要有权访问当前的Http Context:

HttpContext httpContext = HttpContext.Current;
Run Code Online (Sandbox Code Playgroud)

您可以在System.Web命名空间中找到它.

第2步 - 获取标题

授权标头不是HttpContext中唯一的标头.为了访问标头,我们需要从请求中获取它.

string authHeader = this.httpContext.Request.Headers["Authorization"];
Run Code Online (Sandbox Code Playgroud)

如果您调试代码,您将看到该标头的内容与此类似:

基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==

第3步 - 检查标题

您已经提取了标题,因为您需要执行以下操作:

  1. 检查标头是否为空
  2. 检查授权/认证机制是否确实"基本"

像这样:

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.");
}
Run Code Online (Sandbox Code Playgroud)

现在您已经检查过您是否有从中提取数据的内容.

第4步 - 提取凭据

删除"基本"子字符串

您现在可以尝试获取用户名和密码的值.首先,你需要摆脱"基本"子串.你可以这样做:

string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅以下链接:

  1. http://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx
  2. http://msdn.microsoft.com/en-us/library/t97s7bs3(v=vs.110).aspx

解码Base64

现在我们需要从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));
Run Code Online (Sandbox Code Playgroud)

现在用户名和密码将采用以下格式:

username:password
Run Code Online (Sandbox Code Playgroud)

拆分用户名:密码

为了获得用户名和密码,我们可以简单地得到":"的索引

int seperatorIndex = usernamePassword.IndexOf(':');

username = usernamePassword.Substring(0, seperatorIndex);
password = usernamePassword.Substring(seperatorIndex + 1);
Run Code Online (Sandbox Code Playgroud)

现在您可以使用这些数据进行测试.祝好运!

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.");
}
Run Code Online (Sandbox Code Playgroud)

  • ```IndexOf```应该选择字符的第一个匹配项。因此,您的用户名不能包含由RFC 7617明确规定的冒号:```此外,包含冒号字符的用户ID无效,因为用户传递字符串中的第一个冒号将用户ID和密码分开。'' ``。 (6认同)
  • 完美的答案,但请注意,如果用户名或密码包含“:”,则此解决方案将不起作用 (2认同)

pas*_*asx 14

只是添加到主要答案中,摆脱“基本”子字符串的最佳方法是使用AuthenticationHeaderValue Class

var header = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
var credentials = header.Parameter;
Run Code Online (Sandbox Code Playgroud)

如果标头的内容无效,它将抛出 FormatException,例如:“基本”部分不存在。

或者,如果您不想出现异常,请使用AuthenticationHeaderValue.TryParse