wake-up-neo.net

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

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

Einige bieten alternative Lösungen an, die die Verwendung einer cloudbasierten Lösung wie Azure AD oder die Verwendung von IdentityServer4 und das Hosten eines eigenen Tokenservers vorsehen.

In einer ä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 einem Cookie serialisieren und an den Client zurücksenden.

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 authentifizieren, ähnlich wie in früheren Versionen von .Net? Funktioniert die alte Methode noch oder gibt es eine neuere Version?.

  2. Was sind die Vor- und Nachteile, wenn Sie Ihren eigenen Tokenserver verwenden und Ihr eigenes benutzerdefiniertes Prinzip erstellen?

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

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

  5. Was sind einige einfache Implementierungen dieser Technologien?
64
johnny 5

TL; DR

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

ASP.NET-Identität = Aktuelle Identitätsverwaltungsstrategie in ASP.NET

Wie kann ich mich authentifizieren, ähnlich wie in der vorherigen Version von .Net? Funktioniert die alte Methode noch oder gibt es eine neuere Version?

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

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 auf Vorname, Nachname oder was auch immer erweitert werden. Es gibt also wirklich keinen Grund, Benutzerinformationen in ein Cookie zu verschlüsseln und sie vom Client zum Server hin und her zu übertragen. Es werden Begriffe wie Benutzeransprüche, Benutzertoken, Benutzerrollen und externe Anmeldungen unterstützt. Hier sind die Entitäten in ASP.NET Identity:

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins (zur Verknüpfung von externen Identitätsanbietern wie Google, AAD)
  • AspNetUserTokens (zum Speichern von vom Benutzer gesammelten access_tokens und refresh_tokens)

Was sind die Vor- und Nachteile, wenn Sie Ihren eigenen Tokenserver verwenden und Ihr eigenes benutzerdefiniertes Prinzip erstellen?

Ein Tokenserver ist 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äre sozusagen der "Schlüssel zum Haus", der Sie durch die Tür und in die Residenz einer geschützten Ressource, normalerweise einer Web-API, führt. Zur Authentifizierung wird das id_token enthält eine eindeutige Kennung für einen Benutzer/eine Person. Während es üblich ist, einen solchen Bezeichner in das access_token einzufügen, gibt es jetzt ein spezielles Protokoll, um dies zu tun: OpenID-Connect .

Der Grund für einen 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 existieren die Standards für Identitätskontrollen jetzt in OpenID-Connect-Spezifikationen. IdentityServer ist ein Beispiel für einen OAuth= 2.0 Authorization Server in Kombination mit einem OpenID-Connect-Authentifizierungsserver.

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

Wenn Sie eine Cloud-basierte Lösung oder einen separaten Tokenserver verwenden, wie würden Sie dies in Ihre aktuelle Anwendung integrieren? Würde ich dennoch 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.htmlhttps://auth0.com/ docs/quickstart/webapp/aspnet-core

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

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

In diesem Dokument finden Sie Informationen zu den ersten Schritten mit 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, wie kann ich eine Unternehmensanwendung erstellen, um die Anmeldung über Gmail/Facebook zuzulassen 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 die Daten steuern Ihren externen Anmeldeprozess. Wenn 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 erhalten. In ASP.NET Identity ist die Benutzeroberfläche bereits in Visual Studio-Vorlagen integriert. Für coolere Schaltflächen siehe Social Login .

Zusammenfassung

Wenn Sie nur eine Benutzertabelle mit Kennwortanmeldefunktionen und ein 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 zur Sicherung und Validierung von Identitäts- und Zugriffstoken sinnvoll. IdentityServer eignet sich gut, oder lesen Sie openiddict-core oder Auth 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 Prinzip für benutzerdefinierte Ansprüche jedoch nicht unterstützt. Um den gleichen Effekt zu erzielen, verwenden Sie die Anspruchsliste des Objekts ClaimPrincipal.

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

Microsoft.AspNetCore.Authentication.Cookies

Unter der Configure Methode in Startup.cs platziere dies (vor app.UseMvc):

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

Erstellen Sie dann eine Login-Benutzeroberfläche und veröffentlichen Sie das HTML-Formular in einer Aktionsmethode wie der folgenden:

[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 enthalten und die List-Auflistung des ClaimPrincipal kann problemlos abgerufen werden.

Ich hoffe, dass dies ausreicht, da eine vollständige Lösung/ein vollständiges Projekt für einen StackOverflow-Beitrag ein wenig viel zu sein scheint.

106
travis.js

TL; DR

Ich würde wirklich gerne einen vollständigen Beitrag dazu zeigen, wie IdentityServer4 richtig implementiert wird, 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 Tokenserver hat viele Vorteile, ist aber nicht für jedermann geeignet. Wenn Sie eine unternehmensähnliche Lösung implementieren, bei der sich mehrere Clients anmelden können, ist der Tokenserver die beste Wahl. Wenn Sie jedoch nur eine einfache Website erstellen, die externe Anmeldungen unterstützt, können Sie mit ASP Identität und Middleware.

Tipps zu Identity Server 4

Identity Server 4 ist im Vergleich zu vielen anderen Frameworks, die ich gesehen habe, ziemlich gut dokumentiert, aber es ist schwierig, bei Null anzufangen 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 der Autorisierung und nicht der Authentifizierung, wenn Sie OpenIdConnect (OIDC) zur Authentifizierung verwenden 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, das Webapi zum Aufrufen der Authentifizierung gegen Identity Server zu verwenden, und wollte nur, dass dieses Token bestehen bleibt, da es gegen den Server verifiziert wurde. Dieser Fluss kann möglicherweise funktionieren, hat aber viele Mängel.

Endlich der richtige Ablauf Als ich das Javascript-Client-Beispiel fand, bekam ich den richtigen Ablauf. Ihr Client meldet sich an und legt ein Token fest. Dann muss Ihre Web-API den OIdc-Client konsumieren, der überprüft, ob Sie ein Zugriffstoken für IdentityServer haben.

Verbinden mit Stores und Migrationen Anfangs hatte ich viele Missverständnisse mit Migrationen. Ich hatte den Eindruck, dass beim Ausführen einer Migration die SQL intern aus der DLL generiert wurde, anstatt dass Sie den konfigurierten Kontext verwenden, um herauszufinden, wie die SQL erstellt wird.

Es gibt zwei Syntax für Migrationen:

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 brauchen, ich bin nicht sicher, das ApplicationDbContext ist ein Code-First DbContext, in dem Sie erstellen möchten.

Migrationen verwenden etwas Auto-Magic, um herauszufinden, ob Sie eine Verbindungszeichenfolge gemäß der Konfiguration Ihres Startvorgangs haben. Ich bin lediglich davon ausgegangen, dass eine Verbindung vom Server-Explorer verwendet wurde.

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

Beim Implementieren der Autorisierung und Authentifizierung gibt es eine Menge beweglicher Teile. Hoffentlich hilft dieser Beitrag jemandem. Der einfachste Weg, um die Authentifizierungen vollständig zu verstehen, besteht darin, die Beispiele herauszusuchen, um alles zusammenzusetzen und sicherzustellen, dass Sie die Dokumentation lesen

8
johnny 5

Ich habe immer die in ASP.NET Identity (und zuvor Membership) integrierte Autorisierung/Authentifizierung verwendet. Ich habe Auth0 kürzlich implementiert ( https://auth0.com ) und empfehle dies als etwas anderes, um es zu versuchen.

1
Mark Redman

ASP.NET-Identität - Dies ist die integrierte Methode zur Authentifizierung Ihrer Anwendung, unabhängig davon, ob es sich um eine Bearer- oder eine Basisauthentifizierung handelt. Sie gibt uns den vorgefertigten Code für die Benutzerregistrierung, die Anmeldung, die Änderung des Kennworts und alles.

Nehmen wir an, 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. Wenn sich dies ändert, wirken sich dies nicht auf alle unsere 10 Apps aus.

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

0
Amol Aher

Soziale Logins sind mit Identity nicht schwer zu implementieren, es sind jedoch einige anfängliche Einstellungen erforderlich, und manchmal sind die Schritte, die Sie online in den Dokumenten finden, nicht identisch. In der Regel finden Sie dazu Hilfe im Abschnitt für Entwickler der Plattform, die Sie einrichten möchten die sozialen Logins für. Identität ist der Ersatz der alten Mitgliedschaftsfunktionalität, die in älteren Versionen des .net-Frameworks zu finden ist. Überraschenderweise werden Edge-Anwendungsfälle wie die Übergabe eines JWT-Tokens, das Sie bereits an eine Web-API übergeben haben, in den Online-Beispielen nirgendwo behandelt Ich bin mir sicher, dass Sie dazu 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.

0
webdev8183