.NET Core Identity Server 4-Authentifizierung VS Identitätsauthentifizierung

89

Ich versuche zu verstehen, wie die Authentifizierung in ASP.NET Core richtig durchgeführt wird. Ich habe mir mehrere Ressourcen angesehen (von denen die meisten veraltet sind).

Einige Benutzer bieten alternative Lösungen an, die angeben, eine Cloud-basierte Lösung wie Azure AD zu verwenden oder IdentityServer4 zu verwenden und meinen eigenen Tokenserver zu hosten.

In der älteren Version von .Net besteht eine der einfacheren Formen der Authentifizierung darin, ein benutzerdefiniertes Prinzip zu erstellen und zusätzliche Authentifizierungsbenutzerdaten darin zu speichern.

public interface ICustomPrincipal : System.Security.Principal.IPrincipal
{
    string FirstName { get; set; }

    string LastName { get; set; }
}

public class CustomPrincipal : ICustomPrincipal
{
    public IIdentity Identity { get; private set; }

    public CustomPrincipal(string username)
    {
        this.Identity = new GenericIdentity(username);
    }

    public bool IsInRole(string role)
    {
        return Identity != null && Identity.IsAuthenticated && 
           !string.IsNullOrWhiteSpace(role) && Roles.IsUserInRole(Identity.Name, role);
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return FirstName + " " + LastName; } }
}

public class CustomPrincipalSerializedModel
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

Dann würden Sie Ihre Daten in ein Cookie serialisieren und an den Client zurückgeben.

public void CreateAuthenticationTicket(string username) {     

    var authUser = Repository.Find(u => u.Username == username);  
    CustomPrincipalSerializedModel serializeModel = new CustomPrincipalSerializedModel();

    serializeModel.FirstName = authUser.FirstName;
    serializeModel.LastName = authUser.LastName;
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    string userData = serializer.Serialize(serializeModel);

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
    1,username,DateTime.Now,DateTime.Now.AddHours(8),false,userData);
    string encTicket = FormsAuthentication.Encrypt(authTicket);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(faCookie);
}

Meine Fragen sind:

  1. Wie kann ich mich ähnlich wie in früheren Versionen von .Net authentifizieren? Funktioniert die alte Methode immer noch oder gibt es eine neuere Version?

  2. Was sind die Vor- und Nachteile der Verwendung Ihrer eigenen Token-Server-Verse, um Ihr eigenes benutzerdefiniertes Prinzip zu erstellen?

  3. Wenn Sie eine Cloud-basierte Lösung oder einen separaten Token-Server verwenden, wie würden Sie dies in Ihre aktuelle Anwendung integrieren? Würde ich weiterhin eine Benutzertabelle in meiner Anwendung benötigen, wie würden Sie die beiden verknüpfen?

  4. Da es so viele verschiedene Lösungen gibt, kann ich eine Unternehmensanwendung erstellen, um die Anmeldung über Google Mail / Facebook zu ermöglichen und gleichzeitig auf andere SSOs zu erweitern

  5. Was sind einige einfache Implementierungen dieser Technologien?
Johnny 5
quelle
Diese Frage ist zu weit gefasst und auch sehr meinungsbasiert. Es gibt entweder zu viele mögliche Antworten, oder gute Antworten wären für dieses Format zu lang. Bitte fügen Sie Details hinzu, um den Antwortsatz einzugrenzen oder ein Problem zu isolieren, das in einigen Absätzen beantwortet werden kann. Viele gute Fragen erzeugen einen gewissen Grad an Meinung, der auf Expertenerfahrung basiert. Die Antworten auf diese Frage basieren jedoch fast ausschließlich auf Meinungen und nicht auf Fakten, Referenzen oder spezifischem Fachwissen.
Nkosi
@Nkosi Entschuldigung, der Satz war so. Ich habe dies klargestellt, um genauer zu sein
Johnny 5.

Antworten:

141

TL; DR

IdentityServer = Token-Verschlüsselungs- und Validierungsdienste über OAuth 2.0 / OpenId-Connect

ASP.NET Identity = aktuelle Identity Management-Strategie in ASP.NET

Wie kann ich mich ähnlich wie in früheren Versionen von .Net authentifizieren? Funktioniert die alte Methode immer noch oder gibt es eine neuere Version?

Ich sehe keinen Grund, warum Sie den alten Weg in ASP.NET Core nicht erreichen konnten, aber im Allgemeinen wurde diese Strategie durch ASP.NET Identity ersetzt, und ASP.NET Identity ist in ASP.NET Core lebendig und gut.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

ASP.NET Identity verwendet einen Sicherungsspeicher wie SQL Server, um Benutzerinformationen wie Benutzername, Kennwort (Hash), E-Mail, Telefon zu speichern, und kann problemlos erweitert werden, um Vorname, Nachname oder was auch immer zu speichern. Es gibt also wirklich keinen Grund, Benutzerinformationen in ein Cookie zu verschlüsseln und vom Client zum Server hin und her zu übertragen. Es unterstützt Begriffe wie Benutzeransprüche, Benutzertoken, Benutzerrollen und externe Anmeldungen. Hier sind die Entitäten in ASP.NET Identity:

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins (zum Verknüpfen externer Identitätsanbieter wie Google, AAD)
  • AspNetUserTokens (zum Speichern von Dingen wie access_tokens und refresh_tokens, die vom Benutzer angehäuft wurden)

Was sind die Vor- und Nachteile der Verwendung Ihrer eigenen Token-Server-Verse, um Ihr eigenes benutzerdefiniertes Prinzip zu erstellen?

Ein Tokenserver wäre ein System, das eine einfache Datenstruktur generiert, die Autorisierungs- und / oder Authentifizierungsinformationen enthält. Für die Autorisierung wird normalerweise ein Token mit dem Namen access_token verwendet . Dies wären sozusagen die "Schlüssel zum Haus", die Sie durch die Tür in die Residenz einer geschützten Ressource, normalerweise einer Web-API, führen. Für die Authentifizierung id_tokenenthält die eine eindeutige Kennung für einen Benutzer / eine Person. Während es üblich ist, eine solche Kennung in das access_token einzufügen, gibt es jetzt ein dediziertes Protokoll dafür: OpenID-Connect .

Der Grund für Ihren eigenen Security Token Service (STS) besteht darin, Ihre Informationsressourcen über Kryptografie zu schützen und zu steuern, welche Clients (Anwendungen) auf diese Ressourcen zugreifen können. Darüber hinaus sind die Standards für Identitätskontrollen jetzt in den OpenID-Connect-Spezifikationen enthalten. IdentityServer ist ein Beispiel für einen OAuth 2.0-Autorisierungsserver in Kombination mit einem OpenID-Connect-Authentifizierungsserver.

Dies ist jedoch nicht erforderlich, wenn Sie nur eine Benutzertabelle in Ihrer Anwendung haben möchten. Sie benötigen keinen Tokenserver - verwenden Sie einfach ASP.NET Identity. ASP.NET Identity ordnet Ihren Benutzer einem ClaimsIdentity- Objekt auf dem Server zu, ohne dass eine benutzerdefinierte IPrincipal-Klasse erforderlich ist.

Wenn Sie eine Cloud-basierte Lösung oder einen separaten Token-Server verwenden, wie würden Sie dies in Ihre aktuelle Anwendung integrieren? Würde ich weiterhin eine Benutzertabelle in meiner Anwendung benötigen, wie würden Sie die beiden verknüpfen?

In diesen Tutorials finden Sie Informationen zur Integration separater Identitätslösungen in eine Anwendung: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core

Sie benötigen mindestens eine zweispaltige Tabelle, in der der Benutzername der Benutzerkennung des externen Anbieters zugeordnet wird. Dies ist, was die AspNetUserLogins-Tabelle in ASP.NET Identity tut. Die Zeilen in dieser Tabelle hängen jedoch davon ab, ob es sich um einen Benutzerdatensatz in AspNetUsers handelt.

ASP.NET Identity unterstützt externe Anbieter wie Google, Microsoft, Facebook, alle OpenID-Connect-Anbieter und Azure AD. (Google und Microsoft haben das OpenID-Connect-Protokoll bereits implementiert, sodass Sie auch keine benutzerdefinierten Integrationspakete wie dieses benötigen .) Außerdem ist ADFS unter ASP.NET Core Identity noch nicht verfügbar.

In diesem Dokument finden Sie Informationen zu externen Anbietern in ASP.NET Identity:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/

Da es so viele verschiedene Lösungen gibt, kann ich eine Unternehmensanwendung erstellen, um die Anmeldung über Google Mail / Facebook zu ermöglichen und gleichzeitig auf andere SSOs zu erweitern

Wie oben erläutert, führt ASP.NET Identity dies bereits aus. Es ist ziemlich einfach, eine Tabelle "Externe Anbieter" zu erstellen, und Daten steuern Ihren externen Anmeldevorgang. Wenn also ein neues "SSO" hinzukommt, fügen Sie einfach eine neue Zeile mit den Eigenschaften wie der URL des Anbieters, der Client-ID und dem Geheimnis hinzu, das sie Ihnen geben. In ASP.NET Identity ist die Benutzeroberfläche bereits in Visual Studio-Vorlagen integriert. Coolere Schaltflächen finden Sie unter Soziale Anmeldung .

Zusammenfassung

Wenn Sie nur eine Benutzertabelle mit Kennwortanmeldefunktionen und einem Benutzerprofil benötigen, ist ASP.NET Identity perfekt. Keine Notwendigkeit, externe Behörden einzubeziehen. Wenn jedoch viele Anwendungen auf viele APIs zugreifen müssen, ist eine unabhängige Behörde zum Sichern und Validieren von Identitäts- und Zugriffstoken sinnvoll. IdentityServer passt gut zu Openiddict-Core oder Auth0 für eine Cloud-Lösung.

Ich entschuldige mich dafür, dass dies nicht ins Schwarze trifft oder zu einleitend ist. Bitte zögern Sie nicht zu interagieren, um zu dem Ziel zu gelangen, das Sie suchen.

Nachtrag: Cookie-Authentifizierung

Führen Sie die folgenden Schritte aus, um die Bare-Bones-Authentifizierung mit Cookies durchzuführen. Meines Wissens wird ein benutzerdefinierter Anspruchsprinzipal jedoch nicht unterstützt. Verwenden Sie die Anspruchsliste des ClaimPrincipalObjekts, um den gleichen Effekt zu erzielen .

Erstellen Sie eine neue ASP.NET Core 1.1-Webanwendung in Visual Studio 2015/2017, indem Sie im Dialogfeld "Keine Authentifizierung" auswählen. Dann Paket hinzufügen:

Microsoft.AspNetCore.Authentication.Cookies

Unter der vorhandenen ConfigureMethode Startup.cs(vorher app.UseMvc):

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "MyCookieMiddlewareInstance",
    LoginPath = new PathString("/Controller/Login/"),
    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});

Erstellen Sie dann eine Anmelde-Benutzeroberfläche und senden Sie das HTML-Formular an eine Aktionsmethode wie die folgende:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(String username, String password, String returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // check user's password hash in database
        // retrieve user info

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim("FirstName", "Alice"),
            new Claim("LastName", "Smith")
        };

        var identity = new ClaimsIdentity(claims, "Password");

        var principal = new ClaimsPrincipal(identity);

        await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);

        return RedirectToLocal(returnUrl);
    }

    ModelState.AddModelError(String.Empty, "Invalid login attempt.");

    return View();
}

Das HttpContext.User-Objekt sollte Ihre benutzerdefinierten Ansprüche haben und die List-Auflistung des ClaimPrincipal leicht abrufbar sein.

Ich hoffe, dies reicht aus, da eine vollständige Lösung / ein Projekt für einen StackOverflow-Beitrag ein bisschen viel zu sein scheint.

