Authentifizierungsszenarien mit ASP.NET Identity ASP.NET 5

ASP.NET Identity
Kommentare

Bei der Entwicklung nahezu jeder Webanwendung gibt es die Aufgaben, Benutzer zu authentifizieren und Benutzerkonten zu verwalten. ASP.NET Identity automatisiert diese immer wiederkehrenden Aufgaben. Dieser Artikel zeigt, wie ASP.NET Identity in der kommenden Version von ASP.NET genutzt werden kann.

ASP.NET Identity unterstützt bei der Verwaltung von Benutzerkonten sowie bei der Umsetzung einer Zwei-Faktor-Authentifizierung und bietet auch die Möglichkeit, E-Mail-Adressen und Telefonnummern über Tokens zu bestätigen. Darüber hinaus kann ASP.NET Identity Benutzerkonten nach mehreren fehlgeschlagenen Log-in-Versuchen sperren und bei Umsetzung einer Two Factor Authentication unterstützen.

Middleware-Komponenten

Wie auch schon bei der Nutzung von OWIN/Katana in ASP.NET 4 sieht ASP.NET 5 eine Pipeline, bestehend aus so genannten Middleware-Komponenten, vor (Abb. 1). Eine Serverkomponente kümmert sich um die Kommunikation mit der Außenwelt und delegiert sämtliche Anfragen an diese Pipeline. Die Komponenten in der Pipeline bearbeiten der Reihe nach die Anfrage. Sie kümmern sich unter anderem um die Authentifizierung des Benutzers oder um die Aktivierung eines Frameworks wie MVC 6. Nach verrichteter Arbeit kann jede Komponente die aktuelle Anfrage abbrechen oder an die nächste Komponente delegieren. Bricht keine Komponente die Anfrage ab, landet die Anfrage schließlich im Anwendungscode. Die Antwort des Anwendungscodes passiert ebenfalls sämtliche Middleware-Komponenten, jedoch in umgekehrter Reihenfolge. Die Serverkomponente retourniert die aus der Pipeline erhaltene Anfrage an den Aufrufer.

Abb. 1: Pipeline bestehend aus Middleware-Komponenten

Abb. 1: Pipeline bestehend aus Middleware-Komponenten

Im Gegensatz zur vergleichbaren Pipeline in ASP.NET 4 basiert die Pipeline in ASP.NET 5 nicht auf dem offenen Standard OWIN (Open Web Interface for .NET), stattdessen handelt es sich um eine eigene Implementierung des Produktteams. Allerdings ist diese Implementierung der aus der Welt von OWIN sehr ähnlich und sie sieht die Möglichkeit vor, über einfache Adapter OWIN-Middleware-Komponenten zu nutzen.

CookieAuthenticationMiddleware

Unter den im Lieferumfang von ASP.NET 5 enthaltenen Middleware-Komponenten befindet sich auch eine so genannte CookieAuthenticationMiddleware. Diese Komponente prüft bei jeder Anfrage, ob sie den Benutzer anhand eines vorhandenen Cookies authentifizieren kann. Gelingt das nicht, bleibt der Benutzer (vorerst) anonym. Das stellt per se kein Problem dar, zumal der Anwendungscode auch anonymen Benutzern Zugriff auf bestimmte Ressourcen bieten kann. Daneben besteht auch die Möglichkeit, dass nachgelagerte Middleware-Komponenten den Benutzer anhand anderer Kriterien authentifizieren.

Lässt eine Antwort, die die CookieAuthenticationMiddleware passiert, darauf schließen, dass der Anwendungscode dem Benutzer den Zugriff verweigert hat, leitet sie den Benutzer auf eine Log-in-Maske um. Das ist der Fall, wenn der aktuelle Statuscode den Wert 401 (Unauthorized) aufweist.

Daneben kümmert sich die CookieAuthenticationMiddleware auch um das Ausstellen von Sitzungs-Cookies für Benutzer, die der Anwendungscode erfolgreich authentifiziert hat. Dazu übergibt der Anwendungscode die nötigen Benutzerdaten an die Middleware, die diese beim Bearbeiten der Antwortnachricht berücksichtigt. Auf dieselbe Weise kann der Anwendungscode die Middleware anweisen, den Cookie wieder zu löschen, um den aktuellen Benutzer abzumelden.

