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

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; }
        }
    }
主站蜘蛛池模板: 卢湾区| 广东省| 高青县| 高唐县| 腾冲县| 梅河口市| 新竹市| 炉霍县| 九龙县| 大姚县| 潜山县| 乡宁县| 台安县| 天峻县| 苏尼特右旗| 岳阳县| 海兴县| 平潭县| 洞口县| 宝鸡市| 塔河县| 安丘市| 弋阳县| 衡水市| 阜康市| 武城县| 鲁山县| 宝坻区| 崇仁县| 辰溪县| 靖远县| 图们市| 蓝山县| 玉溪市| 吉木乃县| 宁安市| 即墨市| 临海市| 曲靖市| 青川县| 江华|