travis.js
quelle
1
Bitte zeigen Sie ein Beispiel für die Implementierung der Authentifizierung in Core
Johnny 5
2
Die ASP.NET Core-Dokumente zeigen das kanonische Beispiel: docs.microsoft.com/en-us/aspnet/core/security/authentication/… .
travis.js
Wenn Sie können, veröffentlichen Sie bitte ein einfaches Beispiel für die Authentifizierung. Ohne einen Link, über den die Benutzer auf eine Ressource zugreifen können, werde ich eine ausführliche Antwort zum Einrichten von IdentityServer4
Johnny, 5.
Enthält dies für IdentityServer das gesuchte Beispiel: identityserver4.readthedocs.io/en/dev/quickstarts/… ?
travis.js
Hat dies für ASP.NET Identity nicht das Beispiel oder ist das, was Sie sagen, veraltet? docs.microsoft.com/en-us/aspnet/core/security/authentication/…
travis.js
11

TL; DR

Ich würde wirklich gerne einen vollständigen Beitrag zur ordnungsgemäßen Implementierung von IdentityServer4 anzeigen, aber ich habe versucht, den gesamten Text einzupassen, aber es war jenseits der Grenzen dessen, was StackOverflow akzeptiert. Stattdessen werde ich einige Tipps und Dinge korrigieren, die ich gelernt habe.

Was sind die Vorteile der Verwendung eines Tokenservers gegenüber der ASP-Identität?

Ein Token-Server hat viele Vorteile, ist aber nicht für jeden geeignet. Wenn Sie eine unternehmensähnliche Lösung implementieren, bei der sich mehrere Clients anmelden können, ist der Token-Server die beste Wahl. Wenn Sie jedoch nur eine einfache Website erstellen, die externe Anmeldungen unterstützen möchte, können Sie mit ASP Identity und ASP Identity davonkommen etwas Middleware.

Identity Server 4 Tipps

Identity Server 4 ist im Vergleich zu vielen anderen Frameworks, die ich gesehen habe, ziemlich gut dokumentiert, aber es ist schwierig, von vorne zu beginnen und das ganze Bild zu sehen.

Mein erster Fehler war der Versuch, OAuth als Authentifizierung zu verwenden. Ja, es gibt Möglichkeiten, dies zu tun, aber OAuth dient zur Autorisierung und nicht zur Authentifizierung, wenn Sie die Authentifizierung mit OpenIdConnect (OIDC) durchführen möchten.

In meinem Fall wollte ich einen Javascript-Client erstellen, der eine Verbindung zu einer Web-API herstellt. Ich habe mir viele Lösungen angesehen, aber anfangs habe ich versucht, über das Webapi die Authentifizierung gegen Identity Server aufzurufen, und dieses Token sollte nur bestehen bleiben, da es gegen den Server verifiziert wurde. Dieser Fluss kann möglicherweise funktionieren, weist jedoch viele Mängel auf.

Als ich schließlich den richtigen Ablauf fand, als ich das Javascript Client-Beispiel fand, bekam ich den richtigen Ablauf. Ihr Client meldet sich an und legt ein Token fest. Anschließend muss Ihre Web-API den OIdc-Client verwenden, der überprüft, ob Sie ein Zugriffstoken für IdentityServer sind.

Verbindung zu Geschäften und Migrationen herstellen Ich hatte anfangs viele Missverständnisse mit Migrationen. Ich hatte den Eindruck, dass beim Ausführen einer Migration das SQL intern aus der DLL generiert wurde, anstatt den konfigurierten Kontext zu verwenden, um herauszufinden, wie das SQL erstellt wird.

Es gibt zwei Syntaxen für Migrationen. Es ist wichtig zu wissen, welche von Ihrem Computer verwendet wird:

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

Ich denke, der Parameter nach der Migration ist der Name, warum Sie einen Namen benötigen. Ich bin mir nicht sicher, ob dies ApplicationDbContextein Code-First-DbContext ist, in dem Sie erstellen möchten.

Migrationen verwenden eine gewisse automatische Magie, um herauszufinden, ob Sie eine Verbindungszeichenfolge aus der Konfiguration Ihres Starts haben. Ich habe nur angenommen, dass eine Verbindung aus dem Server-Explorer verwendet wurde.

Wenn Sie mehrere Projekte haben, stellen Sie sicher, dass Sie das Projekt mit dem ApplicationDbContext als Start festgelegt haben.

