我如何允许多个域在一个.net Web API与OAuth令牌认证使用CORS?



我们有一个。net Framework Web API,使用基于Token的OAuth认证,并且正在尝试通过Exchange HTML Add-In对它进行调用。我希望允许访问几个域,因为我们可能使用几个不同的应用程序来访问它,但我们不希望允许一般(*)访问,因为它是一个专有的web API,所以没有必要访问它超出已知域。

为了满足飞行前的要求,我尝试了以下方法:

  • 通过返回一个包含多个值的报头。包含多个域
  • 时出现CORS错误
  • 通过PreflightRequestsHandler添加带有多个域的Access-Control-Allow-Origin头:Delegating Handler -相同的结果

如果我将这些设置为一个域,并使用配置。使用带有域的EnableCorsAttribute的EnableCors,它会将这些添加到标头并给出冗余域的错误。

我如何设置我的Web API与多个域的OAuth和CORS设置?

你可以添加标题"Access-Control-Allow-Origin"在回应中Global.asax中授权站点的列表文件

using System.Linq;

private readonly string[] authorizedSites = new string[]
{
"https://site1.com",
"https://site2.com"
};
private void SetAccessControlAllowOrigin() 
{
string origin = HttpContext.Current.Request.Headers.Get("Origin");
if (authorizedSites.Contains(origin)) 
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
}
protected void Application_BeginRequest() 
{
SetAccessControlAllowOrigin();
}

在https://www.ozkary.com/2016/04/web-api-owin-cors-handling-no-access.html找到Oscar Garcia (@ozkary)的以下内容,并实现了它,它工作得很好!添加到微软在项目创建时设置的AppOAuthProvider:

/// <summary>
/// match endpoint is called before Validate Client Authentication. we need
/// to allow the clients based on domain to enable requests
/// the header
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override Task MatchEndpoint(OAuthMatchEndpointContext context)
{
SetCORSPolicy(context.OwinContext);
if (context.Request.Method == "OPTIONS")   
{               
context.RequestCompleted();
return Task.FromResult(0);
}
return base.MatchEndpoint(context);
}


/// <summary>
/// add the allow-origin header only if the origin domain is found on the     
/// allowedOrigin list
/// </summary>
/// <param name="context"></param>
private void SetCORSPolicy(IOwinContext context)
{
string allowedUrls = ConfigurationManager.AppSettings["allowedOrigins"];
if (!String.IsNullOrWhiteSpace(allowedUrls))
{
var list = allowedUrls.Split(',');
if (list.Length > 0)
{
string origin = context.Request.Headers.Get("Origin");
var found = list.Where(item => item == origin).Any();
if (found){
context.Response.Headers.Add("Access-Control-Allow-Origin",
new string[] { origin });
}                   
}

}
context.Response.Headers.Add("Access-Control-Allow-Headers", 
new string[] {"Authorization", "Content-Type" });
context.Response.Headers.Add("Access-Control-Allow-Methods", 
new string[] {"OPTIONS", "POST" });
}            

最新更新