繁体   English   中英

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

[英]How can I retrieve Basic Authentication credentials from the header?

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

string authorizationHeader = this.HttpContext.Request.Headers["Authorization"];

我从这里去哪里? 有几个教程,但我是 .NET 和身份验证的新手,您能否在答案中逐步解释您正在做什么以及为什么这样做。

来自我的博客:

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

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

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

授权:基本 QWxhZGRpbjpvcGVuIHNlc2FtZQ==

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

“QWxhZGRpbjpvcGVuIHNlc2FtZQ==”只是以Base64( http://en.wikipedia.org/wiki/Base64 )编码的“用户名:密码”。 为了访问 .NET (C#) 中的标头和其他 HTTP 属性,您需要访问当前的 Http 上下文:

HttpContext httpContext = HttpContext.Current;

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

第 2 步 - 获取标题

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

string authHeader = this.httpContext.Request.Headers["Authorization"];

(或者,您可以按照下面 pasx 的回答中的建议使用AuthenticationHeaderValue.TryParse

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

基本 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.");
}

现在您已检查是否有可从中提取数据的内容。

第 4 步 - 提取凭据

删除“基本”子字符串

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

string encodedUsernamePassword = authHeader.Substring("Basic ".Length).Trim();

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

  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));

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

username:password

拆分用户名:密码

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

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

username = usernamePassword.Substring(0, seperatorIndex);
password = usernamePassword.Substring(seperatorIndex + 1);

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

最终代码

最终代码可能如下所示:

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.");
}

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

var header = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
var credentials = header.Parameter;

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

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

来自@DawidO 的精彩回答。

如果您只是想提取基本的身份验证凭证并依赖 .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
      }
    }
  }

请记住,使用字符串可能不太安全。 它们将保留在内存中,直到它们被 GC 选中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM