Einführung von Identity in ASP.NET Core

ASP.NET Core Identity:

  • ist eine API, die die Anmeldefunktionalität der Benutzeroberfläche (UI) unterstützt.
  • verwaltet Benutzer*innen, Kennwörter, Profildaten, Rollen, Ansprüche, Token, E-Mail-Bestätigung u. v. m.

Benutzer*innen können ein Konto mit den in Identity gespeicherten Anmeldeinformationen erstellen oder einen externen Anmeldeanbieter verwenden. Zu den unterstützten externen Anmeldeanbietern gehören Facebook, Google, Microsoft-Konto und Twitter.

Informationen zum Anfordern der Authentifizierung für alle App-Benutzer finden Sie unter Erstellen Sie eine ASP.NET Core-App mit durch Autorisierung geschützten Benutzerdaten.

Der Identity Quellcode ist auf GitHub verfügbar. Erstellen Sie ein Gerüst für Identity, und überprüfen Sie in den generierten Dateien die Interaktion der Vorlage mit Identity.

Identity wird in der Regel mithilfe einer SQL Server Datenbank konfiguriert, um Benutzernamen, Kennwörter und Profildaten zu speichern. Alternativ kann ein anderer beständiger Speicher verwendet werden, z. B. Azure Table Storage.

In diesem Thema erfahren Sie, wie Sie mit Identity Nutzer registrieren, anmelden und abmelden. Hinweis: In den Vorlagen werden Benutzername und E-Mail-Adresse für Benutzer*innen gleich behandelt. Ausführlichere Anweisungen zum Erstellen von Apps, die Identity verwenden, finden Sie unter Nächste Schritte.

Weitere Informationen zu Identity in Blazor-Apps finden Sie in der ASP.NET Core Blazor-Authentifizierung und -Autorisierung sowie in den darauf folgenden Artikeln in der Blazor-Dokumentation.

ASP.NET Core Identity ist nicht mit der Microsoft Identity Platform verknüpft. Microsoft Identity Platform ist:

  • Eine Entwicklung der Azure Active Directory -Entwicklerplattform (Azure AD).
  • Eine alternative Identitätslösung für Authentifizierung und Autorisierung in ASP.NET Core Apps.

ASP.NET Core Identity fügt Web-Apps von ASP.NET Core Benutzeroberflächen-Anmeldefunktionen hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:

Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:

  • Authentifizierung als Dienstleistung (AaaS)
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugangskontrolle für APIs
  • Föderationsgateway

Important

Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrate von ASP.NET Core in .NET 5 bis .NET 6.

Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).

View oder laden Sie den Beispielcode herunter (how to download).

Erstellen Sie ein Blazor Web App mit Authentifizierung

Erstellen Sie eine ASP.NET Core Blazor Web App project mit einzelnen Konten.

Note

Für ein Razor Pages-Erlebnis, lesen Sie den Abschnitt Erstellen einer Razor Pages-App mit Authentifizierung.

Eine MVC-Erfahrung finden Sie im Abschnitt "Erstellen einer MVC-App mit Authentifizierung ".

  • Wählen Sie die Blazor Web App Vorlage aus. Wählen Sie Weiteraus.
  • Treffen Sie die folgenden Auswahlen:
    • Authentifizierungstyp: Einzelne Konten
    • Interaktiver Rendermodus: Server
    • Interaktivitätsstandort: Global
  • Wählen Sie "Erstellen" aus.

Die generierte project enthält IdentityRazor-Komponenten. Die Komponenten befinden sich im Ordner Components/Account des Server-project. Beispiel:

  • Components/Account/Pages/Register.razor
  • Components/Account/Pages/Login.razor
  • Components/Account/Pages/Manage/ChangePassword.razor

Identity Razor Komponenten werden in der Dokumentation für spezifische Anwendungsfälle einzeln beschrieben und können sich bei jeder Version ändern. Wenn Sie ein Blazor Web App mit Individuellen Konten generieren, werden IdentityRazor-Komponenten in dem generierten Projekt enthalten. Die Komponenten IdentityRazor können auch im Ordner Components/Account des Serverprojekts in der Blazor Web App Projektvorlage (dotnet/aspnetcore GitHub Repository) geprüft werden.

Note

