So konfigurieren Sie Ihre ASP.NET Web-Apps und APIs erfordern HTTPS

Für jede Anwendung, die im Web gehostet wird, ist es wichtig, dass die Sicherheit von Anfang an integriert ist.
Das Aktivieren Ihrer Webanwendung für sicheren Datenverkehr über HTTPS und das Erzwingen dieser Richtlinie ist eines der ersten Dinge, die Sie implementieren sollten.

Mit etablierten Diensten wie Let’s Encrypt, die kostenlose TLS-Zertifikate bereitstellen, gibt es keinen zwingenden technischen oder finanziellen Grund mehr, HTTPS nicht für Ihre Webanwendungen zu verwenden.
In diesem Artikel zeige ich, wie Sie Ihre Webanwendungen so konfigurieren, dass sie HTTPS erfordern, und behandle Beispiele für beide ASP.NET und ASP.NET Kernprojekte.

HTTPS-Umleitung

Um sicherzustellen, dass Ihre Website ordnungsgemäß gesichert ist, sollten Sie nach Erhalt und Installation eines glänzenden neuen SSL / TLS-Zertifikats sicherstellen, dass HTTPS immer verwendet wird.

Für Ihre Webanwendungen, z. B. MVC-Anwendungen, können Sie den Datenverkehr so konfigurieren, dass er von HTTP nach HTTPS umgeleitet wird.

Aus verschiedenen Gründen ist es dennoch ratsam, den Standard-HTTP-Port (Port 80) offen zu halten und Ihre Benutzer für Webanwendungen, auf die über einen Browser zugegriffen wird, zum Standard-HTTPS-Port (Port 443) umzuleiten.

Dies ist Teil der offiziellen Best-Practice-Ratschläge in der Let’s Encrypt-Dokumentation. Der Top-Sicherheitsforscher Scott Helm hat auch einen sehr guten Artikel, der erklärt, warum das Schließen von Port 80 für die Sicherheit im Kontext von Webanwendungen schlecht ist.

In den folgenden Abschnitten zeige ich, wie die HTTPS-Umleitung für ASP.NET und ASP.NET Kern-Web-Anwendungen.

ASP.NET web apps

Die ASP.NET MVC Framework hat bequem eine eingebaute RequireHttpsAttribute Klasse, die wir in Anspruch nehmen können.

Wenn das Attribut angewendet wird, wird eine Umleitungsantwort an den Client gesendet, wenn eine Anforderung über HTTP anstelle von HTTPS gesendet wurde.

Das Attribut kann entweder pro Controller oder pro Aktion angewendet werden. Ich empfehle jedoch dringend, das Attribut global anzuwenden, um die HTTPS-Umleitung auf der gesamten Site zu erzwingen, wie unten gezeigt.

Filter.Hinzufügen (neu RequireHttpsAttribute());

Die obige Codezeile wird normalerweise innerhalb einer statischen RegisterGlobalFilters -Methode in einer FilterConfig -Klasse gemäß dem folgenden Codeausschnitt angezeigt.

/// < summary>/// Registriert globale Filter./// </summary>/// <param name="filters">Die Sammlung der zu registrierenden Filter</param>public static void RegisterGlobalFilters(GlobalFilterCollection filters){ filters.Add(new HandleErrorAttribute()); Filter.Add(new RequireHttpsAttribute()); Filter.Hinzufügen (neues AuthorizeAttribute());}

In einem ASP.NET anwendung wird die Methode RegisterGlobalFilters normalerweise beim Start von der Methode Application_Start innerhalb der Globalen aufgerufen.asax-Datei.

Bevor Sie fortfahren, ist es wichtig zu beachten, dass globale Filter nur für HTTP-Anforderungen gelten, die an Ihre Controller übergeben werden. Daher ist es für einen Client weiterhin möglich, über unsicheres HTTP auf statische Dateien wie Stylesheets und Skriptdateien zuzugreifen.

Sie sollten darauf achten, relative Links zu statischen Ressourcen zu verwenden, auf die Sie in Ihrem HTML-Code verweisen, oder absolute URLs mit dem HTTPS-Schema zu verwenden, um sicherzustellen, dass alle Inhalte sicher bereitgestellt werden.

Rewrite rules