ASP.NET Identity

Zum Authentifizieren und Autorisieren benötigt eine Anwendung Informationen über die Benutzer. Diese Aufgabe übernimmt die Klassenbibliothek ASP.NET Identity, die einen integralen Bestandteil von ASP.NET 5 darstellt. Standardmäßig nutzt sie Entity Framework zum Laden von Benutzerdaten aus einer Datenbank. Durch das Bereitstellen einer eigenen Datenzugriffslogik kann der Entwickler jedoch auch andere Datenspeicher einbinden.

Zu den verwalteten Entitäten gehören neben Benutzern und Gruppen auch Claims. Dabei handelt es sich vereinfacht ausgedrückt um Name/Wert-Paare, die Benutzer näher beschreiben und die beispielsweise zum Autorisieren der Benutzer genutzt werden können. Daneben sieht ASP.NET Identity pro Benutzer die Möglichkeit zur Verwaltung mehrerer externer Log-ins vor. Auf diese Weise kann die Anwendung ein Benutzerkonto mit Konten bei anderen so genannten Log-in-Providern verknüpfen. Das ermöglicht Szenarien wie „Login with Facebook“.

Neben dem Verwalten von Entitäten kümmert sich ASP.NET Identity auch um wiederkehrende Aufgaben, die bei der Arbeit mit Benutzerkonten auftreten. Dazu gehört das Validieren der einzelnen Felder von Benutzerkonten oder das Deaktivieren von Benutzerkonten nach einer bestimmten Anzahl erfolgloser Anmeldeversuche. Auch das Generieren von Tokens, die dem Benutzer zum Bestätigen seiner E-Mail-Adresse übersendet werden, übernimmt ASP.NET Identity. Dasselbe gilt für Tokens zum Bestätigen der Telefonnummer oder zum Zurücksetzen von Passwörtern. Darüber hinaus unterstützt ASP.NET Identity das Durchführen einer so genannten Two Factor Authentication. Damit ist gemeint, dass sich der Benutzer mit zwei voneinander unabhängigen Faktoren zu erkennen geben muss. Dabei kann es sich zum Beispiel um ein Passwort oder um einen Code handeln, den der Benutzer per SMS und E-Mail erhält.

Seine Dienste bietet ASP.NET Identity der Anwendung über die Klassen SignInManager und UserManager an (Abb. 2). Letztere kümmert sich um die Verwaltung von Benutzerkonten und implementiert die besprochenen Aufgaben. Erstere kümmert sich um den Brückenschlag zwischen den verwalteten Benutzerkonten und den registrieren Middleware-Komponenten. Beispielsweise nimmt der SignInManager zum Anmelden eines Benutzers einen Benutzernamen und ein Passwort entgegen. Konnte er unter Verwendung des UserManagers ein dazu passendes Benutzerkonto finden, weist er die CookieAuthenticationMiddleware an, einen Cookie für diesen Benutzer auszustellen. Zur Kommunikation mit Middleware-Komponenten stützt sich der SignInManager auf den HttpContext, der hierzu Methoden anbietet.

Abb. 2: Ausgewählte Typen in ASP.NET Identity

Abb. 2: Ausgewählte Typen in ASP.NET Identity

ASP.NET Identity registrieren

Sowohl ASP.NET Identity als auch die CookieAuthenticationMiddleware werden beim Hochfahren der Webanwendung über die Klasse Startup eingerichtet. Listing 1 zeigt das Grundgerüst dieser Klasse, die die Projektvorlage in Visual Studio einrichtet. Ihr Konstruktor initialisiert ein Configuration-Objekt, das Konfigurationsdaten aus der Datei config.json sowie aus Umgebungsvariablen anbietet. Dieses Objekt, das Startup in der Eigenschaft Configuration verwaltet, nutzt ASP.NET Identity, um die Datenbankverbindungszeichenfolge für die Benutzerdatenbank zu ermitteln.

Die Methode ConfigureServices bereitet Klassen und Objekte vor, die der Dependency-Injection-Mechanismus von ASP.NET 5 bereitstellt. Diese werden als Services bezeichnet. Die Erweiterungsmethode AddEntityFramework registriert die Services für Entity Framework, und AddSqlServer ergänzt die Services, die Entity Framework zum Zugriff auf SQL-Server-Datenbanken benötigt. Die Erweiterungsmethode AddDbContext registriert zusätzlich ein DbContext-Derivat. Im betrachteten Fall handelt es sich um einen DbContext, der Zugriff auf die von ASP.NET Identity vorgesehene Datenbank gewährt. Damit das möglich ist, muss der angegebene DbContext von der Basisklasse IdentityContext erben. Dadurch, dass an dieser Stelle IdentityContext nicht direkt, sondern eine Subklasse davon zum Einsatz kommt, kann die Anwendung eigene Erweiterungen in die Benutzerdatenbank einbringen.

Die Erweiterungsmethode AddIdentity registriert die Services für ASP.NET Identity beim Dependency-Injection-Mechanismus von ASP.NET. Als Typparameter nimmt sie die Typen jener Klassen entgegen, die einen Benutzer und eine Rolle darstellen. Um mit den Typen von ASP.NET Identity kompatibel zu sein, sind an dieser Stelle Derivate von IdentityUser und IdentityRole anzugeben. Das betrachtete Beispiel nutzt zur Darstellung von Benutzern die anwendungsbezogene Subklasse ApplicationUser, die die Projektvorlage von Visual Studio eingerichtet hat. Auf diese Weise kann die Anwendung Erweiterungen in das Datenmodell einbringen. Zur Darstellung von Rollen nutzt das Beispiel hingegen die Klasse IdentityRole direkt.

Der Aufruf der Erweiterungsmethode AddEntityFrameworkStores ergänzt die Services, die ASP.NET Identity dazu befähigen, über Entity Framework auf Benutzerkonten zuzugreifen. Über einen Typparameter nimmt sie den Typ des dazu zu nutzenden DbContext-Derivats entgegen. Dieses wurde weiter oben mit AddDbContext als Service im Dependency-Injection-Container platziert.

Weitere Services registriert der Aufruf von AddDefaultTokenProviders. Dabei handelt es sich um austauschbare Komponenten, die so genannte Token erzeugen. Damit sind zufällige Zeichenketten gemeint, die die Anwendung dem Benutzer zum Beispiel via E-Mail sendet. Durch das Vorlegen dieser Tokens kann der Benutzer beweisen, dass er tatsächlich im Besitz der angegebenen E-Mail-Adresse ist.

Die Methode Configure der betrachteten Klasse Startup richtet Middleware-Komponenten ein. Die darin aufgerufene Erweiterungsmethode AddIdentity registriert die CookieAuthenticationMiddleware. Genaugenommen registriert AddIdentity sogar mehrere Instanzen dieser Middleware-Komponente, um verschiedene Anwendungsfälle abdecken zu können (Listing 1).

public class Startup
{
  public Startup(IHostingEnvironment env)
  {
    Configuration = new Configuration()
      .AddJsonFile("config.json")
      .AddEnvironmentVariables();
  }

  public IConfiguration Configuration { get; set; }

  public void ConfigureServices(IServiceCollection services)
  {
    […]
    services.AddEntityFramework(Configuration)
            .AddSqlServer()
            .AddDbContext();

    services.AddIdentity<ApplicationUser, IdentityRole>(Configuration)
            .AddEntityFrameworkStores()
            .AddDefaultTokenProviders();
    […]
  }

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
  {
    […]
    app.UseIdentity();
    […]
  }
}

ASP.NET Identity konfigurieren

Um ASP.NET Identity an die eigenen Anforderungen anzupassen, legt der Entwickler unter Verwendung von ConfigureIdentity innerhalb der besprochenen Methode ConfigureServices Konfigurationseinstellungen fest. Ein Beispiel dafür findet sich in Listing 2. Es legt zunächst über die Eigenschaften User und Password einzelne Validierungsregeln für Benutzernamen und Passwörter fest. Die Option SecurityStampValidationInterval gibt ein Intervall an, in dem die Anwendung prüfen soll, ob sich das Passwort seit dem Anmelden geändert hat. Ist das der Fall, meldet die Anwendung den Benutzer aus Sicherheitsgründen ab, sodass er angehalten ist, sich mit dem neuen Passwort anzumelden.

Die Eigenschaft Lockout.MaxFailedAccessAttempts legt fest, nach wie vielen erfolglosen Log-in-Versuchen das Benutzerkonto aus Sicherheitsgründen zu sperren ist. Die Eigenschaft Lockout.DefaultLockoutTimeSpan legt ergänzend dazu fest, wie lange das Benutzerkonto in solch einem Fall gesperrt sein soll. Mit RequireConfirmedEmail definiert der Entwickler, dass der Benutzer seine E-Mail-Adresse bestätigen muss. Dazu erhält er per E-Mail ein Token, das der Entwickler mit RequireConfirmedPhoneNumber für die beim Benutzerkonto hinterlegte Telefonnummer festlegt. In diesem Fall erhält der Benutzer einen Aktivierungscode via SMS. Sowohl den E-Mail-Versand als auch den SMS-Versand muss die Anwendung selbst implementieren, zumal ASP.NET Identity hierfür keine vorgefertigte Funktionalität bietet.

Zum Konfigurieren der ConfigureCookieAuthentication nutzt der Entwickler hingegen die Methode CookieAuthenticationMiddleware. Auch hierfür findet sich ein Beispiel in Listing 2: ExpireTimeSpan definiert die Gültigkeitszeitspanne des Sitzungs-Cookies und somit die maximale Dauer, für die der Benutzer angemeldet bleibt. Legt der Entwickler SlidingExpiration auf true fest, wird der Sitzungs-Cookie bei jedem Zugriff auf die Website erneuert. Das hat zur Folge, dass der Benutzer erst abgemeldet wird, wenn er zwischen zwei Seitenzugriffen die durch ExpireTimeSpan festgelegte Zeitspanne verstreichen lässt. LoginPath legt den URL fest, auf den die CookieAuthenticationMiddleware den Benutzer umleiten soll, wenn er für eine angeforderte Seite nicht die nötigen Rechte aufweist (Listing 2).

[…]
services.ConfigureIdentity(options => {

  options.User.RequireUniqueEmail = true;
  // options.User.UserNameValidationRegex = ""

  options.Password.RequiredLength = 6;
  options.Password.RequireDigit = true;
  options.Password.RequireLowercase = true;
  options.Password.RequireNonLetterOrDigit = true;
  options.Password.RequireUppercase = true;

  options.SecurityStampValidationInterval = TimeSpan.FromMinutes(15);

  options.Lockout.MaxFailedAccessAttempts = 3;
  options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);

  options.SignIn.RequireConfirmedEmail = true;
  options.SignIn.RequireConfirmedPhoneNumber = false;
});

services.ConfigureCookieAuthentication(config => {
  config.ExpireTimeSpan = TimeSpan.FromHours(4);
  config.SlidingExpiration = true;
  config.LoginPath = new PathString("/Account/Login");
});
[…]

Benutzer anmelden

Um einen Benutzer anhand eines Benutzernamens und eines Passworts anzumelden, greift eine ASP.NET-Anwendung auf den von ASP.NET Identity bereitgestellten SignInManager zurück. Diese Komponente, die über Dependency Injection zu beziehen ist, bietet dafür eine Methode PasswordSignInAsync an. Das Beispiel in Listing 3 demonstriert die Nutzung von PasswordSignInAsync. Dabei handelt es sich um eine erweiterte Version einer Action-Methode, die Visual Studio anbietet. Sie nimmt Benutzereingaben wie Benutzername und Passwort über ein LoginViewModel entgegen. Falls die Anwendung den Benutzer aufgrund unzureichender Berechtigungen zur Log-in-Maske gesendet hat, findet sich im Parameter returnUrl die ursprünglich angeforderte Seite. Die Eigenschaft ModelState.IsValid informiert darüber, ob ASP.NET die Benutzereingaben korrekt validieren konnte. Auf diese Weise fängt die Anwendung zum Beispiel leere Benutzernamen oder Passwörter ab.

