我正在使用DynamicPolicyProviderFactory
,如此处所述:这里。以下是我的版本:
public class DynamicPolicyProviderFactory : ICorsPolicyProviderFactory
{
private readonly HashSet<Regex> _allowed;
public DynamicPolicyProviderFactory(IEnumerable allowedOrigins)
{
_allowed = new HashSet<Regex>();
foreach (string pattern in allowedOrigins.Cast<string>()
.Select(Regex.Escape)
.Select(pattern => pattern.Replace("*", "w*")))
{
_allowed.Add(new Regex(pattern, RegexOptions.IgnoreCase));
}
if (_allowed.Count >= 1)
return;
//if nothing is specified, we assume everything is.
_allowed.Add(new Regex(@"https://\w*", RegexOptions.IgnoreCase));
_allowed.Add(new Regex(@"http://\w*", RegexOptions.IgnoreCase));
}
public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
{
var route = request.GetRouteData();
var controller = (string)route.Values["controller"];
var corsRequestContext = request.GetCorsRequestContext();
var originRequested = corsRequestContext.Origin;
var policy = GetPolicyForControllerAndOrigin(controller, originRequested);
return new CustomPolicyProvider(policy);
}
private CorsPolicy GetPolicyForControllerAndOrigin(string controller, string originRequested)
{
// Do lookup to determine if the controller is allowed for
// the origin and create CorsPolicy if it is (otherwise return null)
if (_allowed.All(a => !a.Match(originRequested).Success))
return null;
var policy = new CorsPolicy();
policy.Origins.Add(originRequested);
policy.Methods.Add("GET");
policy.Methods.Add("POST");
policy.Methods.Add("PUT");
policy.Methods.Add("DELETE");
return policy;
}
}
public class CustomPolicyProvider : ICorsPolicyProvider
{
private readonly CorsPolicy _policy;
public CustomPolicyProvider(CorsPolicy policy)
{
this._policy = policy;
}
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
return Task.FromResult(this._policy);
}
}
我需要在WebApiConfig.cs中注册cors。
config.EnableCors();
config.SetCorsPolicyProviderFactory(new DynamicPolicyProviderFactory(Settings.Default.AllowedDomains));
我的应用程序设置被传递:
<MyApp.Properties.Settings>
<setting name="AllowedDomains" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>http://localhost</string>
<string>http*://*.domain1.com</string>
<string>http*://*.domain2.com</string>
</ArrayOfString>
</value>
</setting>
</MyApp.Properties.Settings>
尽管进行了这些设置,但如果我从
http://mg.domain1.com
向http://localhost
发出请求,则我的响应中缺少Access-Control-Allow-Origin
标头。我正在使用Web Api 2.2和Microsoft.AspNet.Cors 5.2.2。编辑:我发现如果在控制器上使用
EnableCors
属性或全局启用它(config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
),它可以正常工作,因此必须是我的动态工厂的问题。令人沮丧的是,DynamicPolicyProvider是从另一个我正在使用的项目中复制/粘贴的,而那个项目却可以正常工作。编辑2:成功了!...我启用了跟踪并找到了错误。
The collection of headers 'accept,content-type' is not allowed
所以我刚刚编辑了GetPolicyForControllerAndOrigin
方法来允许它们。现在一切都正常了,但我很困惑,因为在我的另一个项目中(我从中复制了DynamicPolicyProviderFactory),我不需要这样做。
DynamicPolicyProviderFactory
就像其他类一样,可以组织在任何代码文件夹下。对于MyApp.Properties.Settings
,它在 web.config 中,但如果您想要一个用于编辑该特定部分的 UI,则可以在 VS 中右键单击项目 > 属性 > 设置。 - Mike_G[EnableCors()]
添加到操作或控件中。如果您手动编辑web.config中的应用程序设置,它会在UI编辑器中出现问题。我通常使用UI编辑器创建web.config中的部分(因此不必编写所有设置的xml),然后手动进行编辑。 - Mike_G<string>http*://mysite.com</string>
(将命中http和https)或类似<string>http*://*.mysite.com</string>
以包括子域。 - Mike_G