Um Ihre Webanwendung noch sicherer zu machen, können Sie die Umleitung auf Reverse-Proxy-Ebene konfigurieren, z. B. als Teil Ihrer IIS-Konfiguration. Dadurch wird sichergestellt, dass alle eingehenden Anforderungen entsprechend umgeleitet werden.

Im Fall von IIS können Sie dies über eine Umschreibungsregel implementieren, indem Sie Ihrem Web Folgendes hinzufügen.konfigurationsdatei.

<rewrite> <Regeln> <Regelname ="HTTP zu HTTPS umleiten" stopProcessing="true"> <match url="(.*)" /> < bedingungen> <add input="{HTTPS}" pattern="off" IgnoreCase="true" /> </bedingungen> <Aktionstyp ="Umleiten" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" / > </Regel > </Regeln></ rewrite>

IIS respektiert die obige Rewrite-Regel bei der Verarbeitung eingehenden Datenverkehrs und leitet unsicheren Datenverkehr zu HTTPS um, bevor er Ihren Anwendungscode erreicht.

Wie bei vielen Sicherheitsaspekten ist es meiner Meinung nach am besten, mehrere Sicherheitsebenen einzurichten. Wenn etwas auf einer Ebene fehlschlägt oder falsch konfiguriert ist, ist ein Fallback immer eine gute Sache.

.NET Core

.NET Core verfügt außerdem über eine integrierte RequireHttpsAttribute -Klasse, die entweder pro Controller / Aktion angewendet oder global registriert werden kann.

Die globale Registrierung kann innerhalb der ConfigureServices -Methode Ihrer Startup -Klasse eingerichtet werden, wie unten gezeigt.

/// < summary>/// Diese Methode wird von der Laufzeit aufgerufen./// Verwenden Sie diese Methode, um dem Container Dienste hinzuzufügen./// </summary>/// <param name="services">Die Sammlung von Containerdiensten</param>public void ConfigureServices(IServiceCollection services){ services.AddControllersWithViews(Optionen => Optionen.Preisauswahl.Hinzufügen (neu RequireHttpsAttribute()));}

Der obige Code macht grundsätzlich dasselbe wie in einem traditionellen ASP.NET projekt.

In .NET Core können wir es jedoch besser machen.

.NET Core verfügt außerdem über eine integrierte HTTPS-Umleitungs-Middleware, die wie unten gezeigt mit einer Codezeile konfiguriert werden kann.

app.UseHttpsRedirection();

Die obige Codezeile sollte der Configure -Methode der Startup -Klasse hinzugefügt werden. Die meisten der Standard ASP.NET Core-Webanwendungsvorlagen, z. B. für MVC, konfigurieren die HTTPS-Umleitungs-Middleware automatisch.

Nachfolgend finden Sie ein Beispiel für den typischen Inhalt der Configure -Methode als Referenz.

/// < summary>/// Diese Methode wird von der Laufzeit aufgerufen./// Verwenden Sie diese Methode, um die HTTP-Anforderungspipeline zu konfigurieren./// </zusammenfassung>/// <param name="app">Das Application Builder-Objekt zum Konfigurieren der Anforderungspipeline</param>/// <param name="env">Die Webhosting-Umgebung, in der die Anwendung ausgeführt wird</param>public void Configure(IApplicationBuilder app, IWebHostEnvironment env){ wenn (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } sonst { app.UseExceptionHandler("/ Home / Fehler"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(Endpunkte => { Endpunkte.MapControllerRoute( Name: "Standard", Muster: "{controller =Home} / {action=Index} /{id?}"); });}

Warum ist die HTTPS-Umleitungs-Middleware besser als der RequireHttpsAttribute -Filter?

Nun, dank der Art und Weise, dass ASP.NET Core-Web-Apps werden gehostet, die Middleware-HTTPS-Weiterleitungen werden auf einer höheren Ebene angewendet, und daher werden Anforderungen für statische Dateien wie Stylesheets und Skripte zusätzlich zu Controller-gebundenen Anforderungen umgeleitet.

HSTS

Ein weiteres nützliches Stück ASP.NET Core Middleware ist die HSTS Middleware und wird im obigen Beispiel über die folgende Codezeile konfiguriert.

app.UseHsts();

Beachten Sie, dass wie bei vielen der integrierten Middleware-Komponenten viele erweiterte Aspekte von ASP.NET Core-Middleware kann innerhalb der ConfigureServices -Methode Ihrer Startup-Klasse konfiguriert werden.