Dokumentationslinks zu .NET-Referenzquellcode verweisen normalerweise auf den Standard-Branch des Repositorys, der die aktuelle Entwicklung der nächsten .NET-Version widerspiegelt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter Wie man einen Versionstag des ASP.NET Core-Quellcodes auswählt (dotnet/AspNetCore.Docs #26205).

Weitere Informationen finden Sie unter ASP.NET Core Blazor Authentifizierung und Autorisierung und in den nachfolgenden Artikeln der DokumentationBlazor. Die meisten Artikel im Security und Identity Bereich des Hauptdokumentationssatzes ASP.NET Core gelten für Blazor-Apps. Der Blazor Dokumentationssatz enthält jedoch Artikel und Anleitungen, die Informationen ersetzen oder hinzufügen. Es wird empfohlen, zuerst den allgemeinen ASP.NET Core Dokumentationssatz zu studieren, gefolgt vom Zugriff auf die Artikel in der Dokumentation BlazorSecurity und Identity.

Erstellen Sie eine Razor Pages App mit Authentifizierung

Erstellen Sie ein ASP.NET Core-Webanwendungsprojekt (Razor Pages) mit individuellen Konten.

  • Wählen Sie die Vorlage ASP.NET Core Web App (Razor Pages) aus. Wählen Sie Weiteraus.
  • Wählen Sie für den Authentifizierungstyp"Einzelne Konten" aus.
  • Wählen Sie "Erstellen" aus.

Die generierte Projekt bietet ASP.NET Core Identity als Razor Klassenbibliothek (RCL) an. Die IdentityRazor-Klassenbibliothek macht Endpunkte im Identity-Bereich verfügbar. Beispiel:

  • Areas/Identity/Pages/Account/Register
  • Areas/Identity/Pages/Account/Login
  • Areas/Identity/Pages/Account/Manage/ChangePassword

Seiten werden einzeln in der Dokumentation für spezifische Anwendungsfälle beschrieben und können mit jeder Veröffentlichung geändert werden. Informationen zum Anzeigen aller Seiten in der RCL finden Sie in der Referenzquelle ASP.NET Core (dotnet/aspnetcore GitHub Repository, Identity/UI/src/Areas/Identity/Pages Ordner). Sie können einzelne Seiten oder alle Seiten in die App einbinden. Weitere Informationen finden Sie unter Scaffold Identity in ASP.NET Core Projekten.

Erstellen einer MVC-App mit Authentifizierung

Erstellen Sie ein ASP.NET Core MVC-Projekt mit Einzelkonten.

  • Wählen Sie die Vorlage ASP.NET Core Web App (Model-View-Controller) aus. Wählen Sie Weiteraus.
  • Wählen Sie für den Authentifizierungstyp"Einzelne Konten" aus.
  • Wählen Sie "Erstellen" aus.

Die generierte Projekt bietet ASP.NET Core Identity als Razor Klassenbibliothek (RCL) an. Die IdentityRazor Klassenbibliothek basiert auf Razor Seiten und macht Endpunkte mit dem Identity Bereich verfügbar. Beispiel:

  • Areas/Identity/Pages/Account/Register
  • Areas/Identity/Pages/Account/Login
  • Areas/Identity/Pages/Account/Manage/ChangePassword

Seiten werden einzeln in der Dokumentation für spezifische Anwendungsfälle beschrieben und können mit jeder Veröffentlichung geändert werden. Informationen zum Anzeigen aller Seiten in der RCL finden Sie in der Referenzquelle ASP.NET Core (dotnet/aspnetcore GitHub Repository, Identity/UI/src/Areas/Identity/Pages Ordner). Sie können einzelne Seiten oder alle Seiten in die App einbinden. Weitere Informationen finden Sie unter Scaffold Identity in ASP.NET Core Projekten.

Migrationen anwenden

Wenden Sie die Migrationen an, um die Datenbank zu initialisieren.

Führen Sie den folgenden Befehl in der Paket-Manager Console (PMC) aus:

Update-Database

Test Registrierung und Anmeldung

Führen Sie die App aus, und registrieren Sie eine*n neue*n Benutzer*in. Je nach Bildschirmgröße müssen Sie möglicherweise die Umschaltfläche für die Navigation auswählen, um die Links für das Registrieren und Anmelden anzuzeigen.

Anzeigen der Identity-Datenbank

  • Wählen Sie im Menü ViewSQL Server Objekt-Explorer (SSOX) aus.
  • Navigieren Sie zu (localdb)MSSQLLocalDB(SQL Server 13). Klicken Sie mit der rechten Maustaste auf dbo.AspNetUsers>Daten anzeigen:

Kontextmenü der AspNetUsers-Tabelle im SQL Server-Objekt-Explorer

Konfigurieren von Identity-Diensten

Dienste werden in Program.cs hinzugefügt. Das typische Muster besteht darin, Methoden in der folgenden Reihenfolge aufzurufen:

  1. Add{Service}
  2. builder.Services.Configure{Service}
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

builder.Services.Configure<IdentityOptions>(options =>
{
    // Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 1;

    // Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;

    // User settings.
    options.User.AllowedUserNameCharacters =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    options.User.RequireUniqueEmail = false;
});

builder.Services.ConfigureApplicationCookie(options =>
{
    // Cookie settings
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

    options.LoginPath = "/Identity/Account/Login";
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.SlidingExpiration = true;
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

Der obige Code konfiguriert Identity mit den Standardwerten für die einzelnen Optionen. Dienste werden der App über die Abhängigkeitsinjektion verfügbar gemacht.

Identity wird durch Aufrufen von UseAuthentication aktiviert. UseAuthentication fügt der Anforderungspipeline Authentifizierungsmiddleware hinzu.

Die mit der Vorlage generierte App verwendet keine Autorisierung. app.UseAuthorization ist enthalten, um sicherzustellen, dass sie in der richtigen Reihenfolge hinzugefügt wird, wenn die App um eine Autorisierung erweitert wird. UseRouting, UseAuthentication und UseAuthorization müssen in der im vorherigen Code gezeigten Reihenfolge aufgerufen werden.

Weitere Informationen zu IdentityOptions finden Sie unter IdentityOptions und Starten von Anwendungen.

Metriken ASP.NET Core Identity

ASP.NET Core Identity Metriken bieten Überwachungsfunktionen für Benutzerverwaltungs- und Authentifizierungsprozesse. Anhand dieser Metriken können Sie ungewöhnliche Anmeldemuster erkennen, die Sicherheitsbedrohungen angeben, die Leistung von Identitätsvorgängen nachverfolgen und verstehen, wie Benutzer mit Authentifizierungsfeatures interagieren, z. B. zweistufige Authentifizierung. Diese Observability ist besonders nützlich für Apps mit strengen Sicherheitsanforderungen oder für Apps mit hohem Authentifizierungsverkehr.

Ausführliche Informationen zu den verfügbaren Metriken und deren Verwendung finden Sie unter ASP.NET Core Metrics.

Erstellen von Gerüsten für Register, Login, LogOut und RegisterConfirmation

Fügen Sie die Dateien Register, Login, LogOut und RegisterConfirmation hinzu. Folgen Sie den Anweisungen zur Scaffold-Identität in einem Razor Projekt mit Autorisierung, um den Code zu erzeugen, der in diesem Abschnitt gezeigt wird.

Register überprüfen

Wenn Benutzer*innen auf der Seite die Schaltfläche Register (Registrieren) auswählen, wird die RegisterModel.OnPostAsync-Aktion aufgerufen. Die Benutzer*innen werden von CreateAsync(TUser) im _userManager-Objekt erstellt:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

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

Deaktivieren der Standardkontoüberprüfung

Bei den Standardvorlagen werden die Benutzer*innen zu Account.RegisterConfirmation umgeleitet, wo sie einen Link auswählen können, um das Konto bestätigen zu lassen. Die Standardeinstellung von Account.RegisterConfirmation wird nur für Tests verwendet. Die automatische Kontoüberprüfung sollte in einer Produktions-App deaktiviert werden.

Um ein bestätigtes Konto zu erzwingen und eine sofortige Anmeldung bei der Registrierung zu verhindern, legen Sie DisplayConfirmAccountLink = false in /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs fest:

[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IEmailSender _sender;

    public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
    {
        _userManager = userManager;
        _sender = sender;
    }

    public string Email { get; set; }

    public bool DisplayConfirmAccountLink { get; set; }

    public string EmailConfirmationUrl { get; set; }

    public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
    {
        if (email == null)
        {
            return RedirectToPage("/Index");
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return NotFound($"Unable to load user with email '{email}'.");
        }

        Email = email;
        // Once you add a real email sender, you should remove this code that lets you confirm the account
        DisplayConfirmAccountLink = false;
        if (DisplayConfirmAccountLink)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            EmailConfirmationUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);
        }

        return Page();
    }
}

Anmelden

Das Anmeldeformular wird in folgenden Fällen angezeigt:

  • Der Link Log in (Anmelden) wird ausgewählt.
  • Ein Benutzer versucht, auf eine eingeschränkte Seite zuzugreifen, auf die er nicht zugreifen darf oder wenn er nicht vom System authentifiziert wurde.

Wenn das Formular auf der Anmeldeseite übermittelt wird, wird die OnPostAsync-Aktion aufgerufen. PasswordSignInAsync wird im _signInManager-Objekt aufgerufen.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

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

Informationen zum Treffen von Autorisierungsentscheidungen finden Sie unter Introduction to authorization in ASP.NET Core.

Ausloggen

Der Link Log out (Abmelden) ruft die LogoutModel.OnPost-Aktion auf.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

Im vorherigen Code muss der Code return RedirectToPage(); eine Umleitung sein, damit der Browser eine neue Anforderung ausführt und die Identität für den Benutzer aktualisiert wird.

SignOutAsync löscht die in einem cookie gespeicherten Benutzeransprüche.

Die Nachverarbeitung wird in Pages/Shared/_LoginPartial.cshtml angegeben:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Testen von Identity

Die Standard-Webprojektvorlagen ermöglichen anonymen Zugriff auf die Startseiten. Um Identity zu testen, fügen Sie [Authorize] hinzu.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Wenn Sie angemeldet sind, melden Sie sich ab. Führen Sie die App aus, und wählen Sie den Link Privacy aus. Sie werden zur Anmeldeseite umgeleitet.

Identity erkunden

So erkunden Sie Identity genauer

Identity-Komponenten

Alle Identity-abhängigen NuGet-Pakete sind im ASP.NET Core shared framework enthalten.

Das primäre Paket für Identity ist Microsoft.AspNetCore.Identity. Dieses Paket enthält die Kernmenge von Schnittstellen für ASP.NET Core Identity und wird von Microsoft.AspNetCore.Identity.EntityFrameworkCore eingeschlossen.

Migrieren zu ASP.NET Core Identity

Weitere Informationen und Leitfäden zum Migrieren Ihres vorhandenen Identity-Speichers finden Sie unter Migrieren der Authentifizierung und Identity.

Festlegen der Kennwortsicherheit

Unter Konfiguration finden Sie ein Beispiel, mit dem Mindestkennwortanforderungen festgelegt werden.

AddDefaultIdentity und AddIdentity

AddDefaultIdentity wurde in ASP.NET Core 2.1 eingeführt. Ein Aufruf von AddDefaultIdentity ähnelt dem Aufrufen von Folgendem:

Weitere Informationen finden Sie unter AddDefaultIdentity source.

Verhindern der Veröffentlichung statischer Identity-Ressourcen

Um die Veröffentlichung statischer Identity-Ressourcen (Stylesheets und JavaScript-Dateien für Identity UI) im Web-Root-Verzeichnis zu verhindern, fügen Sie die folgende ResolveStaticWebAssetsInputsDependsOn-Eigenschaft und das RemoveIdentityAssets-Ziel zur Projektdatei der App hinzu.

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Nächste Schritte

Von Rick Anderson

ASP.NET Core Identity:

  • ist eine API, die die Anmeldefunktionalität der Benutzeroberfläche (UI) unterstützt.
  • verwaltet Benutzer*innen, Kennwörter, Profildaten, Rollen, Ansprüche, Token, E-Mail-Bestätigung u. v. m.

Benutzer*innen können ein Konto mit den in Identity gespeicherten Anmeldeinformationen erstellen oder einen externen Anmeldeanbieter verwenden. Zu den unterstützten externen Anmeldeanbietern gehören Facebook, Google, Microsoft-Konto und Twitter.

Informationen zum Anfordern der Authentifizierung für alle App-Benutzer finden Sie unter Erstellen Sie eine ASP.NET Core-App mit durch Autorisierung geschützten Benutzerdaten.

Der Identity Quellcode ist auf GitHub verfügbar. Erstellen Sie ein Gerüst für Identity, und überprüfen Sie in den generierten Dateien die Interaktion der Vorlage mit Identity.

Identity wird in der Regel mithilfe einer SQL Server Datenbank konfiguriert, um Benutzernamen, Kennwörter und Profildaten zu speichern. Alternativ kann ein anderer beständiger Speicher verwendet werden, z. B. Azure Table Storage.

In diesem Thema erfahren Sie, wie Sie mit Identity Nutzer registrieren, anmelden und abmelden. Hinweis: In den Vorlagen werden Benutzername und E-Mail-Adresse für Benutzer*innen gleich behandelt. Ausführlichere Anweisungen zum Erstellen von Apps, die Identity verwenden, finden Sie unter Nächste Schritte.

ASP.NET Core Identity ist nicht mit der Microsoft Identity Platform verknüpft. Microsoft Identity Platform ist:

  • Eine Entwicklung der Azure Active Directory -Entwicklerplattform (Azure AD).
  • Eine alternative Identitätslösung für Authentifizierung und Autorisierung in ASP.NET Core Apps.

ASP.NET Core Identity fügt Web-Apps von ASP.NET Core Benutzeroberflächen-Anmeldefunktionen hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:

Duende Identity Server ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende Identity Server ermöglicht die folgenden Sicherheitsfeatures:

  • Authentifizierung als Dienstleistung (AaaS)
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugangskontrolle für APIs
  • Föderationsgateway

Important

Duende Software erhebt ggf. eine Lizenzgebühr für die Nutzung von Duende Identity Server in der Produktion. Weitere Informationen finden Sie unter Migrate von ASP.NET Core in .NET 5 bis .NET 6.

Weitere Informationen finden Sie in der Dokumentation zu Duende Identity Server (Website von Duende Software).

View oder laden Sie den Beispielcode herunter (how to download).

Erstellen einer Web-App mit Authentifizierung

Erstellen Sie ein ASP.NET Core-Webanwendungsprojekt mit individuellen Benutzerkonten.

  • Wählen Sie die Vorlage ASP.NET Core Web App aus. Benennen Sie das Projekt WebApp1, um denselben Namespace wie das Projekt herunterladen zu haben. Klicke auf OK.
  • Wählen Sie in der Eingabe Authentifizierungstyp die Option Einzelne Benutzerkonten aus.

Die generierte Projekt stellt ASP.NET Core Identity als Razor Klassenbibliothek bereit. Die IdentityRazor-Klassenbibliothek macht Endpunkte im Identity-Bereich verfügbar. Beispiel:

  • /Identity/Konto/Anmeldung
  • /Identity/Account/Abmelden
  • /Identity/Konto/Verwalten

Migrationen anwenden

Wenden Sie die Migrationen an, um die Datenbank zu initialisieren.

Führen Sie den folgenden Befehl in der Paket-Manager Console (PMC) aus:

Update-Database

Test Registrierung und Anmeldung

Führen Sie die App aus, und registrieren Sie eine*n neue*n Benutzer*in. Je nach Bildschirmgröße müssen Sie möglicherweise die Umschaltfläche für die Navigation auswählen, um die Links für das Registrieren und Anmelden anzuzeigen.

Anzeigen der Identity-Datenbank

  • Wählen Sie im Menü ViewSQL Server Objekt-Explorer (SSOX) aus.
  • Navigieren Sie zu (localdb)MSSQLLocalDB(SQL Server 13). Klicken Sie mit der rechten Maustaste auf dbo.AspNetUsers>Daten anzeigen:

Kontextmenü der AspNetUsers-Tabelle im SQL Server-Objekt-Explorer

Konfigurieren von Identity-Diensten

Dienste werden in Program.cs hinzugefügt. Das typische Muster besteht darin, Methoden in der folgenden Reihenfolge aufzurufen:

  1. Add{Service}
  2. builder.Services.Configure{Service}
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

builder.Services.Configure<IdentityOptions>(options =>
{
    // Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 1;

    // Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;

    // User settings.
    options.User.AllowedUserNameCharacters =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    options.User.RequireUniqueEmail = false;
});

builder.Services.ConfigureApplicationCookie(options =>
{
    // Cookie settings
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

    options.LoginPath = "/Identity/Account/Login";
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.SlidingExpiration = true;
});

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

Der obige Code konfiguriert Identity mit den Standardwerten für die einzelnen Optionen. Dienste werden der App über die Abhängigkeitsinjektion verfügbar gemacht.

Identity wird durch Aufrufen von UseAuthentication aktiviert. UseAuthentication fügt der Anforderungspipeline Authentifizierungsmiddleware hinzu.

Die mit der Vorlage generierte App verwendet keine Autorisierung. app.UseAuthorization ist enthalten, um sicherzustellen, dass sie in der richtigen Reihenfolge hinzugefügt wird, wenn die App um eine Autorisierung erweitert wird. UseRouting, UseAuthentication und UseAuthorization müssen in der im vorherigen Code gezeigten Reihenfolge aufgerufen werden.

Weitere Informationen zu IdentityOptions finden Sie unter IdentityOptions und Starten von Anwendungen.

Erstellen von Gerüsten für Register, Login, LogOut und RegisterConfirmation

Fügen Sie die Dateien Register, Login, LogOut und RegisterConfirmation hinzu. Folgen Sie den Anweisungen zur Scaffold-Identität in einem Razor Projekt mit Autorisierung, um den Code zu erzeugen, der in diesem Abschnitt gezeigt wird.

Register überprüfen

Wenn Benutzer*innen auf der Seite die Schaltfläche Register (Registrieren) auswählen, wird die RegisterModel.OnPostAsync-Aktion aufgerufen. Die Benutzer*innen werden von CreateAsync(TUser) im _userManager-Objekt erstellt:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

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

Deaktivieren der Standardkontoüberprüfung

Bei den Standardvorlagen werden die Benutzer*innen zu Account.RegisterConfirmation umgeleitet, wo sie einen Link auswählen können, um das Konto bestätigen zu lassen. Die Standardeinstellung von Account.RegisterConfirmation wird nur für Tests verwendet. Die automatische Kontoüberprüfung sollte in einer Produktions-App deaktiviert werden.

Um ein bestätigtes Konto zu erzwingen und eine sofortige Anmeldung bei der Registrierung zu verhindern, legen Sie DisplayConfirmAccountLink = false in /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs fest:

[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IEmailSender _sender;

    public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
    {
        _userManager = userManager;
        _sender = sender;
    }

    public string Email { get; set; }

    public bool DisplayConfirmAccountLink { get; set; }

    public string EmailConfirmationUrl { get; set; }

    public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
    {
        if (email == null)
        {
            return RedirectToPage("/Index");
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return NotFound($"Unable to load user with email '{email}'.");
        }

        Email = email;
        // Once you add a real email sender, you should remove this code that lets you confirm the account
        DisplayConfirmAccountLink = false;
        if (DisplayConfirmAccountLink)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            EmailConfirmationUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);
        }

        return Page();
    }
}

