Aktualisieren:
Ich habe diesen Link zu meiner anderen Antwort hinzugefügt, wie die JWT-Authentifizierung für die ASP.NET-Web-API hier für alle verwendet wird, die sich für JWT interessieren.
Wir haben es geschafft, die HMAC-Authentifizierung auf die sichere Web-API anzuwenden, und es hat einwandfrei funktioniert. Bei der HMAC-Authentifizierung wird für jeden Verbraucher ein geheimer Schlüssel verwendet, von dem sowohl der Verbraucher als auch der Server wissen, dass er eine Nachricht hasht. HMAC256 sollte verwendet werden. In den meisten Fällen wird das Hash-Passwort des Verbrauchers als geheimer Schlüssel verwendet.
Die Nachricht besteht normalerweise aus Daten in der HTTP-Anforderung oder sogar aus benutzerdefinierten Daten, die dem HTTP-Header hinzugefügt werden. Die Nachricht kann Folgendes enthalten:
- Zeitstempel: Zeit, zu der die Anforderung gesendet wird (UTC oder GMT)
- HTTP-Verb: GET, POST, PUT, DELETE.
- Postdaten und Abfragezeichenfolge,
- URL
Unter der Haube wäre die HMAC-Authentifizierung:
Der Verbraucher sendet eine HTTP-Anfrage an den Webserver, nachdem er die Signatur (Ausgabe des hmac-Hash), die Vorlage der HTTP-Anfrage, erstellt hat:
User-Agent: {agent}
Host: {host}
Timestamp: {timestamp}
Authentication: {username}:{signature}
Beispiel für eine GET-Anfrage:
GET /webapi.hmac/api/values
User-Agent: Fiddler
Host: localhost
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
Die Nachricht an Hash, um die Signatur zu erhalten:
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
Beispiel für eine POST-Anfrage mit Abfragezeichenfolge (Signatur unten ist nicht korrekt, nur ein Beispiel)
POST /webapi.hmac/api/values?key2=value2
User-Agent: Fiddler
Host: localhost
Content-Type: application/x-www-form-urlencoded
Timestamp: Thursday, August 02, 2012 3:30:32 PM
Authentication: cuongle:LohrhqqoDy6PhLrHAXi7dUVACyJZilQtlDzNbLqzXlw=
key1=value1&key3=value3
Die Nachricht an Hash, um die Signatur zu erhalten
GET\n
Thursday, August 02, 2012 3:30:32 PM\n
/webapi.hmac/api/values\n
key1=value1&key2=value2&key3=value3
Bitte beachten Sie, dass Formulardaten und Abfragezeichenfolge in der richtigen Reihenfolge sein sollten, damit der Code auf dem Server Abfragezeichenfolgen und Formulardaten erhält, um die richtige Nachricht zu erstellen.
Wenn eine HTTP-Anforderung an den Server gesendet wird, wird ein Authentifizierungsaktionsfilter implementiert, um die Anforderung zum Abrufen von Informationen zu analysieren: HTTP-Verb, Zeitstempel, URL, Formulardaten und Abfragezeichenfolge, basierend auf diesen, um eine Signatur (Verwendung von hmac-Hash) mit dem Geheimnis zu erstellen Schlüssel (Hash-Passwort) auf dem Server.
Der geheime Schlüssel wird aus der Datenbank mit dem Benutzernamen auf der Anfrage abgerufen.
Anschließend vergleicht der Servercode die Signatur auf der Anforderung mit der erstellten Signatur. Wenn gleich, wird die Authentifizierung übergeben, andernfalls ist sie fehlgeschlagen.
Der Code zum Erstellen der Signatur:
private static string ComputeHash(string hashedPassword, string message)
{
var key = Encoding.UTF8.GetBytes(hashedPassword.ToUpper());
string hashString;
using (var hmac = new HMACSHA256(key))
{
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
hashString = Convert.ToBase64String(hash);
}
return hashString;
}
Wie kann man einen Wiederholungsangriff verhindern?
Fügen Sie eine Einschränkung für den Zeitstempel hinzu, z. B.:
servertime - X minutes|seconds <= timestamp <= servertime + X minutes|seconds
(Servertime: Zeitpunkt der Anforderung an den Server)
Und zwischenspeichern Sie die Signatur der Anforderung im Speicher (verwenden Sie MemoryCache, sollte im Zeitlimit bleiben). Wenn die nächste Anfrage dieselbe Signatur wie die vorherige Anfrage hat, wird sie abgelehnt.
Der Demo-Code lautet wie folgt:
https://github.com/cuongle/Hmac.WebApi
Ich würde vorschlagen, zuerst mit den einfachsten Lösungen zu beginnen - vielleicht reicht in Ihrem Szenario eine einfache HTTP-Basisauthentifizierung + HTTPS aus.
Wenn nicht (zum Beispiel können Sie https nicht verwenden oder benötigen eine komplexere Schlüsselverwaltung), können Sie sich HMAC-basierte Lösungen ansehen, wie von anderen vorgeschlagen. Ein gutes Beispiel für eine solche API wäre Amazon S3 ( http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html ).
Ich habe einen Blogbeitrag über die HMAC-basierte Authentifizierung in der ASP.NET-Web-API geschrieben. Es werden sowohl der Web-API-Dienst als auch der Web-API-Client erläutert, und der Code ist auf bitbucket verfügbar. http://www.piotrwalat.net/hmac-authentication-in-asp-net-web-api/
Hier ist ein Beitrag über die Standardauthentifizierung in der Web-API: http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/
Denken Sie daran, dass Sie höchstwahrscheinlich auch für die Bereitstellung von Client-Bibliotheken verantwortlich sind, wenn Sie eine API für Dritte bereitstellen. Die Standardauthentifizierung hat hier einen erheblichen Vorteil, da sie auf den meisten sofort einsatzbereiten Programmierplattformen unterstützt wird. HMAC hingegen ist nicht so standardisiert und erfordert eine benutzerdefinierte Implementierung. Diese sollten relativ einfach sein, aber dennoch Arbeit erfordern.
PS. Es besteht auch die Möglichkeit, HTTPS + -Zertifikate zu verwenden. http://www.piotrwalat.net/client-certificate-authentication-in-asp-net-web-api-and-windows-store-apps/
quelle
Haben Sie DevDefined.OAuth ausprobiert?
Ich habe es verwendet, um mein WebApi mit 2-Legged OAuth zu sichern. Ich habe es auch erfolgreich mit PHP-Clients getestet.
Mit dieser Bibliothek können Sie ganz einfach Unterstützung für OAuth hinzufügen. So können Sie den Anbieter für die ASP.NET MVC-Web-API implementieren:
1) Holen Sie sich den Quellcode von DevDefined.OAuth: https://github.com/bittercoder/DevDefined.OAuth - die neueste Version ermöglicht
OAuthContextBuilder
Erweiterbarkeit.2) Erstellen Sie die Bibliothek und verweisen Sie in Ihrem Web-API-Projekt darauf.
3) Erstellen Sie einen benutzerdefinierten Kontext-Builder, um das Erstellen eines Kontexts aus folgenden Funktionen zu unterstützen
HttpRequestMessage
:4) Verwenden Sie dieses Tutorial zum Erstellen eines OAuth-Anbieters: http://code.google.com/p/devdefined-tools/wiki/OAuthProvider . Im letzten Schritt (Beispiel für den Zugriff auf geschützte Ressourcen) können Sie diesen Code in Ihrem
AuthorizationFilterAttribute
Attribut verwenden:Ich habe meinen eigenen Provider implementiert, daher habe ich den obigen Code nicht getestet (außer natürlich den,
WebApiOAuthContextBuilder
den ich in meinem Provider verwende), aber er sollte gut funktionieren.quelle
Die Web-API hat ein Attribut eingeführt
[Authorize]
, um die Sicherheit zu gewährleisten. Dies kann global eingestellt werden (global.asx)Oder pro Controller:
Natürlich kann Ihre Art der Authentifizierung variieren und Sie möchten möglicherweise Ihre eigene Authentifizierung durchführen. In diesem Fall kann es hilfreich sein, von Authorizate Attribute zu erben und es zu erweitern, um Ihren Anforderungen zu entsprechen:
Und in Ihrem Controller:
Hier ist ein Link zu anderen benutzerdefinierten Implementierungen für WebApi-Berechtigungen:
http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-membership-provider/
quelle
AuthorizeAttribute
, da es zwei verschiedene Klassen mit demselben Namen in verschiedenen Namespaces gibt: 1. System.Web.Mvc.AuthorizeAttribute -> für MVC-Controller 2. System.Web.Http.AuthorizeAttribute -> für WebApi.Wenn Sie Ihre API von Server zu Server sichern möchten (keine Umleitung zur Website für die zweibeinige Authentifizierung). Sie können sich das OAuth2 Client Credentials Grant-Protokoll ansehen.
https://dev.twitter.com/docs/auth/application-only-auth
Ich habe eine Bibliothek entwickelt, mit der Sie diese Art von Unterstützung ganz einfach zu Ihrer WebAPI hinzufügen können. Sie können es als NuGet-Paket installieren:
https://nuget.org/packages/OAuth2ClientCredentialsGrant/1.0.0.0
Die Bibliothek zielt auf .NET Framework 4.5 ab.
Sobald Sie das Paket zu Ihrem Projekt hinzugefügt haben, wird eine Readme-Datei im Stammverzeichnis Ihres Projekts erstellt. In dieser Readme-Datei können Sie sehen, wie Sie dieses Paket konfigurieren / verwenden.
Prost!
quelle
In Fortsetzung der Antwort von @ Cuong Le wäre mein Ansatz, einen Wiederholungsangriff zu verhindern
// Verschlüsseln Sie die Unix-Zeit auf Clientseite mit dem freigegebenen privaten Schlüssel (oder dem Kennwort des Benutzers).
// Sende es als Teil des Anforderungsheaders an den Server (WEB API)
// Entschlüsseln Sie die Unix-Zeit am Server (WEB-API) mit dem freigegebenen privaten Schlüssel (oder dem Kennwort des Benutzers).
// Überprüfen Sie den Zeitunterschied zwischen der Unix-Zeit des Clients und der Unix-Zeit des Servers. Er sollte nicht größer als x Sekunden sein
// Wenn Benutzer-ID / Hash-Passwort korrekt sind und die entschlüsselte UnixTime innerhalb von x Sekunden der Serverzeit liegt, handelt es sich um eine gültige Anforderung
quelle