
上QQ阅读APP看书,第一时间看更新
Implementing authentication in HTTP message handlers
For a self-hosted web API, the best practice is to implement authentication in an HTTP Message Handler. The principal will be set by the message handler after verifying the HTTP request. For a web API that is self-hosted, consider implementing authentication in a message handler. Otherwise, use an HTTP module instead.
The following code snippet shows an example of basic authentication implemented in an HTTP module:
public class AuthenticationHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var credentials = ParseAuthorizationHeader(request); if (credentials != null) { // Check if the username and passowrd in credentials are valid against the ASP.NET membership. // If valid, the set the current principal in the request context var identity = new GenericIdentity(credentials.Username); Thread.CurrentPrincipal = new GenericPrincipal(identity, null);; } return base.SendAsync(request, cancellationToken) .ContinueWith(task => { var response = task.Result; if (credentials == null && response.StatusCode == HttpStatusCode.Unauthorized) Challenge(request, response); return response; }); } protected virtual Credentials ParseAuthorizationHeader(HttpRequestMessage request) { string authorizationHeader = null; var authorization = request.Headers.Authorization; if (authorization != null && authorization.Scheme == "Basic") authorizationHeader = authorization.Parameter; if (string.IsNullOrEmpty(authorizationHeader)) return null; authorizationHeader = Encoding.Default.GetString(Convert.FromBase64String(authorizationHeader)); var authenticationTokens = authorizationHeader.Split(':'); if (authenticationTokens.Length < 2) return null; return new Credentials() { Username = authenticationTokens[0], Password = authenticationTokens[1], }; } void Challenge(HttpRequestMessage request, HttpResponseMessage response) { response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", request.RequestUri.DnsSafeHost)); } public class Credentials { public string Username { get; set; } public string Password { get; set; } } }