Was ist HSTS und warum sollten wir es verwenden?

Das Problem mit der HTTPS-Umleitung allein liegt in der ersten unsicheren Anforderung, die von einem Client in die Anwendung kommt.

Wenn die erste eingehende HTTP-Anforderung von einem ‘Mann in der Mitte’ abgefangen wird, geht die Integrität der Anforderung verloren. Zum Beispiel könnte der Client woanders umgeleitet werden, ohne dass er es bemerkt, z. B. auf eine gefälschte Anmeldeseite.

HSTS steht für HTTP Strict Transport Security und hilft, das oben beschriebene Problem zu lösen, indem es den Browser darüber informiert, dass auf eine Webanwendung nur über HTTPS zugegriffen werden soll.

Dazu wird ein Strict-Transport-Security-Header in der Antwort zurückgegeben, sodass nachfolgende Anforderungen HTTPS ohne weitere Umleitungen verwenden. Der Browser speichert diese Anweisung zwischen, um sicherzustellen, dass weitere Besuche der Website über HTTPS ohne weitere Weiterleitungen erfolgen.

Die allererste Anfrage

Ja, das klingt alles großartig, aber was ist mit dieser allerersten Anfrage?

Wir haben den größten Teil des Problems gelöst, aber wir haben uns immer noch nicht mit der allerersten Anfrage eines Kunden befasst, der unsere Website noch nie zuvor besucht hat.

Um supersicher zu sein und den Kreislauf zu schließen, können wir unsere Site als ‘vorinstalliert’ registrieren. Browser führen eine Liste von Websites, die sich in einer Preload-Liste befinden, und wenn sich Ihre Website in dieser Liste befindet, erhalten Sie niemals eine unsichere Anforderung von einem Client, da der Browser den Preload-Status einhält.

Sie können Ihre Site für das Vorladen registrieren, indem Sie auf die HSTS Preload-Website gehen und eine Anforderung zum Vorladen senden.

Unten finden Sie ein Beispiel für einen HSTS-Header mit der angegebenen Preload-Direktive.

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

Beachten Sie, dass es äußerst wichtig ist, dass Sie Ihre Site gründlich testen, bevor Sie HSTS in einer Produktionsumgebung aktivieren, um sicherzustellen, dass sie über HTTPS ordnungsgemäß funktioniert. Dies ist besonders wichtig, wenn Sie Ihre Website vorab laden, da dies nicht einfach rückgängig gemacht werden kann und es Monate dauern kann, bis Ihre Website aus der Vorladeliste entfernt wird.

Ich empfehle dringend, HSTS für Ihre Webanwendungen zu konfigurieren. Ob Sie sich auch dafür entscheiden, Ihre Website vorinstalliert zu haben, hängt von Ihren spezifischen Sicherheitsanforderungen ab.

Ausgehende Regeln

Gemäß dem Abschnitt Regeln neu schreiben zu einem früheren Zeitpunkt in diesem Artikel können Sie HSTS auch auf Reverse-Proxy-Ebene aktivieren.

Unten finden Sie ein Beispiel, wie Sie dies in einem Web konfigurieren können.konfigurationsdatei, wenn Sie Ihre Anwendung in IIS hosten.

<rewrite> <outboundRules> <Regelname= "Strict-Transport-Security hinzufügen, wenn HTTPS aktiviert ist" enabled="true"> <match serverVariable="RESPONSE_Strict_Transport_Security" pattern=".*" /> <Bedingungen> <add input="{HTTPS}" pattern="on" IgnoreCase="true" /> </Bedingungen > < Aktionstyp = "Umschreiben" Wert = "maximales Alter=31536000" /> </ rule> </outboundRules></rewrite>

Jetzt wird der HSTS-Header für den gesamten HTTPS-Datenverkehr auf Ihrer Site festgelegt.

Beachten Sie, dass der obige Ansatz sowohl für traditionelle ASP.NET und ASP.NET Kernanwendungen. Sie müssen nur ein Web hinzufügen.stellen Sie sicher, dass die Eigenschaft ‘In Ausgabeverzeichnis kopieren’ auf ‘Kopieren, wenn neuer’ gesetzt ist.

APIs

APIs unterscheiden sich von normalen Webanwendungen, auf die von Menschen zugegriffen wird, sowohl im Design als auch in den beabsichtigten Anwendungsfällen und Sicherheitsüberlegungen.

In den folgenden Abschnitten werden die Best Practices für die Anforderung von HTTPS für APIs behandelt.

HTTPS erforderlich?

Traditionell ASP.NET Web-API-Projekte haben keinen Zugriff auf ein integriertes Attribut, das HTTPS erfordert.

Dies hindert uns jedoch nicht daran, unsere eigenen zu erstellen.

Unten finden Sie ein Beispiel dafür.

/// <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 = neuer UriBuilder (Anfrage.RequestUri) { Schema = Uri.UriSchemeHttps, Port = 443 }; Aktionskontext.Antwort.Headern.Location = UriBuilder.Uri; } sonst ActionContext.Antwort = Anfrage.CreateResponse(HttpStatusCode.NotFound, "SSL ist erforderlich"); }}

Im obigen Beispiel habe ich eine Klasse namens RequireHttpsAttribute erstellt, die von der Klasse AuthorizationFilterAttribute abgeleitet ist, und überschreibe die virtuelle Methode OnAuthorization.

Bei GET-Anforderungen informiert die obige Methode Clients mithilfe des HTTPS-Schemas über die richtige URL, indem sie diese im Location-Header zurückgibt. Für alle anderen Anfragen wird einfach die Meldung ‘SSL is required’ zurückgegeben.

Obwohl dies beim Aufrufen einer API über einen Browser sinnvoll ist, besteht eines der Probleme mit dem obigen Code darin, dass ein Umleitungsstatuscode zurückgegeben wird, den die meisten API-Clients nicht verstehen.

Abhängig von Ihrem Standpunkt könnte der obige Code stattdessen geändert werden, um den HTTP-Statuscode auf etwas anderes zu setzen, z. B. eine fehlerhafte Anforderung, anstatt zu versuchen, den Client umzuleiten.

Wir können etwas Ähnliches in implementieren .NET Core durch Erstellen einer eigenen Klasse wie ApiRequireHttpsAttribute, die von der integrierten Klasse RequireHttpsAttribute abgeleitet ist. Wir können dann die virtuelle HandleNonHttpsRequest -Methode überschreiben und den Antwortcode entsprechend dem folgenden Beispielcode festlegen.

/// < zusammenfassung>/// Wird aufgerufen, wenn die Anforderung nicht über HTTPS empfangen wird./// </summary>/// <param name="filterContext">Der Filterkontext</param>geschützte Überschreibung void HandleNonHttpsRequest(AuthorizationFilterContext filterContext){ filterContext.Ergebnis = neues StatusCodeResult (400);}

Der obige Code setzt den HTTP-Statuscode für die Antwort auf Bad Request (400). Es kann geändert werden, um eine Nachricht in die Antwort oder eine andere benutzerdefinierte Logik aufzunehmen, die erforderlich ist.

Nicht hören?

Ok, also haben wir uns angesehen, wie API-Clients gezwungen werden, HTTPS zu verwenden, wenn sie versuchen, HTTP zu verwenden.

Ist dies jedoch die beste Option?

Best Practice schreibt vor, dass wir mehrere Sicherheitsebenen haben sollten, aber es schreibt auch vor, dass wir die Sicherheit so früh wie möglich implementieren sollten.

Eigentlich ist das Sicherste, was wir im Zusammenhang mit APIs tun können, zu verhindern, dass sie einen nicht sicheren Port abhören. Dieser Hinweis wird in den Microsoft-Dokumenten für ASP.NET Kern.

Natürlich können wir nicht verhindern, dass ein API-Client versucht, unsere API auf unsichere Weise zu erreichen. In diesem Fall ist es jedoch die Schuld des API-Integrators und nicht etwas, für das wir etwas Sinnvolles tun können, um dies zu verhindern.

Zusammenfassung

In diesem Artikel habe ich behandelt, wie Sie HTTPS in Ihren Web-Apps und APIs erzwingen können, und ich habe die am besten geeigneten und sichersten Lösungen für beide Szenarien besprochen.

Das Wichtigste ist, dass Sie mehrere Sicherheitsebenen für Ihre Anwendung implementieren und die Sicherheit nach Möglichkeit so früh wie möglich erzwingen.

Nutzen Sie HSTS und nutzen Sie die Leistungsfähigkeit Ihrer Reverse-Proxy-Konfiguration, um Anforderungen auf sichere Weise zu verarbeiten.

Leave a Reply