ASP.NET Web API基本身份验证授权标头

时间:2012-10-11 12:12:43

标签: authorization asp.net-web-api

我有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: {}

5 个答案:

答案 0 :(得分:9)

如果您对此感到困惑,可以使用以下方式获取标题:

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

但不是通过

var header = request.Headers.Authorization;

答案 1 :(得分:7)

我注意到自己,如果Authorization-header只包含密钥/令牌,request.Headers.Authorization将无法正常启动,因为它正在查找格式为<Scheme> <key/token>的方案,即{ {1}},Authorization: Token VXNlcjpQYXNzd29yZA==不再为空,并包含Authorizationrequest.Headers.Authorization.Scheme = "Token"

答案 2 :(得分:5)

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

我用:

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

以下是完整解决方案的链接:

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

答案 3 :(得分:0)

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

授权为null,因为在创建HttpRequestHeaders类时会解析定义好的HTTP头,如Accept,Authorization等等。因此,如果请求的格式与.NET接受该标头的格式不同,那么该特定属性将为null。

以下是来自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;
}

答案 4 :(得分:0)

尽管此线程非常旧,但是如果我分享我如何解决此问题,它可能会对其他人有所帮助:

请求应包含

授权:基本 VXNlcjpQYXNzd29yZA ==

代替:

授权:VXNlcjpQYXNzd29yZA ==

因此,在请求中进行以下更改可以解决问题:

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