Co próbuję zrobić
Mam backend ASP.Net Core Web API hostowany na bezpłatnym abonamencie Azure (kod źródłowy: https://github.com/killerrin/Portfolio-Backend ).
Mam również witrynę kliencką, którą chcę używać w tym interfejsie API. Aplikacja kliencka nie będzie hostowana na platformie Azure, ale raczej będzie hostowana na stronach Github lub w innej usłudze hostingowej, do której mam dostęp. Z tego powodu nazwy domen nie będą się zgadzać.
Patrząc na to, muszę włączyć CORS po stronie Web API, jednak próbowałem już prawie wszystkiego od kilku godzin i to nie działa.
Jak mam skonfigurować klienta To tylko prosty klient napisany w React.js. Dzwonię do interfejsów API przez AJAX w Jquery. Strona React działa, więc wiem, że to nie to. Wywołanie interfejsu API Jquery działa tak, jak zostało to potwierdzone w Próbie 1. Oto jak wykonuję połączenia
var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
//alert(username + "|" + password + "|" + apiUrl);
$.ajax({
url: apiUrl,
type: "POST",
data: {
username: username,
password: password
},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var authenticatedUser = JSON.parse(response);
//alert("Data Loaded: " + authenticatedUser);
if (onComplete != null) {
onComplete(authenticatedUser);
}
},
error: function (xhr, status, error) {
//alert(xhr.responseText);
if (onComplete != null) {
onComplete(xhr.responseText);
}
}
});
Co próbowałem
Próba 1 - „Właściwa” droga
https://docs.microsoft.com/en-us/aspnet/core/security/cors
Wykonałem ten samouczek na stronie Microsoft do T, wypróbowując wszystkie 3 opcje włączania go Globalnie w pliku Startup.cs, konfigurowania go na każdym kontrolerze i wypróbowania go przy każdej akcji.
Zgodnie z tą metodą Cross Domain działa, ale tylko na pojedynczej akcji na jednym kontrolerze (POST do AccountController). W pozostałych przypadkach Microsoft.AspNetCore.Cors
oprogramowanie pośrednie odmawia ustawienia nagłówków.
Zainstalowałem Microsoft.AspNetCore.Cors
przez NUGET, a wersja jest1.1.2
Oto jak mam to skonfigurować w Startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add Cors
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
// Add framework services.
services.AddMvc();
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
});
...
...
...
}
// This method gets called by the runtime. Use this method to configure
//the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
// Enable Cors
app.UseCors("MyPolicy");
//app.UseMvcWithDefaultRoute();
app.UseMvc();
...
...
...
}
Jak widać, robię wszystko zgodnie z zaleceniami. Dwa razy dodawałem Corsę przed MVC, a kiedy to nie działało, próbowałem nałożyć [EnableCors("MyPolicy")]
każdy kontroler jako taki
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
Próba 2 - brutalne zmuszanie
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
Po kilku godzinach próbowania poprzedniej próby, doszedłem do wniosku, że spróbuję go przerobić, próbując ręcznie ustawić nagłówki, zmuszając je do uruchomienia przy każdej odpowiedzi. Zrobiłem to po tym samouczku, w jaki sposób ręcznie dodawać nagłówki do każdej odpowiedzi.
To są nagłówki, które dodałem
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
To są inne nagłówki, które próbowałem i które zawiodły
.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")
Dzięki tej metodzie nagłówki Cross Site są poprawnie stosowane i pojawiają się w mojej konsoli programisty oraz w Postmanie. Problem jednak polega na tym, że gdy przeglądarka przechodzi Access-Control-Allow-Origin
pomyślnie, przeglądarka internetowa sycze pasuje (sądzę), Access-Control-Allow-Headers
stwierdzając415 (Unsupported Media Type)
Więc metoda brutalnej siły też nie działa
Wreszcie
Czy ktoś doszedł do tego i mógł pomóc, czy po prostu wskazać mi właściwy kierunek?
EDYTOWAĆ
Aby uzyskać wywołania API, musiałem przestać używać JQuery i przejść na XMLHttpRequest
format czystego Javascript .
Próba 1
Udało mi się dostać Microsoft.AspNetCore.Cors
do pracy, postępując zgodnie z odpowiedzią MindingData, z wyjątkiem Configure
metody wstawiania app.UseCors
wcześniej app.UseMvc
.
Ponadto po zmieszaniu z JavaScript API Solution options.AllowAnyOrigin()
do obsługi symboli wieloznacznych zaczęło działać.
Próba 2
Udało mi się więc sprawić, że próba 2 (brutalne zmuszanie) do działania ... z jedynym wyjątkiem, że Wildcard dla Access-Control-Allow-Origin
nie działa i jako taki muszę ręcznie ustawić domeny, które mają do niego dostęp.
Oczywiście nie jest idealny, ponieważ chcę, aby ten interfejs WebAPI był szeroko otwarty dla wszystkich, ale przynajmniej działa dla mnie na osobnej stronie, co oznacza, że to początek
app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
.AddDefaultSecurePolicy()
.AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
.AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));
źródło
415 (Unsupported Media Type)
problemu ustawContent-Type
nagłówek żądania naapplication/json
.Odpowiedzi:
Ponieważ masz bardzo prostą zasadę CORS (zezwalaj na wszystkie żądania z domeny XXX), nie musisz komplikować jej. Najpierw spróbuj wykonać następujące czynności (bardzo podstawowa implementacja CORS).
Jeśli jeszcze tego nie zrobiłeś, zainstaluj pakiet nuget CORS.
W metodzie ConfigureServices pliku startup.cs dodaj usługi CORS.
Następnie w metodzie Configure pliku startup.cs dodaj:
Teraz spróbuj. Zasady mają zastosowanie, gdy chcesz mieć różne zasady dla różnych działań (np. Różnych hostów lub różnych nagłówków). Dla prostego przykładu tak naprawdę go nie potrzebujesz. Zacznij od tego prostego przykładu i stamtąd dostosuj, jak trzeba.
Dalsza lektura: http://dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/
źródło
app.UseCors
PO `` app. UseMvc () `. Programy pośrednie są wykonywane w kolejności, w jakiej zostały zarejestrowaneoptions.DisableHttpsRequirement();
, aby którykolwiek z tych elementów działał. Wygląda na to, że ustawienia https cors nie miały zastosowania.W ConfigureServices dodaj
services.AddCors();
usługi PRZED usługą.AddMvc ();Dodaj UseCors w Konfiguruj
Najważniejsze jest to, aby dodać
app.UseCors
wcześniejapp.UseMvc()
.Upewnij się, że zadeklarowałeś funkcjonalność CORS przed MVC, aby oprogramowanie pośredniczące zostało uruchomione, zanim potok MVC przejmie kontrolę i zakończy żądanie.
Po zadziałaniu powyższej metody możesz ją zmienić, skonfiguruj określony POCHODZENIE, aby akceptować wywołania interfejsu API i unikać pozostawiania interfejsu API tak otwartego dla każdego
W metodzie konfiguracji powiadom CORS, aby użył właśnie utworzonej zasady:
Właśnie znalazłem ten kompaktowy artykuł na ten temat - https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi
źródło
Configure()
kolejności, nie jest tu tak naprawdę ważneConfigureServices()
AllowCredentials()
zAllowAnyOrigin()
podobnymi powyżej. Aby użyćAllowCredentials()
, musisz ustawićWithOrigins()
. docs.microsoft.com/en-us/aspnet/core/security/…Stworzyłem własną klasę oprogramowania pośredniego, która działała dla mnie, myślę, że coś jest nie tak z klasą oprogramowania pośredniego .net core
i użyłem go w ten sposób w pliku startup.cs
źródło
if (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) return this._next(context);
W moim przypadku tylko
get
żądanie działa dobrze zgodnie z odpowiedzią MindingData. W przypadku innych rodzajów wniosków musisz napisać:Nie zapomnij dodać
.AllowAnyHeader()
źródło
Aby rozwinąć na user8266077 „s odpowiedzi , znalazłem, że wciąż potrzebne do odpowiedzi opcjami dostaw dla inspekcji wstępnej wniosków w podstawowej .NET 2.1 Podgląd moim przypadku użycia:
a następnie włączył oprogramowanie pośrednie, tak jak w Startup.cs
źródło
app.Use<CorsMiddleware>();
await _next(context)
i ustawiając kod statusu i odpowiedź ręcznie, jeśli tak się stanie. Musiałem także dodać „autoryzację” do kontroli dostępu-Zezwól na nagłówki, aby żądanie inspekcji wstępnej działało podczas wysyłania żądań reakcji wymagających autoryzacji.źródło
Walczyłem z tym przez DAYS.
I w końcu go do pracy, przenosząc
app.UseCors(CORS_POLICY);
się do TOP dniaConfigure()
.Również:
Microsoft.AspNetCore.Cors
był wymagany pakiet NuGet w .Net Core 2 i niższych; jest teraz automatycznie częścią Microsoft.AspNetCore w .Net Core 3 i wyższych.builder.AllowAnyOrigin()
i.AllowCredentials()
opcje CORS są teraz wzajemnie wykluczające się w .Net Core 3 i wyższychhttps
. Adres URL http wydawał się dawać błąd CORS niezależnie od konfiguracji CORS serwera .Net Core. Na przykładhttp://localhost:52774/api/Contacts
dałby błąd CORS; po prostu zmieniając adres URL nahttps://localhost:44333/api/Contacts
działający.Uwaga dodatkowa :
źródło
Żadna z powyższych procedur nie pomogła, a następnie przeczytałem artykuł, który rozwiązał problem.
Poniżej znajduje się kod.
i
i na szczycie mojej metody działania
źródło
app.UseCors()
)[EnableCors()]
w tej samej aplikacji. Powinieneś użyć jednego lub drugiego - ale nie obu: docs.microsoft.com/en-us/aspnet/core/security/… :Use the [EnableCors] attribute or middleware, not both in the same app.
spróbuj dodać
jQuery.support.cors = true;
przed wywołaniem AjaxMoże się również zdarzyć, że dane wysyłane do interfejsu API będą nieporadne,
spróbuj dodać następującą funkcję JSON
następnie w twoich danych: obiekt zmień na
źródło
Najprostszym rozwiązaniem jest dodanie
do Startup.cs.
źródło
Myślę, że jeśli używasz własnego oprogramowania pośredniego CORS , musisz upewnić się, że to naprawdę żądanie CORS , sprawdzając nagłówek źródła .
źródło
Access-Control-Allow-Origin
nagłówek nie został wydany przez serwer. Właściwie wysłałem żądania za pośrednictwem listonosza bezOrigin
nagłówka. To uratowało mi dzień! (A przynajmniej moje przedpołudnie;))W oparciu o Twój komentarz w odpowiedzi MindingData, nie ma to nic wspólnego z twoimi CORS, działa dobrze.
Działanie kontrolera zwraca nieprawidłowe dane. HttpCode 415 oznacza „Nieobsługiwany typ nośnika”. Dzieje się tak, gdy albo przekażesz niewłaściwy format do kontrolera (tj. XML do kontrolera, który akceptuje tylko json) lub gdy zwrócisz niewłaściwy typ (zwróć Xml w kontrolerze, który zadeklarował, że zwraca tylko xml).
Na później sprawdź jedno z
[Produces("...")]
atrybutów twojej akcjiźródło
Dla mnie nie miało to nic wspólnego z kodem, którego używałem. W przypadku platformy Azure musieliśmy przejść do ustawień usługi aplikacji, w menu bocznym wpis „CORS”. Tam musiałem dodać domenę, o którą prosiłem. Kiedy już to miałem, wszystko było magiczne.
źródło
W launchSettings.json, w iisSettings, ustaw anonymousAuthentication na true:
Następnie w Startup.cs, w ConfigureServices, przed services.AddMvc, dodaj:
a następnie w metodzie configure przed app. UseMvc () dodaj:
źródło
Używam .Net CORE 3.1 i spędziłem wieki waląc głową w ścianę, gdy zdałem sobie sprawę, że mój kod zaczął działać, ale moje środowisko debugowania zostało zepsute, więc oto 2 wskazówki, jeśli próbujesz rozwiązać problem problem:
Jeśli próbujesz rejestrować nagłówki odpowiedzi przy użyciu oprogramowania pośredniego ASP.NET, nagłówek „Kontrola dostępu - Allow-Origin” nigdy się nie pojawi, nawet jeśli tam jest. Nie wiem jak, ale wydaje się, że jest dodawany poza rurociągiem (w końcu musiałem go użyć wireshark).
.NET CORE nie wyśle w odpowiedzi „Access-Control-Allow-Origin”, chyba że w żądaniu masz nagłówek „Origin”. Listonosz nie ustawi tego automatycznie, więc musisz go dodać samodzielnie.
źródło
W moim przypadku naprawiłem za pomocą UseCors przed UserRouting ..
źródło
.NET Core 3.1
Pracował dla mnie i jak mówią doktorzy, aby to zrobić:
w klasie startowej:
W metodzie ConfigureServices ():
W metodzie Configure ():
https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1
źródło
Dostałem odpowiedź MindingData powyżej do pracy, ale musiałem użyć Microsoft.AspNet.Cors zamiast Microsoft.AspNetCore.Cors. Korzystam z projektu interfejsu API aplikacji sieci .NetCore w programie Visual Studio 2019
źródło
The
pozwoli ci robić CORS z wbudowanymi funkcjami, ale nie obsługuje żądania OPCJE. Najlepszym jak dotąd obejściem jest utworzenie nowego oprogramowania pośredniego, jak sugerowano w poprzednim poście. Sprawdź odpowiedź oznaczoną jako poprawną w następującym poście:
Włącz nagłówek OPCJE dla CORS w .NET Core Web API
źródło
Prosty i łatwy sposób to zrobić.
Install-Package Microsoft.AspNetCore.Cors
app.UseCors(options => options.AllowAnyOrigin());
źródło
Oto mój kod:)
źródło
Oto jak to zrobiłem.
Widzę, że w niektórych odpowiedziach ustalają
app.UserCors("xxxPloicy")
i wprowadzają[EnableCors("xxxPloicy")]
kontrolery. Nie musisz robić obu.Oto kroki.
W Startup.cs wewnątrz ConfigureServices dodaj następujący kod.
Jeśli chcesz zastosować cały projekt, dodaj następujący kod w Konfiguruj metodę w Startup.cs
Lub
Jeśli chcesz dodać go do określonych kontrolerów, dodaj kod włączania cors, jak pokazano poniżej.
Aby uzyskać więcej informacji: zobacz to
źródło
Użyj niestandardowego atrybutu akcji / kontrolera, aby ustawić nagłówki CORS.
Przykład:
Następnie kontroler / działanie interfejsu API sieci Web:
źródło
Aby dodać tutaj odpowiedź, jeśli używasz
app.UseHttpsRedirection()
i nie używasz portu SSL, rozważ skomentowanie tego.źródło
Używałem blazor webassemble jako klienta i rdzenia interfejsu API asp.net jako backendu i miałem też problem z corsami.
Znalazłem rozwiązanie z tym kodem:
Mój podstawowy interfejs WWW ASP.Net Startup.cs Pierwsze wiersze ConfigureServices i Configure Method wyglądają tak:
i moja metoda Konfiguruj:
zmień
http://example.com
w domenie klienta lub adresie IPźródło
źródło