.net CORS - 响应为 401 时丢失 Allow Origin 标头 - 未授权
Posted
技术标签:
【中文标题】.net CORS - 响应为 401 时丢失 Allow Origin 标头 - 未授权【英文标题】:.net CORS - Losing Allow Origin header when the response is 401 - not authorized 【发布时间】:2014-08-11 08:43:17 【问题描述】:当响应为 401-Unauthorized 时,我正在尝试确定为什么/如何丢失“Access-Control-Allow-Origin”标头。
我正在使用基于令牌的身份验证,其中令牌具有到期日期。当这个令牌过期时,服务器会返回一个 401-unauthorized,因为它应该,但在 chrome(以及 IE 和 FF)中,它永远不会看到 Allow Origin 标头和通常的 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 请求都可以正常执行。
对为什么标题消失有任何想法吗?
【问题讨论】:
【参考方案1】:我遇到了完全相同的问题,并通过在返回之前将 CORS 标头显式添加到 401 响应来解决它。
var response = new HttpResponseMessage(HttpStatusCode.Unauthorized);
response.Headers.WwwAuthenticate.Add(new AuthenticationHeaderValue("Bearer", "errorMessage"));
response.Headers.Add(AccessControlAllowOrigin, "*");
return response;
【讨论】:
AccessControlAllowOrigin 在哪个命名空间?以上是关于.net CORS - 响应为 401 时丢失 Allow Origin 标头 - 未授权的主要内容,如果未能解决你的问题,请参考以下文章
.net 核心允许在使用 CORS 时发回错误 401(而不是零)
401 响应 CORS preflight OPTIONS 请求到 Spring Boot 服务器
ASP.NET Core 5 JWT 身份验证失败,响应代码为 401