Danach folgt der Aufruf der Methode PasswordSignInAsync. Sie nimmt den erfassten Benutzernamen und das erfasste Passwort entgegen. Der dritte Parameter, an den das betrachtete Beispiel den Wert RememberMe übergibt, informiert darüber, ob der Benutzer auch nach dem Beenden der Browsersitzung angemeldet bleiben soll. Diesem Wunsch kommt ASP.NET Identity durch Ausstellen eines persistenten Cookies nach. Der Parameter shouldLockout gibt an, ob ASP.NET Identity das betroffene Benutzerkonto nach einigen erfolglosen Log-in-Versuchen sperren soll. Auf diese Weise werden Angreifer am Ausprobieren verschiedener Passwörter gehindert. Nach wie vielen erfolglosen Log-in-Versuchen das Konto zu sperren ist und wie lange die Sperrung des Benutzerkontos bestehen bleiben soll, kann der Entwickler konfigurieren. Standardmäßig gesteht ASP.NET Identity dem Benutzer fünf Versuche zu und sperrt das Benutzerkonto danach für fünf Minuten.

Das Ergebnis von PasswordSignInAsync ist ein Objekt vom Typ SignInResult. Seine Eigenschaft Succeeded gibt Auskunft über den Erfolg des Log-in-Versuchs. Signalisiert diese Eigenschaft, dass der Benutzer erfolgreich angemeldet wurde, leitet die Action-Methode den Benutzer auf die ursprünglich angefragte Seite weiter. Ansonsten prüft die Action-Methode unter Verwendung der Eigenschaften von SignInResult, warum der Log-in-Vorgang nicht erfolgreich war: IsLockedOut gibt beispielsweise darüber Auskunft, ob ASPNET Identity das Benutzerkonto in Folge einer Reihe erfolgloser Log-in-Versuche gesperrt hat. IsNotAllowed weist hingegen den Wert true auf, wenn das Benutzerkonto erst aktiviert werden muss. Dies kann zum Beispiel durch Angabe eines Tokens bewerkstelligt werden, das die Anwendung dem Benutzer per E-Mail zukommen lässt. Die Eigenschaft RequiresTwoFactor gibt hingegen darüber Auskunft, dass sich der Benutzer zusätzlich mit weiteren Daten zu erkennen geben muss. In diesem Fall leitet die Anwendung den Benutzer auf die Action-Methode TwoFactorAuth um.

Weisen alle besprochenen Eigenschaften den Wert false auf, ist es wahrscheinlich, dass eine falsche Benutzername/Passwort-Kombination übergeben wurde. In diesem Fall platziert die gezeigte Action-Methode eine allgemeine Fehlermeldung im Model State (Listing 3).

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task Login(LoginViewModel model, string returnUrl = null)
{
  if (ModelState.IsValid)
  {
    var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);

    if (result.Succeeded)
    {
      return RedirectToLocal(returnUrl);
    }
    if (result.IsLockedOut)
    {
      ModelState.AddModelError("", "Vorübergehend deaktiviert");
    }
    else if (result.IsNotAllowed)
    {
      ModelState.AddModelError("", "Konto muss noch aktiviert werden");
    }
    else if (result.RequiresTwoFactor)
    {
      return RedirectToAction("TwoFactorAuth", new { returnUrl = returnUrl, rememberMe = model.RememberMe });
    }
    else
    {
      ModelState.AddModelError("", "Fehler beim Login!");
    }
  }

  // If we got this far, something failed, redisplay form
  return View(model);
}

Benutzer registrieren

Zum Warten von Benutzerkonten weist die Klasse UserManager einige Methoden auf. Wie auch der SignInManager, kann der UserManager über den Dependency-Injection-Mechanismus von ASP.NET 5 bezogen werden. Das Beispiel in Listing 4 demonstriert die Nutzung des UserManagers. Dabei handelt es sich abermals um eine erweiterte Version einer Action-Methode, die die von Visual Studio genutzte Projektvorlage bereitstellt.

