私は、Badri L. によるPro ASP .NET Web API Securityの第 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
API のメソッドを [Authorize] で装飾し、if
上記のステートメントにブレークポイントを設定するとheaders.Authorization
、最初のリクエストで null になります。この休憩を続けると、if ステートメントが再びヒットします。今回はheaders.Authorization.Scheme
、"Basic" ではなく "Negotiate" を使用します。
Handler を 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;
}
}
}