Anmelden

Das Anmeldeformular wird in folgenden Fällen angezeigt:

  • Der Link Log in (Anmelden) wird ausgewählt.
  • Ein Benutzer versucht, auf eine eingeschränkte Seite zuzugreifen, auf die er nicht zugreifen darf oder wenn er nicht vom System authentifiziert wurde.

Wenn das Formular auf der Anmeldeseite übermittelt wird, wird die OnPostAsync-Aktion aufgerufen. PasswordSignInAsync wird im _signInManager-Objekt aufgerufen.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

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

Informationen zum Treffen von Autorisierungsentscheidungen finden Sie unter Introduction to authorization in ASP.NET Core.

Ausloggen

Der Link Log out (Abmelden) ruft die LogoutModel.OnPost-Aktion auf.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

Im vorherigen Code muss der Code return RedirectToPage(); eine Umleitung sein, damit der Browser eine neue Anforderung ausführt und die Identität für den Benutzer aktualisiert wird.

SignOutAsync löscht die in einem cookie gespeicherten Benutzeransprüche.

Die Nachverarbeitung wird in Pages/Shared/_LoginPartial.cshtml angegeben:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Testen von Identity

Die Standard-Webprojektvorlagen ermöglichen anonymen Zugriff auf die Startseiten. Um Identity zu testen, fügen Sie [Authorize] hinzu.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Wenn Sie angemeldet sind, melden Sie sich ab. Führen Sie die App aus, und wählen Sie den Link Privacy aus. Sie werden zur Anmeldeseite umgeleitet.