Die Aufgabe der gezeigten Methode Register ist das Erstellen eines neuen Benutzerkontos. Die Eckdaten dieses Kontos nimmt Register über den Parameter vom Typ RegisterViewModel entgegen. Sofern ASP.NET MVC die über diesen Parameter übergebenen Eigenschaften erfolgreich validieren konnte, erzeugt Register ein Objekt vom Typ ApplicationUser, der einen Benutzer repräsentiert. Das Beispiel hinterlegt den Benutzernamen und die E-Mail-Adresse des Benutzers. Daneben setzt sie die Eigenschaft TwoFactorEnabled auf true, um die optionale Two Factor Authentication für dieses Konto zu aktivieren.

Um den Benutzer anzulegen, übergibt Register den ApplicationUser an die Methode CreateAsync des UserManagers. Zusätzlich übergibt Register das festgelegte Passwort. Das Ergebnis von CreateAsync ist ein Objekt des Typs IdentityResult. Über seine Eigenschaft Succeeded informiert dieses Objekt über den Erfolg der angestoßenen Option. Ansonsten bietet sie über die Eigenschaft Errors Beschreibungen zu den aufgetretenen Fehlern. War CreateAsync erfolgreich, muss der Benutzer die erfasste E-Mail-Adresse bestätigen. Dazu generiert Register mit der von UserManager bereitgestellten Methode GenerateEmailConfirmationTokenAsync eine zufällige Zeichenfolge, die auch als Token bezeichnet wird, und sendet sie unter Verwendung von MessageServices.SendEmailAsync an die angegebene E-Mail-Adresse. Bei MessageServices.SendEmailAsync handelt es sich um eine Methode, die nicht Teil von ASP.NET Identity, sondern von der Webanwendung bereitzustellen ist.

Damit der Benutzer das Token nicht manuell von der E-Mail in die Anwendung kopieren muss, erstellt Register mit der Hilfsmethode Url.Action einen URL, die das Token über einen URL-Parameter an die Action-Methode ConfirmEmail übersendet. Da dieser URL in die E-Mail aufgenommen wird, muss der Benutzer zum Aktivieren des Benutzerkontos lediglich auf diesen URL klicken (Listing 4).

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task Register(RegisterViewModel model)
{
  if (ModelState.IsValid)
  {
    var user = new ApplicationUser {
      UserName = model.UserName,
      Email = model.UserName,
      TwoFactorEnabled = true
    };
    
    var result = await UserManager.CreateAsync(user, model.Password);

    if (result.Succeeded)
    {
      var emailToken = await UserManager.GenerateEmailConfirmationTokenAsync(user);

      var confirmationUrl = Url.Action(
        "ConfirmEmail", 
        "Account", 
        new { userId = user.Id, 
          token = emailToken }, 
        protocol: Request.Scheme);

      await MessageServices.SendEmailAsync(
        user.Email, 
        "EMail-Bestätigung", 
        "EMail-Adresse bestätigen:" 
        + confirmationUrl);

      return View("ConfirmNow");
    }
    else
    {
      foreach (var error in result.Errors)
      {
        ModelState.AddModelError("", error.Description);
      }
    }
  }

  // If we got this far, something failed, redisplay form
  return View(model);
}

Bestätigung über Token

Um eine E-Mail-Adresse durch ASP.NET Identity bestätigen zu lassen, ruft die Anwendung die Methode ConfirmEmailAsync der Klasse UserManager auf. An diese Methode übergibt sie das Objekt, das den betroffenen Benutzer beschreibt, sowie das per E-Mail versendete Token:

Tabelle 1: Methoden zum Ausstellen und Prüfen von Tokens

Tabelle 1: Methoden zum Ausstellen und Prüfen von Tokens

Two Factor Authentication

Ist für ein Benutzerkonto die Two Factor Authentication aktiviert, muss sich der Benutzer nach erfolgreicher Prüfung des erfassten Passworts mit einem weiteren so genannten Faktor zu erkennen geben. Zur Prüfung dieses zweiten Faktors setzt ASP.NET Identity auf ein erweiterbares Providerkonzept. Im Lieferumfang befinden sich zwei Provider. Der eine erzeugt einen Bestätigungscode, der via E-Mail an den Benutzer zu versenden ist, der andere einen Bestätigungscode für den Versand via SMS.

