Einführung in Identity in ASP.NET Core

Von Rick Anderson

ASP.NET Core Identity:

  • Ist eine API, die die Anmeldefunktionen der Benutzeroberfläche unterstützt.
  • Verwaltet Benutzer, Kennwörter, Profildaten, Rollen, Ansprüche, Token, E-Mail-Bestätigung und vieles mehr.

Benutzer können ein Konto mit den anmeldeinformationen erstellen, die gespeichert sind Identity , oder sie können einen externen Anmeldeanbieter verwenden. Unterstützte externe Anmeldeanbieter umfassen Facebook, Google, Microsoft-Konto und Twitter.

Informationen dazu, wie global die Authentifizierung aller Benutzer angefordert werden kann, finden Sie unter Authentifizierte Benutzer erforderlich.

Der Identity Quellcode ist auf GitHub verfügbar. Gerüst Identity und zeigen Sie die generierten Dateien an, um die Vorlageninteraktion mit Identity.

Identityist in der Regel mithilfe einer SQL Server Datenbank zum Speichern von Benutzernamen, Kennwörtern und Profildaten konfiguriert. Alternativ kann ein anderer persistenter Speicher verwendet werden, z. B. Azure Table Storage.

In diesem Thema erfahren Sie, wie Identity Sie einen Benutzer registrieren, anmelden und abmelden können. Hinweis: Die Vorlagen behandeln Benutzernamen und E-Mails genauso für Benutzer. Ausführlichere Anweisungen zum Erstellen von Apps, die verwendet werden Identity, finden Sie in den nächsten Schritten.

Microsoft Identity Platform ist:

  • Eine Weiterentwicklung der Azure Active Directory (Azure AD)-Entwicklerplattform.
  • 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 Benutzeroberflächen-Anmeldefunktionen zu ASP.NET Core-Web-Apps hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:

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

  • Authentifizierung als Dienst
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugriffssteuerung für APIs
  • Federation Gateway

Weitere Informationen finden Sie unter Willkommen bei IdentityServer4.

Anzeigen oder Herunterladen des Beispielcodes (herunterladen).

Erstellen einer Web-App mit Authentifizierung

Erstellen Sie ein ASP.NET Core Webanwendungsprojekt mit einzelnen Benutzerkonten.

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

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

  • /Identity/Konto/Anmeldung
  • /Identity/Konto/Abmelden
  • /Identity/Account/Manage

Anwenden von Migrationen

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

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

Update-Database

Registrieren und Anmelden testen

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

Anzeigen der Identity Datenbank

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

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

Konfigurieren von Identity Diensten

Dienste werden hinzugefügt.Program.cs 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 vorherige Code konfiguriert sich Identity mit Standardoptionswerten. Dienste werden der App über die Abhängigkeitseinfügung zur Verfügung gestellt.

Identity wird durch Aufrufen UseAuthenticationaktiviert. UseAuthentication Fügt der Anforderungspipeline Authentifizierungs-Middleware hinzu.

Die von 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-Autorisierung hinzugefügt wird. UseRouting, UseAuthenticationund UseAuthorization muss in der Reihenfolge aufgerufen werden, die im vorherigen Code angezeigt wird.

Weitere Informationen finden IdentityOptionsSie unter IdentityOptions und Anwendungsstart.

Gerüstregister, Anmeldung, LogOut und RegisterConfirmation

Fügen Sie die RegisterDateien LogOutLogin, und RegisterConfirmation Dateien hinzu. Folgen Sie der Gerüstidentität in einem Razor Projekt mit Autorisierungsanweisungen , um den in diesem Abschnitt gezeigten Code zu generieren.

Register untersuchen

Wenn ein Benutzer auf die Schaltfläche " Registrieren " auf der Register Seite klickt, wird die RegisterModel.OnPostAsync Aktion aufgerufen. Der Benutzer wird von CreateAsync(TUser) dem _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

Mit den Standardvorlagen wird der Benutzer an die Stelle weitergeleitet, an der Account.RegisterConfirmation er einen Link auswählen kann, um das Konto bestätigt zu haben. Der Standardwert Account.RegisterConfirmation wird nur zum Testen verwendet, die automatische Kontoüberprüfung sollte in einer Produktions-App deaktiviert werden.

Um ein bestätigtes Konto zu erfordern und die sofortige Anmeldung bei der Registrierung zu verhindern, legen Sie folgendes /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.csfestDisplayConfirmAccountLink = false:

[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 angezeigt, wenn:

  • Der Link "Anmelden " ist ausgewählt.
  • Ein Benutzer versucht, auf eine eingeschränkte Seite zuzugreifen, die nicht für den Zugriff autorisiert ist oder wenn er nicht vom System authentifiziert wurde.

Wenn das Formular auf der Anmeldeseite übermittelt wird, wird die OnPostAsync Aktion aufgerufen. PasswordSignInAsync wird für das _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 in der Einführung in die Autorisierung in ASP.NET Core.

Abmelden

Der Link "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 Ansprüche des Benutzers, die in einem cookie.

Post wird in der :Pages/Shared/_LoginPartial.cshtml

@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>

Test Identity

Die Standardmäßigen Webprojektvorlagen ermöglichen anonymen Zugriff auf die Homepages. Zum Testen Identityfügen Sie Folgendes hinzu [Authorize]:

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 Privacy Link aus. Sie werden zur Anmeldeseite umgeleitet.

Erkunden Identity

Identity Weitere Informationen finden Sie unter:

Identity Komponenten

IdentityAlle von NuGet abhängigen NuGet-Pakete sind im ASP.NET Core freigegebenen Framework enthalten.

Das primäre Paket für IdentityMicrosoft.AspNetCore.Identity. Dieses Paket enthält den Kernsatz von Schnittstellen für ASP.NET Core Identityund wird von Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migrieren zu ASP.NET Core Identity

Weitere Informationen und Anleitungen zum Migrieren Ihres vorhandenen Identity Speichers finden Sie unter Migrieren der Authentifizierung und Identity.

Festlegen der Kennwortstärke

Siehe Konfiguration für ein Beispiel, das die Mindestkennwortanforderungen festlegt.

AddDefaultIdentity und AddIdentity

AddDefaultIdentitywurde in ASP.NET Core 2.1 eingeführt. Anrufe ähneln dem Aufrufen der folgenden Schritte AddDefaultIdentity :

Weitere Informationen finden Sie in der AddDefault-QuelleIdentity.

Verhindern der Veröffentlichung statischer Identity Ressourcen

Um die Veröffentlichung statischer Identity Objekte (Stylesheets und JavaScript-Dateien für Identity ui) im Webstamm zu verhindern, fügen Sie die folgende ResolveStaticWebAssetsInputsDependsOn Eigenschaft und RemoveIdentityAssets das Ziel der 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 Anmeldefunktionen der Benutzeroberfläche unterstützt.
  • Verwaltet Benutzer, Kennwörter, Profildaten, Rollen, Ansprüche, Token, E-Mail-Bestätigung und vieles mehr.

Benutzer können ein Konto mit den anmeldeinformationen erstellen, die gespeichert sind Identity , oder sie können einen externen Anmeldeanbieter verwenden. Unterstützte externe Anmeldeanbieter umfassen Facebook, Google, Microsoft-Konto und Twitter.

Informationen dazu, wie global die Authentifizierung aller Benutzer angefordert werden kann, finden Sie unter Authentifizierte Benutzer erforderlich.

Der Identity Quellcode ist auf GitHub verfügbar. Gerüst Identity und zeigen Sie die generierten Dateien an, um die Vorlageninteraktion mit Identity.

Identityist in der Regel mithilfe einer SQL Server Datenbank zum Speichern von Benutzernamen, Kennwörtern und Profildaten konfiguriert. Alternativ kann ein anderer persistenter Speicher verwendet werden, z. B. Azure Table Storage.

In diesem Thema erfahren Sie, wie Identity Sie einen Benutzer registrieren, anmelden und abmelden können. Hinweis: Die Vorlagen behandeln Benutzernamen und E-Mails genauso für Benutzer. Ausführlichere Anweisungen zum Erstellen von Apps, die verwendet werden Identity, finden Sie in den nächsten Schritten.

Microsoft Identity Platform ist:

  • Eine Weiterentwicklung der Azure Active Directory (Azure AD)-Entwicklerplattform.
  • 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 Benutzeroberflächen-Anmeldefunktionen zu ASP.NET Core-Web-Apps hinzu. Verwenden Sie zum Sichern von Web-APIs und SPAs eine der folgenden Optionen:

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

  • Authentifizierung als Dienst
  • Einmaliges Anmelden und einmaliges Abmelden für mehrere Anwendungstypen
  • Zugriffssteuerung für APIs
  • Federation Gateway

Weitere Informationen finden Sie unter Willkommen bei IdentityServer4.

Anzeigen oder Herunterladen des Beispielcodes (herunterladen).

Erstellen einer Web-App mit Authentifizierung

Erstellen Sie ein ASP.NET Core Webanwendungsprojekt mit einzelnen Benutzerkonten.

  • Klicken Sie auf Datei>Neu>Projekt.
  • Wählen Sie ASP.NET Core-Webanwendung aus. Benennen Sie das Projekt WebApp1 , um denselben Namespace wie der Projektdownload zu haben. Klicken Sie auf OK.
  • Wählen Sie eine ASP.NET Core Webanwendung aus, und wählen Sie dann "Authentifizierung ändern" aus.
  • Wählen Sie einzelne Benutzerkonten aus, und klicken Sie auf 'OK'.

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

  • /Identity/Konto/Anmeldung
  • /Identity/Konto/Abmelden
  • /Identity/Account/Manage

Anwenden von Migrationen

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

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

PM> Update-Database

Registrieren und Anmelden testen

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

Anzeigen der Identity Datenbank

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

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

Konfigurieren von Identity Diensten

Dienste werden hinzugefügt.ConfigureServices 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 vorherige hervorgehobene Code konfiguriert mit Standardwerten Identity . Dienste werden der App über die Abhängigkeitseinfügung zur Verfügung gestellt.

Identity wird durch Aufrufen UseAuthenticationaktiviert. UseAuthentication Fügt der Anforderungspipeline Authentifizierungs-Middleware 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 vorherige Code konfiguriert sich Identity mit Standardoptionswerten. Dienste werden der App über die Abhängigkeitseinfügung zur Verfügung gestellt.

Identity wird durch Aufrufen UseAuthenticationaktiviert. UseAuthentication Fügt der Anforderungspipeline Authentifizierungs-Middleware 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 von 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-Autorisierung hinzugefügt wird. UseRouting, UseAuthentication, UseAuthorizationund UseEndpoints muss in der Reihenfolge aufgerufen werden, die im vorherigen Code angezeigt wird.

Weitere Informationen zu IdentityOptions und Startup, finden Sie unter IdentityOptions und Anwendungsstart.

Gerüstregister, Anmeldung, LogOut und RegisterConfirmation

Fügen Sie die RegisterDateien LogOutLogin, und RegisterConfirmation Dateien hinzu. Folgen Sie der Gerüstidentität in einem Razor Projekt mit Autorisierungsanweisungen , um den in diesem Abschnitt gezeigten Code zu generieren.

Register untersuchen

Wenn ein Benutzer auf die Schaltfläche " Registrieren " auf der Register Seite klickt, wird die RegisterModel.OnPostAsync Aktion aufgerufen. Der Benutzer wird von CreateAsync(TUser) dem _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

Mit den Standardvorlagen wird der Benutzer an die Stelle weitergeleitet, an der Account.RegisterConfirmation er einen Link auswählen kann, um das Konto bestätigt zu haben. Der Standardwert Account.RegisterConfirmation wird nur zum Testen verwendet, die automatische Kontoüberprüfung sollte in einer Produktions-App deaktiviert werden.

Um ein bestätigtes Konto zu erfordern und die sofortige Anmeldung bei der Registrierung zu verhindern, legen Sie folgendes /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.csfestDisplayConfirmAccountLink = false:

[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 angezeigt, wenn:

  • Der Link "Anmelden " ist ausgewählt.
  • Ein Benutzer versucht, auf eine eingeschränkte Seite zuzugreifen, die nicht für den Zugriff autorisiert ist oder wenn er nicht vom System authentifiziert wurde.

Wenn das Formular auf der Anmeldeseite übermittelt wird, wird die OnPostAsync Aktion aufgerufen. PasswordSignInAsync wird für das _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 in der Einführung in die Autorisierung in ASP.NET Core.

Abmelden

Der Link "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 Ansprüche des Benutzers, die in einem cookie.

Post wird in der :Pages/Shared/_LoginPartial.cshtml

@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>

Test Identity

Die Standardmäßigen Webprojektvorlagen ermöglichen anonymen Zugriff auf die Homepages. Zum Testen Identityfügen Sie Folgendes hinzu [Authorize]:

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 Privacy Link aus. Sie werden zur Anmeldeseite umgeleitet.

Erkunden Identity

Identity Weitere Informationen finden Sie unter:

Identity Komponenten

IdentityAlle von NuGet abhängigen NuGet-Pakete sind im ASP.NET Core freigegebenen Framework enthalten.

Das primäre Paket für IdentityMicrosoft.AspNetCore.Identity. Dieses Paket enthält den Kernsatz von Schnittstellen für ASP.NET Core Identityund wird von Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migrieren zu ASP.NET Core Identity

Weitere Informationen und Anleitungen zum Migrieren Ihres vorhandenen Identity Speichers finden Sie unter Migrieren der Authentifizierung und Identity.

Festlegen der Kennwortstärke

Siehe Konfiguration für ein Beispiel, das die Mindestkennwortanforderungen festlegt.

AddDefaultIdentity und AddIdentity

AddDefaultIdentitywurde in ASP.NET Core 2.1 eingeführt. Anrufe ähneln dem Aufrufen der folgenden Schritte AddDefaultIdentity :

Weitere Informationen finden Sie in der AddDefault-QuelleIdentity.

Verhindern der Veröffentlichung statischer Identity Ressourcen

Um die Veröffentlichung statischer Identity Objekte (Stylesheets und JavaScript-Dateien für Identity ui) im Webstamm zu verhindern, fügen Sie die folgende ResolveStaticWebAssetsInputsDependsOn Eigenschaft und RemoveIdentityAssets das Ziel der 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