Identity erkunden

So erkunden Sie Identity genauer

Identity-Komponenten

Alle Identity-abhängigen NuGet-Pakete sind im ASP.NET Core shared framework enthalten.

Das primäre Paket für Identity ist Microsoft.AspNetCore.Identity. Dieses Paket enthält die Kernmenge von Schnittstellen für ASP.NET Core Identity und wird von Microsoft.AspNetCore.Identity.EntityFrameworkCore eingeschlossen.

Migrieren zu ASP.NET Core Identity

Weitere Informationen und Leitfäden zum Migrieren Ihres vorhandenen Identity-Speichers finden Sie unter Migrieren der Authentifizierung und Identity.

Festlegen der Kennwortsicherheit

Unter Konfiguration finden Sie ein Beispiel, mit dem Mindestkennwortanforderungen festgelegt werden.

AddDefaultIdentity und AddIdentity

AddDefaultIdentity wurde in ASP.NET Core 2.1 eingeführt. Ein Aufruf von AddDefaultIdentity ähnelt dem Aufrufen von Folgendem:

Weitere Informationen finden Sie unter AddDefaultIdentity source.

Verhindern der Veröffentlichung statischer Identity-Ressourcen

Um die Veröffentlichung statischer Identity-Ressourcen (Stylesheets und JavaScript-Dateien für Identity UI) im Web-Root-Verzeichnis zu verhindern, fügen Sie die folgende ResolveStaticWebAssetsInputsDependsOn-Eigenschaft und das RemoveIdentityAssets-Ziel zur Projektdatei der App hinzu.

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Nächste Schritte

