我正在阅读 Badri L. 撰写的Pro ASP .NET Web API 安全性中的第 8 章,尝试为将由 HTTP/JS 客户端使用的 Web 应用程序实现基本身份验证。
我已将以下身份验证处理程序添加到我的 WebAPI 项目中:
public class AuthenticationHandler : DelegatingHandler
{
private const string SCHEME = "Basic";
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
System.Threading.CancellationToken
cancellationToken)
{
try
{
// Request Processing
var headers = request.Headers;
if (headers.Authorization != null && SCHEME.Equals(headers.Authorization.Scheme))
{
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
// etc
当我使用 [Authorize] 在我的 API 中装饰方法并在if
上面的语句中设置断点时,headers.Authorization
在第一次请求时为 null。如果我继续这个休息时间,if 语句会再次被击中,这次headers.Authorization.Scheme
是“协商”,而不是“基本”:
我已经在 WebApiConfig 中注册了我的处理程序:
config.MessageHandlers.Add(new AuthenticationHandler());
但是我不知道为什么 Authorize 属性不尊重基本身份验证,或者为什么 - 因为该方案不是“基本”并且if()
我的处理程序返回false
- 我应该从我的 API 控制器获取数据得到401 Unauthorized
.
我没有在我的 web.config 中指定任何 authenticationType。
知道我做错了什么吗?
编辑:完整处理程序:
public class AuthenticationHandler : DelegatingHandler
{
private const string SCHEME = "Basic";
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
System.Threading.CancellationToken
cancellationToken)
{
try
{
// Request Processing
var headers = request.Headers;
if (headers.Authorization != null && SCHEME.Equals(headers.Authorization.Scheme))
{
Encoding encoding = Encoding.GetEncoding("iso-8859-1");
string credentials = encoding.GetString(Convert.FromBase64String(headers.Authorization.Parameter));
string[] parts = credentials.Split(':');
string userId = parts[0].Trim();
string password = parts[1].Trim();
// TODO: Authentication of userId and Pasword against credentials store here
if (true)
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, userId),
new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password)
};
var principal = new ClaimsPrincipal(new[] {new ClaimsIdentity(claims, SCHEME)});
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
HttpContext.Current.User = principal;
}
}
var response = await base.SendAsync(request, cancellationToken);
// Response processing
if (response.StatusCode == HttpStatusCode.Unauthorized)
{
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue(SCHEME));
}
return response;
}
catch (Exception)
{
// Error processing
var response = request.CreateResponse(HttpStatusCode.Unauthorized);
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue(SCHEME));
return response;
}
}
}