Es gibt viele bewegliche Teile beim Implementieren von Autorisierung und Authentifizierung. Hoffentlich hilft dieser Beitrag jemandem. Der einfachste Weg, um Authentifizierungen vollständig zu verstehen, besteht darin, ihre Beispiele auseinander zu nehmen, um alles zusammenzusetzen und sicherzustellen, dass Sie die Dokumentation lesen

Johnny 5
quelle
Der Name nach der Add-Migration ist der Verweis auf Ihre Version / Änderungen, die Sie vorgenommen haben. Der gleiche Name wird verwendet, um das Migrationsskript Up & Down hinzuzufügen.
Jay
@ Jay Danke für diese Klarstellung
Johnny 5
Der Konfigurationsdatenbankkontext des Identitätsservers ist immer noch nicht so gut wie der von IdentityDbContext. Das Erstellen einer benutzerdefinierten Implementierung ist ein Problem. Identityserver 4 scheint jetzt nicht sehr aktiv zu sein, um nach .core-Updates neue Updates zu veröffentlichen.
Jay
3

ASP.NET-Identität - Dies ist der Build zur Authentifizierung Ihrer Anwendung, unabhängig davon, ob es sich um eine Träger- oder eine Basisauthentifizierung handelt. Sie gibt uns den vorgefertigten Code, um die Benutzerregistrierung durchzuführen, sich anzumelden, das Kennwort zu ändern und alles.

Betrachten wir nun, wir haben 10 verschiedene Anwendungen und es ist nicht möglich, in allen 10 Apps dasselbe zu tun. diese sehr fragile und sehr schlechte Praxis.

Um dieses Problem zu beheben, können wir unsere Authentifizierung und Autorisierung zentralisieren, sodass jede Änderung nicht alle unsere 10 Apps betrifft.

Der Identitätsserver bietet Ihnen die Möglichkeit, dasselbe zu tun. Wir können eine Beispiel-Web-App erstellen, die gerade als Identitätsdienst verwendet wurde. Sie validiert Ihren Benutzer und stellt ein JWT-Zugriffstoken bereit.

Amol Aher
quelle
2

Ich habe immer die integrierte Autorisierung / Authentifizierung für ASP.NET-Identität (und zuvor Mitgliedschaft) verwendet. Ich habe kürzlich Auth0 ( https://auth0.com ) implementiert und empfehle dies als einen anderen Versuch.

Mark Redman
quelle
Das Auth0 .net-Kernbeispiel ist ziemlich schnell und einfach zu implementieren, aber die Verwendung aller Funktionen erfordert einiges an Arbeit. Ich habe Auth0 implementiert, das viele Funktionen integriert, und es funktioniert gut, aber wie all diese Dinge gibt es auch seine Anforderungen ein bisschen Arbeit und etwas Frust.
Mark Redman
Wenn eine Authentifizierung gut funktioniert, werde ich eine ausführliche Antwort darauf veröffentlichen. Ich habe letzte Woche gerade an der Authentifizierung gearbeitet. Und nichts ist so eng wie es sein sollte
Johnny 5.
0

Soziale Anmeldungen sind mit Identity nicht schwer zu implementieren, aber es sind einige anfängliche Einstellungen erforderlich, und manchmal sind die Schritte, die Sie online in den Dokumenten finden, nicht identisch. In der Regel finden Sie Hilfe dazu im Entwicklerbereich der Plattform, die Sie einrichten möchten die sozialen Logins für. Identität ist der Ersatz für die alte Mitgliedschaftsfunktionalität, die in älteren Versionen des .net-Frameworks enthalten ist. Was mich überrascht hat, ist, dass Edge-Anwendungsfälle wie das Übergeben eines JWT-Tokens, das Sie bereits an eine Web-API haben, in den Online-Beispielen nirgends behandelt werden Ich bin mir sicher, dass Sie selbst im Pluralsight keine eigene Token-Berechtigung benötigen, aber ich habe kein einziges Beispiel dafür gefunden, wie Daten in einem Get oder Post übergeben werden, der sich nicht mit einem selbst gehosteten Server befasst.

webdev8183
quelle
Vielleicht sind Sie nach diesem docs.identityserver.io/en/release/quickstarts/…
Jay