Von Rick Anderson

ASP.NET Core Identity:

  • ist eine API, die die Anmeldefunktionalität der Benutzeroberfläche (UI) unterstützt.
  • verwaltet Benutzer*innen, Kennwörter, Profildaten, Rollen, Ansprüche, Token, E-Mail-Bestätigung u. v. m.

Benutzer*innen können ein Konto mit den in Identity gespeicherten Anmeldeinformationen erstellen oder einen externen Anmeldeanbieter verwenden. Zu den unterstützten externen Anmeldeanbietern gehören Facebook, Google, Microsoft-Konto und Twitter.

Informationen zum Anfordern der Authentifizierung für alle App-Benutzer finden Sie unter Erstellen Sie eine ASP.NET Core-App mit durch Autorisierung geschützten Benutzerdaten.

Der Identity Quellcode ist auf GitHub verfügbar. Erstellen Sie ein Gerüst für Identity, und überprüfen Sie in den generierten Dateien die Interaktion der Vorlage mit Identity.

Identity wird in der Regel mithilfe einer SQL Server Datenbank konfiguriert, um Benutzernamen, Kennwörter und Profildaten zu speichern. Alternativ kann ein anderer beständiger Speicher verwendet werden, z. B. Azure Table Storage.

In diesem Thema erfahren Sie, wie Sie mit Identity Nutzer registrieren, anmelden und abmelden. Hinweis: In den Vorlagen werden Benutzername und E-Mail-Adresse für Benutzer*innen gleich behandelt. Ausführlichere Anweisungen zum Erstellen von Apps, die Identity verwenden, finden Sie unter Nächste Schritte.

