【问题标题】:ASP.NET Web API Basic Authentication Authorisation HeaderASP.NET Web API 基本身份验证授权标头
【发布时间】:2012-10-02 02:23:49
【问题描述】:

我有一个BasicAuthenticationAttribute 检查请求中的 Authorization 标头,但尽管它存在,它仍然认为 Authorization 标头为空:

public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (actionContext.Request.Headers.Authorization == null)
        {
            actionContext.Response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
        }

        ...

如果我检查 actionContext.Request.Headers 我可以看到 Authorization 列出:

{Connection: Keep-Alive
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-gb
Authorization: REDACTED_BUT_PRESENT==
Host: localhost:44300
Referer: https://localhost:44300/
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; .NET4.0E)
}

更新

我刚刚检查了完整的请求标头,它们看起来像这样...我可以在第一部分中看到 Authorization 标头,但第二部分中的 Authorization 标头显然为空。

request.Headers

{Connection: Keep-Alive
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-gb
Authorization: REDACTED_BUT_PRESENT==
Host: localhost:1734
Referer: http://localhost:1734/
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; .NET4.0E)
}
    base {System.Net.Http.Headers.HttpHeaders}: {Connection: Keep-Alive
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: en-gb
Authorization: VXNlcjpQYXNzd29yZA==
Host: localhost:1734
Referer: http://localhost:1734/
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; InfoPath.3; .NET4.0E)
}
    Accept: {*/*}
    AcceptCharset: {}
    AcceptEncoding: {gzip, deflate}
    AcceptLanguage: {en-gb}
    Authorization: null
    CacheControl: null
    ... removed for brevity ...
    Warning: {}

【问题讨论】:

  • 您是否在尝试基本身份验证。
  • @satish - 是的 - 所以我正在设置授权标头并使用我的操作过滤器对其进行检查。
  • 我制作了一个消息处理程序,它似乎工作正常。我也会尝试使用动作过滤器。你能检查一下这是否有帮助gist.github.com/3872727 -Handler ,gist.github.com/3872715 - 单元测试
  • 这对我来说基本上是一样的——我可以看到授权标头与发布的一样,但在消息处理程序中它认为request.Headers.Authorization 为空。让我检查单元测试生成的标头,看看它是否看起来不同。

标签: authorization asp.net-web-api


【解决方案1】:

如果您遇到此问题,可以使用以下方法获取标题:

var header = request.Headers.FirstOrDefault(h => h.Key.Equals("Authorization"));

但不是通过

var header = request.Headers.Authorization;

【讨论】:

  • 这是为什么呢?这看起来很奇怪。
  • 我相信是因为它是像字典一样的Key/Value结构。
  • 说真的,这是为什么呢?我正在使用的库检查 Authorization 属性,而不是 headers 集合...
  • @Fenton,在 Web API2 控制器中,我们可以使用 Request.Headers.Authorization.Parameter 将给出实际的令牌。
  • 为什么不 request.Headers["Authorization"] ?!
【解决方案2】:

我自己注意到,如果 Authorization-header 仅包含密钥/令牌,request.Headers.Authorization 将无法正确启动,因为它也在寻找格式为<Scheme> <key/token> 的方案,即Authorization: Token VXNlcjpQYXNzd29yZA==,然后Authorization 将不再为 null 并包含 request.Headers.Authorization.Scheme = "Token"request.Headers.Authorization.Parameter = "VXNlcjpQYXNzd29yZA=="

【讨论】:

    【解决方案3】:

    我已经发布了我自己的基本身份验证属性示例。也许这会给你一些提示。

    我使用:

    HttpContext.Current.Request.Headers["Authorization"];
    

    这里是完整解决方案的链接:

    http://remy.supertext.ch/2012/04/basic-http-authorization-for-web-api-in-mvc-4-beta/

    【讨论】:

    【解决方案4】:

    虽然,这个帖子已经很老了,但如果我分享一下我是如何解决这个问题的,它可能会对其他人有所帮助:

    请求应包含

    授权:基本 VXNlcjpQYXNzd29yZA==

    代替:

    授权:VXNlcjpQYXNzd29yZA==

    所以以下请求的更改可能会解决问题:

    client.Headers.Add("Authorization", "Basic VXNlcjpQYXNzd29yZA==");
    

    【讨论】:

      【解决方案5】:

      在@finstas 的回答中添加更多信息。

      Authorization 为空,因为在创建 HttpRequestHeaders 类时会解析明确定义的 HTTP 标头,例如 Accept、Authorization 等。因此,如果请求的格式与 .NET 对该标头接受的格式不同,则该特定属性将为空。

      下面是 AuthenticationHeaderValue 类的反编译代码,负责解析 Authorization 标头。同样,对于不同的 HTTP 标头,还有其他类也可以做到这一点。

      希望这能提供更多信息,说明为什么 Token 和值之间需要有一个空格。

      internal static int GetAuthenticationLength(string input, int startIndex, out object parsedValue)
      {
        parsedValue = (object) null;
        if (string.IsNullOrEmpty(input) || startIndex >= input.Length)
          return 0;
        int tokenLength = HttpRuleParser.GetTokenLength(input, startIndex);
        if (tokenLength == 0)
          return 0;
        AuthenticationHeaderValue authenticationHeaderValue = new AuthenticationHeaderValue();
        authenticationHeaderValue.scheme = input.Substring(startIndex, tokenLength);
        int startIndex1 = startIndex + tokenLength;
        int whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, startIndex1);
        int index = startIndex1 + whitespaceLength;
        if (index == input.Length || (int) input[index] == 44)
        {
          parsedValue = (object) authenticationHeaderValue;
          return index - startIndex;
        }
        if (whitespaceLength == 0)
          return 0;
        int startIndex2 = index;
        int parameterEndIndex = index;
        if (!AuthenticationHeaderValue.TrySkipFirstBlob(input, ref index, ref parameterEndIndex) || index < input.Length && !AuthenticationHeaderValue.TryGetParametersEndIndex(input, ref index, ref parameterEndIndex))
          return 0;
        authenticationHeaderValue.parameter = input.Substring(startIndex2, parameterEndIndex - startIndex2 + 1);
        parsedValue = (object) authenticationHeaderValue;
        return index - startIndex;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-09-10
        • 1970-01-01
        • 2015-05-05
        • 1970-01-01
        • 2012-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多