.net CORS -当响应是401 -未授权时丢失允许起源头

本文关键字:许起 源头 授权 CORS 响应 net | 更新日期: 2023-09-27 18:09:37

我正试图确定为什么/如何在响应为401-Unauthorized时失去'Access-Control-Allow-Origin'标头。

我使用基于令牌的身份验证,其中令牌具有有效期。当此令牌过期时,服务器返回401未经授权,因为它应该,但在chrome(和IE和FF)中,它永远不会看到允许起源标头和错误与通常的CORS错误:XMLHttpRequest cannot load http://my.rest.service. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

我不确定这些是否相关,因为验证逻辑工作得很好,只是当响应为401时CORS阻塞。

c# CORS处理程序

namespace NViewREST.Handlers
{
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Threading;
    using System.Threading.Tasks;
    /// <summary>
    /// Handler for processing Cross Origin Resource Sharing (CORS) requests
    /// </summary>
    public class CorsHandler : DelegatingHandler
    {
        /// <summary>The origin.</summary>
        private const string Origin = "Origin";
    
        /// <summary>Header indicating we should treat this is CORS request.</summary>
        private const string EnableCors = "X-EnableCors";
        /// <summary>The access control request method.</summary>
        private const string AccessControlRequestMethod = "Access-Control-Request-Method";
        /// <summary>The access control request headers.</summary>
        private const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        /// <summary>The access control allow origin.</summary>
        private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        /// <summary>The access control allow methods.</summary>
        private const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        /// <summary>The access control allow headers.</summary>
        private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";
        /// <summary>
        /// send async request
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>The <see cref="Task"/>.</returns>
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // if it has our NFIB enable CORS header or has the access control request method header, we're assuming CORS request
            var isCorsRequest = request.Headers.Contains(AccessControlRequestMethod) || request.Headers.Contains(EnableCors);
            // preflight == OPTIONS request - usually only sent prior to CORS requests
            var isPreflightRequest = request.Method == HttpMethod.Options;
            // express exit if its a normal request
            if (!isCorsRequest)
            {
                return base.SendAsync(request, cancellationToken);
            }
            // actual CORS request - add appropriate header before executing as  normal
            if (!isPreflightRequest)
            {
                 return base.SendAsync(request, cancellationToken).ContinueWith(
                    t =>
                        {
                            var resp = t.Result;
                            resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                            return resp;
                        },
                    cancellationToken);
            }
            // at this point its the preflight request - add headers to indicate allowed origins
            var response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
            // add header to indicate allowed methods
            var accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
            if (accessControlRequestMethod != null)
            {
                response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
            }
            // add headers to indicate allowed headers
            var requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
            if (!string.IsNullOrEmpty(requestedHeaders))
            {
                response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
            }
            // send result of OPTIONS request
            var tcs = new TaskCompletionSource<HttpResponseMessage>();
            tcs.SetResult(response);
            return tcs.Task;
        }
    }
}

我可以步进添加标题的行,即使响应是401,所以我知道在。net端正在添加它。

JavaScript Ajax调用

function executeAjax (method, url, data, token) {
    url = (url.indexOf('/') === 0) ? url : "/" + url;
    var options = {
        method: method,
        url: app.settings.apiUrlRoot + url,
        data: data
    };
    token = token || localStorage.getItem("sessionKey");
    options.headers = {
        "Accept": "application/json",
        //header for enabling CORS
        "X-EnableCors": 'true'
    }
    if (token !== undefined && token !== null)
    {
        options.headers["X-ADAuth"] = token,
    }
    return $.ajax(options);
};

调用的结果是前面提到的CORS错误。

据我所知,防火墙或中间件没有问题,因为任何其他非401 ajax请求执行得很好。

有什么想法为什么头消失?

.net CORS -当响应是401 -未授权时丢失允许起源头

我遇到了完全相同的问题,并通过在401响应返回之前显式地将CORS标头添加到响应中来解决了这个问题。

var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "errorMessage"));
response.Headers.Add(AccessControlAllowOrigin, "*");
return response;