Microsoft Identity Platform lautet:

  • Eine Entwicklung der Azure Active Directory -Entwicklerplattform (Azure AD).
  • Eine alternative Identitätslösung für Authentifizierung und Autorisierung in ASP.NET Core Apps.
  • Nicht im Zusammenhang mit ASP.NET Core Identity.

ASP.NET Core Identity fügt Web-Apps von ASP.NET Core Benutzeroberflächen-Anmeldefunktionen hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:

Duende IdentityServer ist ein OpenID Connect- und OAuth 2.0-Framework für ASP.NET Core. Duende IdentityServer ermöglicht die folgenden Sicherheitsfeatures:

  • Authentifizierung als Dienstleistung (AaaS)
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugangskontrolle für APIs
  • Föderationsgateway

Weitere Informationen finden Sie in der Übersicht über Duende IdentityServer.

Weitere Informationen zu anderen Authentifizierungsanbietern finden Sie unter Community OSS authentication options for ASP.NET Core

View oder laden Sie den Beispielcode herunter (how to download).

Erstellen einer Web-App mit Authentifizierung

Erstellen Sie ein ASP.NET Core-Webanwendungsprojekt mit individuellen Benutzerkonten.

  • Wählen Sie File>New>Project aus.
  • Wählen Sie ASP.NET Core Webanwendung aus. Benennen Sie das Projekt WebApp1, um denselben Namespace wie das Projekt herunterladen zu haben. Klicke auf OK.
  • Wählen Sie eine ASP.NET Core Webanwendung und dann Change Authentication aus.
  • Wählen Sie Einzelne Benutzerkonten und dann OK aus.

