Używam DynamicPolicyProviderFactory
zgodnie z opisem here. Poniżej jest moja wersja DynamicPolicyProviderFactory:Interfejs API sieci Web z włączonym CORS nie może dodać nagłówka
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);
}
}
Moje wezwanie do zarejestrowania Cors wygrać WebApiConfig.cs
config.EnableCors();
config.SetCorsPolicyProviderFactory(new DynamicPolicyProviderFactory(Settings.Default.AllowedDomains));
a moje ustawienia aplikacji są przekazywane:
<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>
Mimo tych ustawień nagłówek Access-Control-Allow-Origin
nie jest obecny na moim r odpowiedzi, jeśli zgłoszę żądanie od http://mg.domain1.com
do http://localhost
. Korzystam z Web Api 2.2 i Microsoft.AspNet.Cors 5.2.2.
edit: I odkryli, że jeśli mogę użyć atrybutu EnableCors
na kontrolerze, lub włączyć je globalnie (config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
) to działa, więc to musi być coś z moim dynamicznego fabryce. Frustrujące jest to, że DynamicPolicyProvider jest kopiowany/wklejany z innego projektu, którego używam, który działa dobrze.
edit 2: Sukces ... Włączyłem tracing i znalazł błędu
The collection of headers 'accept,content-type' is not allowed
Więc po prostu edytowany metodę GetPolicyForControllerAndOrigin
do nich pozwalają. Teraz wszystko działa, z tym wyjątkiem, że jestem zdezorientowany, ponieważ nie musiałem przeskakiwać przez ten obręcz w moim drugim projekcie (tym, który skopiowałem DynamicPolicyProviderFactory z).
To niesamowite, jak skomplikowane były ustawienia CORS z wieloma różnymi sposobami, w jaki sposób można je skonfigurować, gdzie każdy "prawie działa", a dokumentacja jest straszna, wszędzie i nie wyjaśnia połowy rzeczy, które ". powinien zostać wdrożony, aby działał. – pootzko
@pootzko Zdecydowanie się zgadzam! Również Mike_G, czy mogę po prostu umieścić DynamicPolicyProviderFactory.cs w folderze głównym lub czy musi on przejść do określonego folderu? Co to jest: '', nie mogę go znaleźć nigdzie w pliku Web.config. Czy to jest "appSettings"? – Si8
@ Si8 'DynamicPolicyProviderFactory' jest jak każda inna klasa i może być zorganizowany w dowolnym folderze kodu. dla 'MyApp.Poperties.Settings', to jest w web.config, ale jeśli chcesz UI do edycji tej konkretnej sekcji, kliknij prawym przyciskiem myszy na twoim projekcie w VS> Właściwości> Ustawienia –