Konfiguracja Cross-Origin Resource Sharing (CORS) w aplikacjach ASP.NET Core jest kluczowym aspektem zarówno bezpieczeństwa, jak i funkcjonalności nowoczesnych aplikacji webowych. Najczęstsze wyzwania to błędna kolejność middleware w pipeline, konflikt pomiędzy AllowAnyOrigin() i AllowCredentials(), nieprawidłowa obsługa żądań preflight oraz niewłaściwa konfiguracja nagłówków CORS. Rekomendowane praktyki obejmują stosowanie nazwanych polityk CORS, poprawne rozmieszczenie middleware UseCors(), wskazywanie konkretnych origin w środowiskach produkcyjnych oraz wdrażanie skutecznych narzędzi debugujących. Należy także pamiętać o obsłudze żądań OPTIONS, konfiguracji subdomen za pomocą SetIsOriginAllowedToAllowWildcardSubdomains() oraz precyzyjnym zarządzaniu atrybutami EnableCors i DisableCors w przypadku różnych kontrolerów i akcji.
Podstawy CORS w ASP.NET Core
Cross-Origin Resource Sharing to mechanizm chroniący przed nieautoryzowanym wykonywaniem żądań HTTP między różnymi domenami, portami i protokołami. W aplikacjach ASP.NET Core CORS umożliwia komunikację pomiędzy frontendem a backendowym API hostowanym na innych adresach.
Działanie mechanizmu polega na dołączaniu przez serwer określonych nagłówków HTTP, które informują przeglądarkę, jakie domeny mogą uzyskać dostęp do zasobów. Przeglądarka w razie potrzeby wysyła zapytanie preflight (OPTIONS), by upewnić się, że serwer akceptuje daną operację.
Aby poprawnie skonfigurować CORS w ASP.NET Core, należy:
- zarejestrować usługę CORS w kontenerze dependency injection (wywołanie
AddCors()w ConfigureServices), - zdefiniować szczegółowe polityki CORS dostosowane do wymagań aplikacji,
- umieścić odpowiednio middleware
UseCors()w pipeline przetwarzania żądań.
Middleware UseCors() należy wywołać po UseRouting(), ale przed UseAuthorization(), aby zapewnić poprawną obsługę nagłówków CORS.
Najczęstsze błędy konfiguracyjne
Poniżej przedstawiono najczęstsze źródła problemów z CORS w ASP.NET Core:
- Nieprawidłowa kolejność middleware – gdy UseCors() zostanie umieszczone za middleware autoryzacji, nagłówki CORS nie są generowane, co prowadzi do błędów przeglądarki;
- Konflikt AllowAnyOrigin() z AllowCredentials() – protokół CORS nie pozwala łączyć wildcard origin (*) z credentials, co skutkuje wyjątkiem runtime;
- Nieprawidłowa obsługa żądań preflight (OPTIONS) – niewłaściwe skonfigurowanie kontrolerów lub routingu skutkuje błędami 405 lub brakiem wymaganych nagłówków;
- Błędy w konfiguracji nagłówków CORS – brak odpowiednich nagłówków Access-Control-Allow-Origin, -Methods lub -Headers blokuje żądania rozumiane jako udane przez serwer, ale odrzucone przez przeglądarkę;
- Brak konfiguracji właściwych origin – szczególnie w środowiskach developerskich zapomina się o dodaniu localhost z poprawnym portem, co prowadzi do problemów przy testach;
- Niewłaściwe użycie atrybutów EnableCors i DisableCors – skutkuje to konfliktami oraz niespodziewanymi efektami, szczególnie w kombinacji z RequireCors w routingach;
- Zła obsługa subdomen/wildcardów – błędy przy stosowaniu WithOrigins() z wildcard można naprawić wyłącznie za pomocą SetIsOriginAllowedToAllowWildcardSubdomains().
Dobre praktyki konfiguracji
W celu poprawnego i bezpiecznego skonfigurowania mechanizmu CORS dla aplikacji ASP.NET Core, zaleca się następujące działania:
- Wykorzystanie nazwanych polityk – pozwala zarządzać dostępem w sposób granularny oraz wielokrotnie wykorzystywać polityki w aplikacji;
- Prawidłowa kolejność middleware – umieszczenie UseCors() po UseRouting(), ale przed UseAuthorization(), gwarantuje prawidłowe dodawanie nagłówków przed autoryzacją;
- Określ konkretny origin w produkcji – AllowAnyOrigin() stosuj wyłącznie lokalnie; w środowisku produkcyjnym zawsze wymieniaj dozwolone domeny;
- Logging i debugowanie – aktywuj logi na poziomie Debug oraz monitoruj origin żądania, politykę CORS i nagłówki w odpowiedzi;
- Obsługa żądań preflight – upewnij się, że backend automatycznie obsługuje zapytania OPTIONS, w razie konieczności ręcznie konfigurując odpowiedzi w kontrolerach;
- Użycie SetIsOriginAllowed() w zaawansowanych scenariuszach – umożliwia dynamiczną weryfikację pochodzenia żądania;
- Rozdzielanie konfiguracji środowiskowej – korzystaj z appsettings.json do oddzielnej konfiguracji dla Development, Staging i Production;
- Testowanie konfiguracji CORS – wykonuj testy z różnych origin, przy różnych metodach HTTP oraz z/bez credentials, używaj rzeczywistych przeglądarek, nie tylko narzędzi developerskich typu Postman.