Die generierte Projekt stellt ASP.NET Core Identity als Razor Klassenbibliothek bereit. Die IdentityRazor-Klassenbibliothek macht Endpunkte im Identity-Bereich verfügbar. Beispiel:

  • /Identity/Konto/Anmeldung
  • /Identity/Account/Abmelden
  • /Identity/Konto/Verwalten

Migrationen anwenden

Wenden Sie die Migrationen an, um die Datenbank zu initialisieren.

Führen Sie den folgenden Befehl in der Paket-Manager Console (PMC) aus:

PM> Update-Database

Test Registrierung und Anmeldung

Führen Sie die App aus, und registrieren Sie eine*n neue*n Benutzer*in. Je nach Bildschirmgröße müssen Sie möglicherweise die Umschaltfläche für die Navigation auswählen, um die Links für das Registrieren und Anmelden anzuzeigen.

Anzeigen der Identity-Datenbank

  • Wählen Sie im Menü ViewSQL Server Objekt-Explorer (SSOX) aus.
  • Navigieren Sie zu (localdb)MSSQLLocalDB(SQL Server 13). Klicken Sie mit der rechten Maustaste auf dbo.AspNetUsers>Daten anzeigen:

Kontextmenü der AspNetUsers-Tabelle im SQL Server-Objekt-Explorer

Konfigurieren von Identity-Diensten

Dienste werden in ConfigureServices hinzugefügt. Das typische Muster besteht darin, alle Add{Service}-Methoden und dann alle services.Configure{Service}-Methoden aufzurufen.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
     // options.UseSqlite(
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings.
        options.Password.RequireDigit = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequiredLength = 6;
        options.Password.RequiredUniqueChars = 1;

        // Lockout settings.
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // User settings.
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });
}

Der obige hervorgehobene Code konfiguriert Identity mit den Standardwerten für die einzelnen Optionen. Dienste werden der App über die Abhängigkeitsinjektion verfügbar gemacht.

Identity wird durch Aufrufen von UseAuthentication aktiviert. UseAuthentication fügt der Anforderungspipeline Authentifizierungsmiddleware hinzu.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        // options.UseSqlite(
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings.
        options.Password.RequireDigit = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequiredLength = 6;
        options.Password.RequiredUniqueChars = 1;

        // Lockout settings.
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // User settings.
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });
}

Der obige Code konfiguriert Identity mit den Standardwerten für die einzelnen Optionen. Dienste werden der App über die Abhängigkeitsinjektion verfügbar gemacht.

Identity wird durch Aufrufen von UseAuthentication aktiviert. UseAuthentication fügt der Anforderungspipeline Authentifizierungsmiddleware hinzu.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseMigrationsEndPoint();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Die mit der Vorlage generierte App verwendet keine Autorisierung. app.UseAuthorization ist enthalten, um sicherzustellen, dass sie in der richtigen Reihenfolge hinzugefügt wird, wenn die App um eine Autorisierung erweitert wird. UseRouting, UseAuthentication, UseAuthorization und UseEndpoints müssen in der im vorherigen Code gezeigten Reihenfolge aufgerufen werden.

Weitere Informationen zu IdentityOptions und Startup finden Sie unter IdentityOptions und Starten von Anwendungen.

Erstellen von Gerüsten für Register, Login, LogOut und RegisterConfirmation

Fügen Sie die Dateien Register, Login, LogOut und RegisterConfirmation hinzu. Folgen Sie den Anweisungen zur Scaffold-Identität in einem Razor Projekt mit Autorisierung, um den Code zu erzeugen, der in diesem Abschnitt gezeigt wird.

Register überprüfen

Wenn Benutzer*innen auf der Seite die Schaltfläche Register (Registrieren) auswählen, wird die RegisterModel.OnPostAsync-Aktion aufgerufen. Die Benutzer*innen werden von CreateAsync(TUser) im _userManager-Objekt erstellt:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

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

Deaktivieren der Standardkontoüberprüfung

Bei den Standardvorlagen werden die Benutzer*innen zu Account.RegisterConfirmation umgeleitet, wo sie einen Link auswählen können, um das Konto bestätigen zu lassen. Die Standardeinstellung von Account.RegisterConfirmation wird nur für Tests verwendet. Die automatische Kontoüberprüfung sollte in einer Produktions-App deaktiviert werden.

Um ein bestätigtes Konto zu erzwingen und eine sofortige Anmeldung bei der Registrierung zu verhindern, legen Sie DisplayConfirmAccountLink = false in /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs fest:

[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
    private readonly UserManager<IdentityUser> _userManager;
    private readonly IEmailSender _sender;

    public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
    {
        _userManager = userManager;
        _sender = sender;
    }

    public string Email { get; set; }

    public bool DisplayConfirmAccountLink { get; set; }

    public string EmailConfirmationUrl { get; set; }

    public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
    {
        if (email == null)
        {
            return RedirectToPage("/Index");
        }

        var user = await _userManager.FindByEmailAsync(email);
        if (user == null)
        {
            return NotFound($"Unable to load user with email '{email}'.");
        }

        Email = email;
        // Once you add a real email sender, you should remove this code that lets you confirm the account
        DisplayConfirmAccountLink = false;
        if (DisplayConfirmAccountLink)
        {
            var userId = await _userManager.GetUserIdAsync(user);
            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            EmailConfirmationUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
                protocol: Request.Scheme);
        }

        return Page();
    }
}

Anmelden

Das Anmeldeformular wird in folgenden Fällen angezeigt:

  • Der Link Log in (Anmelden) wird ausgewählt.
  • Ein Benutzer versucht, auf eine eingeschränkte Seite zuzugreifen, auf die er nicht zugreifen darf oder wenn er nicht vom System authentifiziert wurde.

Wenn das Formular auf der Anmeldeseite übermittelt wird, wird die OnPostAsync-Aktion aufgerufen. PasswordSignInAsync wird im _signInManager-Objekt aufgerufen.

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

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

Informationen zum Treffen von Autorisierungsentscheidungen finden Sie unter Introduction to authorization in ASP.NET Core.

Ausloggen

Der Link Log out (Abmelden) ruft die LogoutModel.OnPost-Aktion auf.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

Im vorherigen Code muss der Code return RedirectToPage(); eine Umleitung sein, damit der Browser eine neue Anforderung ausführt und die Identität für den Benutzer aktualisiert wird.

SignOutAsync löscht die in einem cookie gespeicherten Benutzeransprüche.

Die Nachverarbeitung wird in Pages/Shared/_LoginPartial.cshtml angegeben:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Testen von Identity

Die Standard-Webprojektvorlagen ermöglichen anonymen Zugriff auf die Startseiten. Um Identity zu testen, fügen Sie [Authorize] hinzu.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Wenn Sie angemeldet sind, melden Sie sich ab. Führen Sie die App aus, und wählen Sie den Link Privacy aus. Sie werden zur Anmeldeseite umgeleitet.

Identity erkunden

So erkunden Sie Identity genauer

Identity-Komponenten

Alle Identity-abhängigen NuGet-Pakete sind im ASP.NET Core shared framework enthalten.

Das primäre Paket für Identity ist Microsoft.AspNetCore.Identity. Dieses Paket enthält die Kernmenge von Schnittstellen für ASP.NET Core Identity und wird von Microsoft.AspNetCore.Identity.EntityFrameworkCore eingeschlossen.

Migrieren zu ASP.NET Core Identity

Weitere Informationen und Leitfäden zum Migrieren Ihres vorhandenen Identity-Speichers finden Sie unter Migrieren der Authentifizierung und Identity.

Festlegen der Kennwortsicherheit

Unter Konfiguration finden Sie ein Beispiel, mit dem Mindestkennwortanforderungen festgelegt werden.

Verhindern der Veröffentlichung statischer Identity-Ressourcen

Um die Veröffentlichung statischer Identity-Ressourcen (Stylesheets und JavaScript-Dateien für Identity UI) im Web-Root-Verzeichnis zu verhindern, fügen Sie die folgende ResolveStaticWebAssetsInputsDependsOn-Eigenschaft und das RemoveIdentityAssets-Ziel zur Projektdatei der App hinzu.

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Nächste Schritte