Die Arbeit mit Web-APIs in ASP.NET Core Minimal APIs ist eine effektive Methode, um skalierbare, wartbare und sichere Webdienste zu erstellen. In dieser Anleitung wird beschrieben, wie man grundlegende Operationen wie das Abrufen, Hinzufügen, Aktualisieren und Löschen von Produkten in einer API umsetzt und dabei moderne Webstandards und Sicherheitsaspekte berücksichtigt.
Zunächst muss man sicherstellen, dass die REST Client-Erweiterung in Visual Studio Code installiert ist, falls diese noch nicht vorhanden ist. Dies kann über den Extensions Marketplace erfolgen. Anschließend startet man das Projekt „Northwind.WebApi.Service“ im bevorzugten Code-Editor, wobei das HTTPS-Profil zu verwenden ist. Das Projekt sollte während der Tests immer laufen, da wir in den nächsten Schritten HTTP-Anfragen an die Web-API stellen werden.
In einem Ordner namens RestClientTests, der im Projektverzeichnis apps-services-net7 angelegt wird, können wir die erforderlichen Testdateien erstellen. Zum Beispiel beginnt der Test für die GET-Anfrage, die alle Produkte abruft, mit einer HTTP-Anfrage, wie im folgenden Codeausschnitt gezeigt:
Nach dem Senden der Anfrage erhält man eine Antwort im JSON-Format, die die ersten zehn Produkte auflistet, die auf Lager sind und nicht aus dem Sortiment genommen wurden. Weitere Testanfragen können hinzugefügt werden, etwa um die zweite Seite von Produkten zu erhalten, Produkte zu suchen, die nicht auf Lager sind, oder Produkte zu finden, die aus dem Sortiment genommen wurden.
Ein Beispiel für weitere Anfragen könnte so aussehen:
Jede dieser Anfragen liefert unterschiedliche Daten, je nachdem, welche Kriterien in der URL definiert sind. So lassen sich die Funktionen der Web-API detailliert testen. Die Anfragen können entweder über den Button „Send Request“ in Visual Studio Code ausgeführt werden oder durch die Tastenkombinationen des Systems.
Für komplexere Tests können auch POST-, PUT- und DELETE-Anfragen verwendet werden. Beispielsweise könnte man eine neue Produktanfrage mittels einer POST-Anfrage hinzufügen, die wie folgt aussieht:
Nach dem Senden dieser Anfrage und dem Erhalt eines erfolgreichen Statuscodes (201) stellt sich heraus, dass das neue Produkt in der Datenbank eingefügt wurde. Der zugewiesene Produkt-ID wird als Antwort zurückgegeben. Sollte ein Produkt aktualisiert werden, etwa die Preise oder Bestandszahlen, geschieht dies über eine PUT-Anfrage:
Ein erfolgreicher Update-Vorgang wird durch den Statuscode 204 angezeigt. Ebenso können Produkte gelöscht werden, wie dies in einer DELETE-Anfrage demonstriert wird:
Die erfolgreiche Löschung eines Produkts wird durch eine Antwort mit dem Statuscode 204 bestätigt, während das erneute Senden derselben Anfrage zu einem Fehler (404) führt, da das Produkt nun gelöscht wurde.
Neben den grundlegenden CRUD-Operationen ist es wichtig, die Sicherheitsaspekte und die Konfiguration der Web-API zu verstehen. Ein wichtiger Aspekt bei der Arbeit mit Web-APIs ist die Same-Origin-Policy (SOP), die sicherstellt, dass Anfragen nur von der gleichen Quelle (Host, Protokoll, Port) wie der Webdienst selbst ausgeführt werden dürfen. Diese Sicherheitsmaßnahme verhindert Angriffe wie Cross-Site Request Forgery (CSRF). Wenn jedoch eine API auch von externen Quellen genutzt werden soll, ist es notwendig, CORS (Cross-Origin Resource Sharing) zu konfigurieren.
In ASP.NET Core kann dies über die Middleware UseCors erfolgen, die bestimmte Ursprünge (Origins) für API-Anfragen freigibt. Die Konfiguration erfolgt über die Program.cs-Datei, in der explizit festgelegt wird, welche Ursprünge zugelassen sind:
Eine weitere wichtige Konfiguration betrifft das HTTP-Logging. Insbesondere das Loggen der Herkunft (Origin) von HTTP-Anfragen kann entscheidend für die Sicherheitsanalyse sein. In ASP.NET Core kann dies über die AddHttpLogging-Methode eingestellt werden, um den Ursprung von Anfragen zu protokollieren und Sicherheitslücken frühzeitig zu identifizieren.
Abschließend ist es unerlässlich, die Fehlerbehandlung und Sicherheitsmechanismen zu implementieren, um potenzielle Angriffe zu verhindern. Die Konfiguration der API, das Testen ihrer Funktionen und das Verständnis der Sicherheitsaspekte tragen dazu bei, robuste und sichere Web-Services zu erstellen.
Wie kann man DDoS-Angriffe durch effektives Rate-Limiting verhindern?
Ein Denial-of-Service (DoS)-Angriff ist ein böswilliger Versuch, einen Webservice zu stören, indem dieser mit Anfragen überflutet wird. Falls alle Anfragen von demselben Ursprungsort kommen, wäre es relativ einfach, diese nach der Erkennung des Angriffs zu blockieren. Doch in vielen Fällen werden solche Angriffe als verteilte DoS-Angriffe (DDoS) durchgeführt, bei denen die Anfragen aus vielen verschiedenen Quellen stammen, sodass es nahezu unmöglich ist, die Angreifer von echten Nutzern zu unterscheiden. Ein solcher Angriff kann den Webservice erheblich verlangsamen oder sogar vollständig zum Erliegen bringen.
Echte Nutzer sollten daher nur die minimal erforderliche Anzahl von Anfragen stellen, um den Service effizient zu nutzen. Was als „vernünftige“ Anzahl von Anfragen betrachtet wird, hängt von den spezifischen Anforderungen und dem Service ab, den man bereitstellt. Eine Möglichkeit, DDoS-Angriffe zu verhindern und gleichzeitig sicherzustellen, dass echte Benutzer nicht benachteiligt werden, ist die Einführung von Rate-Limiting. Diese Technik beschränkt die Anzahl der Anfragen, die von einem Client innerhalb eines bestimmten Zeitrahmens gesendet werden dürfen. Dies ist nicht nur eine Maßnahme gegen Angriffe, sondern kann auch helfen, Missbrauch zu verhindern und für unterschiedliche Tarife zu sorgen, wie sie bei abonnementbasierten Webdiensten vorkommen.
Um DDoS-Angriffe zu verhindern, kann man beispielsweise die Anzahl der Anfragen eines Clients pro Minute begrenzen. In solchen Fällen sollten Anfragen, die das festgelegte Limit überschreiten, eine 429-Fehlermeldung („Too Many Requests“) oder eine 503-Fehlermeldung („Service Unavailable“) zurückgeben. Diese Antwortcodes signalisieren dem Client, dass er seine Anfragen reduzieren muss, um den Service weiterhin nutzen zu können.
Für die Implementierung eines solchen Rate-Limitings in .NET Core kann das Paket AspNetCoreRateLimit verwendet werden. Dieses dritte Party-Paket stellt eine flexible Middleware bereit, die auf der IP-Adresse oder der Client-ID basiert und die Anzahl der Anfragen reguliert. Um dies zu erreichen, müssen zunächst die erforderlichen Konfigurationen und Parameter in der appsettings.Development.json Datei des Projekts definiert werden. Ein Beispiel für eine solche Konfiguration ist wie folgt:
Wichtige Punkte dabei:
-
EnableEndpointRateLimiting ist auf
falsegesetzt, was bedeutet, dass alle Endpunkte die gleichen Regeln teilen. -
Wenn ein Client sich identifizieren muss, kann er einen Header namens
X-Client-Idmit einer einzigartigen Zeichenkette setzen. -
Erreicht ein Client das Rate-Limit, wird der Webservice mit einem HTTP-Statuscode 429 antworten.
-
Zwei Endpunkte sind vom Rate-Limiting ausgeschlossen: einer für das Abrufen von Lizenzen und einer für die Statusabfrage des Services.
-
Zwei spezielle Client-IDs (
dev-id-1unddev-id-2) sind von der Rate-Limitierung ausgenommen. Diese könnten etwa für interne Entwickler-Konten vorgesehen sein.
Ein weiteres Beispiel ist die Konfiguration von spezifischen Client-Regeln. So kann für den Client console-client-abc123 eine höhere Anfragefrequenz gewährt werden, etwa 5 Anfragen alle 10 Sekunden und bis zu 250 Anfragen innerhalb von 12 Stunden.
Um diese Konfiguration in einem .NET Core-Projekt umzusetzen, muss das AspNetCoreRateLimit-Paket in das Projekt integriert werden. Zunächst wird der Dienst für das Rate-Limiting im Program.cs mit der Methode AddMemoryCache() und AddInMemoryRateLimiting() registriert. Danach wird die Konfiguration aus der appsettings.json geladen und die Rate-Limiting-Optionen werden gesetzt. Der folgende Code veranschaulicht, wie dies in der Praxis aussieht:
Wenn die Anwendung aufgerufen wird, wird die Middleware zur Überwachung der Anfragen und zur Durchsetzung der Rate-Limits verwendet. Sollte der Client das Limit überschreiten, erhält er die oben erwähnte Fehlermeldung, die ihm signalisiert, dass er seine Anfragen anpassen muss.
Ein weiterer wichtiger Punkt, der beachtet werden sollte, ist, dass Rate-Limiting nicht nur als Schutzmaßnahme gegen Angriffe dient, sondern auch zur Verbesserung der Servicequalität beiträgt. Wenn Clients zu viele Anfragen auf einmal senden, könnte dies den Server überlasten und die gesamte Dienstleistung beeinträchtigen. Durch die Implementierung von Rate-Limiting kann der Server Anfragen besser verwalten, die Antwortzeiten stabil halten und die Verfügbarkeit des Services gewährleisten. In einem kommerziellen Webservice könnte man darüber hinaus auch eine flexible Tarifgestaltung einführen, bei der Benutzer, die ein höheres Anfragevolumen benötigen, für zusätzliche Anfragen bezahlen müssen.
Es ist ebenso wichtig zu verstehen, dass Rate-Limiting nicht nur auf Basis der IP-Adresse durchgeführt werden kann, sondern auch auf Basis der Client-ID. Dies ermöglicht eine feiner granulierte Kontrolle darüber, wie verschiedene Clients auf den Service zugreifen dürfen. Auch bei einem gut implementierten Rate-Limiting müssen jedoch Mechanismen zur ordnungsgemäßen Fehlerbehandlung und zum Monitoring vorhanden sein, um die Performance und Verfügbarkeit des Systems zu gewährleisten.
Wie die Manipulation von Wahlen durch soziale Medien und geheime Akteure die Demokratie gefährdet
Wann begannen die modernen Menschen, die Erde zu bevölkern?
Claude 2 und GPT-3.5: Ein Vergleich der Leistungsfähigkeit von KI-Sprachmodellen
Wie man echte Verbindungen im Berufsleben aufbaut: Die Bedeutung von Rapport und Respekt

Deutsch
Francais
Nederlands
Svenska
Norsk
Dansk
Suomi
Espanol
Italiano
Portugues
Magyar
Polski
Cestina
Русский