官术网_书友最值得收藏!

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; }
        }
    }
主站蜘蛛池模板: 名山县| 黄平县| 大英县| 包头市| 梁山县| 霍邱县| 南皮县| 朔州市| 大兴区| 和静县| 丹寨县| 青浦区| 楚雄市| 诏安县| 景东| 应城市| 多伦县| 长宁县| 东辽县| 普安县| 江山市| 荥经县| 策勒县| 梅河口市| 三台县| 金坛市| 宜君县| 镇康县| 文安县| 扶余县| 饶平县| 丹凤县| 台中市| 峡江县| 岳阳县| 内黄县| 广州市| 禄劝| 巨鹿县| 神池县| 余姚市|