Nachdem sich der Benutzer mit seinem Passwort authentifiziert hat, erzeugt ASP.NET Identity einen temporären Cookie, der den Benutzer beschreibt, bis seine Identität durch einen zweiten Faktor bestätigt wurde. Die Methode GetTwoFactorAuthenticationUserAsync des SignInManagers liefert ein Objekt, das diesen Benutzer beschreibt:

var user = await SignInManager.GetTwoFactorAuthenticationUserAsync();

Um eine Liste mit sämtlichen Providern für eine Two Factor Authentication zu erhalten, übergibt die Anwendung dieses Objekt an die Methode GetValidTwoFactorProvidersAsync des UserManagers:

var providers = await UserManager.GetValidTwoFactorProvidersAsync(user);

Diese Methode liefert die Namen der Provider, die die Anwendung gemeinsam mit dem jeweiligen Benutzerkonto nutzen kann. Weist das Benutzerkonto eine bestätigte E-Mail-Adresse auf, kann die Anwendung beispielsweise den Provider für E-Mail-Codes nutzen. Weist das Benutzerkonto eine bestätigte Telefonnummer auf, kann die Anwendung darüber hinaus auch auf den Provider für SMS-Codes zurückgreifen. Es ist üblich, dass Anwendungen dem Benutzer die Möglichkeit geben, sich für eine der möglichen Optionen zu entscheiden. Um mit dem gewählten Provider ein Token zu generieren, ruft die Anwendung die Methode GenerateTwoFactorTokenAsync auf:

var token = await UserManager.GenerateTwoFactorTokenAsync(user, option);

Das erste Argument entspricht dem Benutzerobjekt, das zweite Argument ist der Name des gewählten Providers. Für das Versenden des Tokens ist die Anwendung selbst verantwortlich. Um ein solches vom Benutzer vorgelegtes Token zu prüfen und somit die Two Factor Authentication abzuschließen, delegiert die Anwendung an die Methode TwoFactorSignInAsync des SignInManagers:

var result = await SignInManager.TwoFactorSignInAsync(option, code, rememberMe, rememberClient: true);

Der erste Parameter gibt den Namen des gewählten Providers an, der zweite den übersendeten Code. Der dritte Parameter ist ein boolescher Wert, der darüber Auskunft gibt, ob der Benutzer einen persistenten Session-Cookie erhalten soll. Ein solcher Session-Cookie bewirkt, dass der Benutzer auch nach dem Ende einer Browsersitzung angemeldet bleibt.

Der vierte Parameter, rememberClient, gibt hingegen an, dass ein weiterer persistenter Cookie zu erstellen ist. Dieser Cookie gibt darüber Auskunft, dass mit dem genutzten Browser bereits eine Two Factor Authentication erfolgreich durchgeführt wurde. Ist dieser Cookie vorhanden, muss sich der Benutzer trotz aktivierter Two Factor Authentication nur mit seinem Passwort anmelden. Damit kann eine Anwendung einen Mittelweg zwischen Sicherheit und Benutzerfreundlichkeit erreichen.

Fazit und Ausblick

ASP.NET Identity bietet eine komfortable Lösung zur Implementierung wiederkehrender Aufgaben zur Verwaltung von Benutzerkonten und der Authentifizierung von Benutzern. Aufgrund seines flexiblen Designs kann der Entwickler diese Bibliothek an vielen Stellen an eigene Bedürfnisse anpassen.

Zum Anmelden von Benutzern spielt ASP.NET Identity mit Middleware-Komponenten zusammen. Während dieser Artikel den Einsatz der CookieAuthenticationMiddleware beleuchtet hat, kann der Entwickler auch Middleware-Komponenten einsetzen, die eine Anmeldung mit externen Log-in-Providern ermöglichen, und verwaltete Benutzerkonten mit externen Gegenstücken verknüpfen. Das macht Szenarien wie „Log-in mit Facebook“ möglich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -