jak skonfigurować swój ASP.NET aplikacje internetowe i interfejsy API aby wymagać protokołu HTTPS
w przypadku każdej aplikacji hostowanej w Internecie, konieczne jest, aby zabezpieczenia były wbudowane od samego początku.
włączenie aplikacji internetowej do obsługi bezpiecznego ruchu przez HTTPS i egzekwowanie tej zasady jest jedną z pierwszych rzeczy, które należy wdrożyć i jest to równie ważne dla aplikacji internetowych, jak dla interfejsów API.
dzięki dobrze ugruntowanym usługom, takim jak Let ‘ s Encrypt, które zapewniają bezpłatne certyfikaty TLS, nie ma już przekonujących powodów technicznych ani finansowych, aby nie używać HTTPS w aplikacjach internetowych.
w tym artykule zademonstruję jak poprawnie skonfigurować aplikacje internetowe tak, aby wymagały HTTPS i przytoczę przykłady dla obu ASP.NET oraz ASP.NET projekty podstawowe.
przekierowanie HTTPS
aby upewnić się, że witryna jest prawidłowo zabezpieczona, po uzyskaniu i zainstalowaniu nowego błyszczącego certyfikatu SSL/TLS, należy upewnić się, że HTTPS jest zawsze używany.
w przypadku aplikacji internetowych, np. aplikacji MVC, można skonfigurować przekierowanie ruchu z HTTP do HTTPS.
z wielu powodów nadal zaleca się, aby otworzyć domyślny port HTTP (port 80) i przekierować użytkowników do domyślnego portu HTTPS (port 443) w przypadku aplikacji internetowych, do których można uzyskać dostęp za pośrednictwem przeglądarki.
jest to część oficjalnej porady dotyczącej najlepszych praktyk w dokumentacji Let ‘ s Encrypt. Najlepszy badacz bezpieczeństwa, Scott Helm, ma również bardzo dobry artykuł, który wyjaśnia, dlaczego zamknięcie Portu 80 jest szkodliwe dla bezpieczeństwa w kontekście aplikacji internetowych.
w poniższych sekcjach demonstruję jak skonfigurować przekierowanie HTTPS dla ASP.NET oraz ASP.NET podstawowe aplikacje internetowe.
ASP.NET web apps
The ASP.NET MVC Framework ma wbudowaną klasę RequireHttpsAttribute
, z której możemy skorzystać.
po zastosowaniu atrybut spowoduje odesłanie odpowiedzi przekierowania do Klienta, jeśli żądanie zostało wysłane przez HTTP zamiast HTTPS.
atrybut może być zastosowany na podstawie kontrolera lub działania. Jednak gorąco polecam stosowanie atrybutu globalnie, aby wymusić przekierowanie HTTPS w całej witrynie, jak pokazano poniżej.
Add (nowy RequireHttpsAttribute());
powyższy wiersz kodu zwykle pojawia się w statycznej metodzie RegisterGlobalFilters
w klasie FilterConfig
, zgodnie z poniższym fragmentem kodu.
/// <podsumowanie> / / / rejestruje filtry Globalne.///</ summary>///<param name="filters">zbiór filtrów do rejestracji< / param>public static void RegisterGlobalFilters(GlobalFilterCollection filters){ filters.Add (new HandleErrorAttribute ()); filtry.Add (new RequireHttpsAttribute ()); filtry.Dodaj (nowy AuthorizeAttribute());}
w ASP.NET aplikacja, metoda RegisterGlobalFilters
jest zwykle wywoływana podczas uruchamiania z metody Application_Start
w ramach Globalnej.akta asax.
zanim przejdziemy dalej, ważne jest, aby pamiętać, że filtry globalne będą miały zastosowanie tylko do żądań HTTP, które są przekazywane do kontrolerów. W związku z tym klient nadal może uzyskać dostęp do plików statycznych, takich jak arkusze stylów i pliki skryptów przez niezabezpieczony protokół HTTP.
powinieneś uważać, aby używać względnych linków do wszelkich zasobów statycznych, do których odwołujesz się z HTML, lub używać bezwzględnych adresów URL ze schematem HTTPS, aby upewnić się, że cała zawartość jest obsługiwana w bezpieczny sposób.
przepisywanie reguł
aby zapewnić jeszcze większe bezpieczeństwo aplikacji internetowej, można skonfigurować przekierowanie na poziomie odwrotnego serwera proxy, np. jako część konfiguracji usług IIS. Dzięki temu wszystkie przychodzące żądania zostaną odpowiednio przekierowane.
w przypadku usług IIS można to zaimplementować za pomocą reguły przepisywania, dodając do sieci następujące elementy.plik konfiguracyjny.
<rewrite ><rules ><rule name="HTTP to HTTPS redirect" stopProcessing="true"> <match url="(.*)" /> <warunki> <add input="{HTTPS}" pattern="off" ignoreCase="true" /> </conditions> <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" /> </rule> </rules></rewrite>
usługi IIS będą respektować powyższą regułę przepisywania podczas obsługi ruchu przychodzącego, przekierowując niezabezpieczony ruch do https, zanim dotrze do kodu aplikacji.
podobnie jak w przypadku wielu aspektów bezpieczeństwa, uważam, że najlepiej jest mieć wiele warstw zabezpieczeń. Jeśli coś zawiedzie lub jest źle skonfigurowane na jednym poziomie, posiadanie awaryjnego jest zawsze dobrą rzeczą.
. NET Core
. NET Core ma również wbudowaną klasę RequireHttpsAttribute
, która może być stosowana na podstawie każdego kontrolera/akcji lub może być zarejestrowana globalnie.
globalna rejestracja może być skonfigurowana za pomocą metody ConfigureServices
twojej klasy Startup
, jak pokazano poniżej.
/// <summary> / / / metoda ta zostanie wywołana przez runtime./// Użyj tej metody, aby dodać usługi do kontenera.///</ summary>///<param name="services">zbiór usług kontenerowych< / param>public void ConfigureServices(iservicecollection services){ services.AddControllersWithViews (options = > options.Filtry.Add (nowy RequireHttpsAttribute()));}
powyższy kod robi zasadniczo to samo co w tradycyjnym ASP.NET projekt.
jednak w. NET Core możemy zrobić coś lepszego.
. NET Core ma również wbudowane oprogramowanie pośredniczące przekierowania HTTPS, które można skonfigurować za pomocą jednej linii kodu, jak pokazano poniżej.
UseHttpsRedirection ();
powyższy wiersz kodu powinien zostać dodany do metody Configure
klasy Startup
. Większość standardowych ASP.NET podstawowe szablony aplikacji internetowych, np. dla MVC, automatycznie konfigurują oprogramowanie pośredniczące przekierowania HTTPS.
Poniżej znajduje się przykład typowej zawartości metody Configure
.
/// <summary> / / / metoda ta zostanie wywołana przez runtime./// Użyj tej metody do skonfigurowania potoku żądania HTTP./// </podsumowanie>/// <param name="app">obiekt konstruktora aplikacji używany do konfiguracji potoku żądania</param>/// <param name="env">środowisko hostingowe, w którym aplikacja jest uruchomiona</param>Public void Configure(aplikacja IApplicationBuilder, iwebhostenvironment env){ if (env.IsDevelopment ()) {app.UseDeveloperExceptionPage ();} else { app.UseExceptionHandler ("/Home / Error"); app.UseHsts ();} app.UseHttpsRedirection (); app.UseStaticFiles (); app.UseRouting (); app.UseAuthorization (); app.UseEndpoints (endpoints => { endpoints.MapControllerRoute (name: "default", pattern: "{controller = Home} / {action = Index}/{id?}"); });}
dlaczego więc oprogramowanie pośredniczące przekierowania HTTPS jest lepsze niż filtr RequireHttpsAttribute
?
Cóż, dzięki temu, że ASP.NET hostowane są podstawowe aplikacje internetowe, przekierowania https warstwy pośredniej są stosowane na wyższym poziomie, a zatem żądania dotyczące plików statycznych, takich jak arkusze stylów i skrypty, będą również przekierowywane oprócz żądań związanych z kontrolerem.
HSTS
kolejny przydatny kawałek ASP.NET core middleware jest oprogramowaniem pośredniczącym HSTS i jest skonfigurowane w powyższym przykładzie za pomocą następującego wiersza kodu.
UseHsts();
zauważ, że podobnie jak w przypadku wielu wbudowanych komponentów middleware, wiele bardziej zaawansowanych aspektów ASP.NET Core middleware można skonfigurować w ramach metody ConfigureServices
klasy startowej.
co to jest HSTS i dlaczego powinniśmy z niego korzystać?
problem z przekierowaniem HTTPS sam w sobie jest z tym pierwszym niezabezpieczonym żądaniem, które przychodzi do aplikacji od klienta.
jeśli pierwsze przychodzące żądanie HTTP zostanie przechwycone przez ‘człowieka w środku’, integralność żądania zostanie utracona. Na przykład klient może zostać przekierowany gdzie indziej, nie zauważając np. fałszywej strony logowania.
HSTS oznacza http Strict Transport Security i pomaga rozwiązać problem opisany powyżej, informując przeglądarkę, że aplikacja internetowa powinna być dostępna tylko przez HTTPS.
robi to zwracając nagłówek Strict-Transport-Security w odpowiedzi tak, że kolejne żądania używają HTTPS bez dalszych przekierowań. Przeglądarka buforuje tę instrukcję, aby zapewnić, że dalsze wizyty na stronie będą przez HTTPS bez dalszych przekierowań.
pierwsza Prośba
tak, to wszystko brzmi świetnie, ale co z tą pierwszą prośbą?
rozwiązaliśmy większość problemu, ale nadal nie mamy do czynienia z pierwszym żądaniem otrzymanym od klienta, który nigdy wcześniej nie odwiedził naszej strony.
aby być super-bezpiecznym i zamknąć pętlę na tym, możemy zarejestrować naszą stronę jako “wstępnie załadowaną”. Przeglądarki przechowują listę witryn, które znajdują się na liście “preload”, a jeśli Twoja witryna znajduje się na tej liście, nigdy nie otrzymasz niebezpiecznego żądania od klienta, ponieważ przeglądarka będzie honorować status preload.
możesz zarejestrować swoją witrynę do wstępnego załadowania, przechodząc do strony HSTS Preload i wysyłając prośbę o jej wstępne załadowanie.
Poniżej znajduje się przykład nagłówka HSTS z podaną dyrektywą preload.
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
pamiętaj, że bardzo ważne jest, aby dokładnie przetestować swoją witrynę przed włączeniem HSTS w środowisku produkcyjnym, aby upewnić się, że działa poprawnie przez HTTPS. Jest to szczególnie ważne, jeśli zdecydujesz się na wstępne załadowanie witryny, ponieważ nie można tego łatwo cofnąć i usunięcie witryny z listy wstępnego ładowania może potrwać miesiące.
Gorąco polecam konfigurację HSTS dla Twoich aplikacji internetowych. To, czy zdecydujesz się również na wstępnie załadowaną witrynę, zależy od konkretnych wymagań bezpieczeństwa.
reguły wychodzące
zgodnie z sekcją reguły przepisywania z poprzedniego artykułu, możesz także włączyć HSTS na poziomie odwrotnego serwera proxy.
Poniżej znajduje się przykład jak skonfigurować to w sieci.plik konfiguracyjny, jeśli aplikacja jest hostowana w usługach IIS.
<przepisz ><outboundRules ><nazwa reguły="Dodaj Strict-Transport-Security, gdy HTTPS" włączony="true"> <dopasuj serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" /> <warunki> <add input="{HTTPS}" pattern="on" ignoreCase="true" /> < / warunki> <action type="Rewrite" value = "max-age=31536000" /> </reguła></outboundRules></rewrite>
teraz nagłówek HSTS zostanie ustawiony dla całego ruchu HTTPS w Twojej witrynie.
zauważ, że powyższe podejście będzie działać zarówno dla tradycyjnych ASP.NET oraz ASP.NET podstawowe zastosowania. Wystarczy dodać stronę www.plik konfiguracyjny do projektu i upewnij się, że właściwość “Kopiuj do katalogu wyjściowego” jest ustawiona na “Kopiuj, jeśli nowszy”.
API
API różnią się nieco od zwykłych aplikacji internetowych, do których dostęp mają ludzie, zarówno pod względem projektu, przeznaczenia, jak i bezpieczeństwa.
omówimy najlepsze praktyki dotyczące wymogu HTTPS dla interfejsów API w poniższych sekcjach.
wymagasz HTTPS?
tradycyjne ASP.NET projekty Web API nie mają dostępu do wbudowanego atrybutu wymagającego HTTPS.
jednak to nie powstrzymuje nas przed tworzeniem własnych.
Poniżej znajduje się przykład jak to zrobić.
/// <summary>/// Called when a process requests authorization./// </summary>/// <param name="actionContext">The action context</param>public override void OnAuthorization(HttpActionContext actionContext){ HttpRequestMessage request = actionContext.Request; if (request.RequestUri.Scheme != Uri.UriSchemeHttps) { if (request.Method.Equals(HttpMethod.Get)) { actionContext.Response = request.CreateResponse(HttpStatusCode.Found, "SSL is required"); // Provide the correct URL to the user via the Location header. var uriBuilder = new uribuilder (request.RequestUri) {Scheme = Uri.UriSchemeHttps, Port = 443 }; actionContext.Odpowiedź.Nagłówki.Location = uriBuilder.Uri;} else actionContext.Odpowiedź = Prośba.CreateResponse (HttpStatusCode.NotFound, "SSL jest wymagane"); }}
w powyższym przykładzie utworzyłem klasę o nazwie RequireHttpsAttribute
, która wywodzi się z klasy AuthorizationFilterAttribute
i nadpisuję metodę virtual OnAuthorization
.
w przypadku żądań GET powyższa metoda informuje klientów o poprawnym adresie URL za pomocą schematu HTTPS, zwracając to w nagłówku lokalizacji. Dla wszystkich innych żądań po prostu zwracany jest komunikat “SSL is required”.
chociaż ma to sens podczas wywoływania API z przeglądarki, jednym z problemów z powyższym kodem jest to, że zwraca on kod statusu przekierowania, którego większość klientów API nie zrozumie.
w zależności od punktu widzenia powyższy kod może zostać zmieniony, aby ustawić kod statusu HTTP na coś innego, na przykład złe żądanie, zamiast próbować przekierować klienta.
możemy zaimplementować coś podobnego wNet Core poprzez stworzenie naszej własnej klasy, takiej jak ApiRequireHttpsAttribute
, która wywodzi się z wbudowanej klasy RequireHttpsAttribute
. Następnie możemy nadpisać metodę virtual HandleNonHttpsRequest
i odpowiednio ustawić kod odpowiedzi, zgodnie z poniższym przykładowym kodem.
/// <podsumowanie> / / / wywołane, jeśli żądanie nie zostało odebrane przez HTTPS.///</ summary>///<param name="filterContext">the filter context< / param>protected override void HandleNonHttpsRequest(AuthorizationFilterContext filterContext){ filterContext.Result = new StatusCodeResult (400);}
powyższy kod ustawia kod statusu HTTP odpowiedzi na złe żądanie (400). Można go zmienić, aby uwzględnić wiadomość w odpowiedzi lub jakąkolwiek inną logikę niestandardową.
nie słuchasz?
OK, więc przyjrzeliśmy się, jak zmusić klientów API do korzystania z HTTPS, gdy próbują użyć HTTP.
czy to jednak najlepsza opcja?
najlepsza praktyka nakazuje, że powinniśmy mieć wiele warstw zabezpieczeń, ale także nakazuje, że powinniśmy wdrożyć zabezpieczenia tak wcześnie, jak to możliwe.
w rzeczywistości najbezpieczniejszą rzeczą, jaką możemy zrobić w kontekście interfejsów API, jest uniemożliwienie im nasłuchiwania na niezabezpieczonym porcie. Ta rada znajduje odzwierciedlenie w dokumentach Microsoft dla ASP.NET Rdzeń.
oczywiście nie możemy uniemożliwić klientowi API próby uzyskania naszego API w niepewny sposób. Jednak w tym przypadku jest to wina integratora API, a nie coś, dla czego możemy zrobić coś znaczącego, aby temu zapobiec.
podsumowanie
w tym artykule omówiłem sposób egzekwowania protokołu HTTPS w aplikacjach internetowych i interfejsach API oraz omówiłem Najbardziej odpowiednie i bezpieczne rozwiązania dla obu scenariuszy.
najważniejsze jest to, że powinieneś zaimplementować wiele warstw zabezpieczeń dla swojej aplikacji i tam, gdzie to możliwe, egzekwować zabezpieczenia tak wcześnie, jak to możliwe.
wykorzystaj HSTS i wykorzystaj moc konfiguracji serwera odwrotnego proxy, aby bezpiecznie obsługiwać żądania.
Leave a Reply