13

我有一个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)
}

更新

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

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: {}
4

5 回答 5

13

如果你遇到这个问题,你可以使用以下方法获取标题:

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

但不是通过

var header = request.Headers.Authorization;
于 2012-10-11T16:02:27.550 回答
9

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

于 2016-04-28T08:31:28.070 回答
5

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

我用:

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

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

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

于 2013-01-22T22:25:16.197 回答
1

虽然,这个线程很老,但如果我分享我是如何解决这个问题的,它可能会对其他人有所帮助:

请求应包含

授权:基本VXNlcjpQYXNzd29yZA==

代替:

授权:VXNlcjpQYXNzd29yZA==

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

client.Headers.Add("Authorization", "Basic VXNlcjpQYXNzd29yZA==");
于 2020-09-08T10:35:13.370 回答
0

为@finstas 的答案添加更多信息。

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

下面是负责解析 Authorization 标头的 AuthenticationHeaderValue 类的反编译代码。类似地,对于不同的 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;
}
于 2016-05-31T06:59:00.037 回答