Einführung in Identity ASP.NET Core

Von Rick Anderson

ASP.NET Core Identity:

  • Eine API, die Anmeldefunktionen für die Benutzeroberfläche (UI) unterstützt.
  • Verwaltet Benutzer, Kennwörter, Profildaten, Rollen, Ansprüche, Token, E-Mail-Bestätigungen und vieles mehr.

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

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

Die Identität "data-linktype="external">Identity Quellcode ist auf GitHub verfügbar. Scaffold Identity und zeigen die generierten Dateien an, um die Vorlageninteraktion mit zu Identity überprüfen.

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

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

Microsoft Identity Platform ist:

  • Eine Weiterentwicklung der Azure Active Directory (Azure AD) Entwicklerplattform.
  • Steht 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 Welcome to IdentityServer4.

Anzeigen oder Herunterladen des Beispielcodes (Herunterladen von).

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. Geben Sie dem Projekt den Namen WebApp1, damit es den gleichen Namespace wie der Projektdownload hat. Klicken Sie auf OK.
  • Wählen Sie in der Eingabe Authentifizierungstyp die Option Einzelne Benutzerkontenaus.

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

  • /Identity/Account/Login
  • /Identity/Account/Logout
  • /Identity/Account/Manage

Anwenden von Migrationen

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

Testregistrierung und -anmeldung

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 die Option SQL Server Objekt-Explorer (SSOX) aus.
  • Navigieren Sie zu (localdb)MSSQLLocalDB(SQL Server 13). Klicken Sie mit der rechten Maustaste auf dbo. AspNetUsersView Data (AspNetUsers-Ansichtsdaten):

Contextual menu on AspNetUsers table in SQL Server Object Explorer

Konfigurieren von Identity Diensten

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

  1. Add{Service}
  2. 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 vorangehende Code konfiguriert Identity mit Standardoptionswerten. Dienste werden der App durch Abhängigkeitsinjektionzur Verfügung gestellt.

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

Die vorlagengenerierte App verwendet keine Autorisierung. app.UseAuthorization ist enthalten, um sicherzustellen, dass es in der richtigen Reihenfolge hinzugefügt wird, wenn die App Autorisierung hinzufügt. UseRouting, UseAuthenticationUseAuthorization , und müssen in der reihenfolge UseEndpoints aufgerufen werden, die im vorherigen Code gezeigt wird.

Weitere Informationen zu IdentityOptions finden Sie unter und IdentityOptionsIdentityOptions

Gerüst für Register, Login, LogOut und RegisterConfirmation

Fügen Sie die Register Dateien , , und LoginLogOutRegisterConfirmation hinzu. Befolgen Sie die Scaffold identity into a Razor project with authorization Anweisungen, um den in diesem Abschnitt gezeigten Code zu generieren.

Register untersuchen

Wenn ein Benutzer auf der Seite auf die Schaltfläche Registrieren klickt, wird die Aktion RegisterModel.OnPostAsync aufgerufen. Der Benutzer wird von Identity _UserManager_1_CreateAsync__0_System_String_" data-linktype="absolute-path">CreateAsync für das Objekt _userManager 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 zu dem Account.RegisterConfirmation umgeleitet, wo er einen Link auswählen kann, um das Konto zu bestätigen. Der Standardwert Account.RegisterConfirmation wird Account.RegisterConfirmation für Tests verwendet. Die automatische Kontoüberprüfung sollte in einer Produktions-App deaktiviert werden.

Um ein bestätigtes Konto zu erfordern und eine sofortige Anmeldung bei der Registrierung zu verhindern, legen Sie DisplayConfirmAccountLink = false in DisplayConfirmAccountLink = falsefest:

[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, 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 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 unter Einführung in die Autorisierung in ASP.NET Core.

Abmelden

Der Link Abmelden ruft die 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.

_SignInManager_1_SignOutAsync" data-linktype="absolute-path">SignOutAsync löscht die in einem gespeicherten Ansprüche des cookie Benutzers.

Post wird in pages/Shared/_LoginPartial.cshtmlangegeben:

@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 Standardvorlagen für Webprojekte ermöglichen anonymen Zugriff auf die Startseiten. Fügen Sie zum Testen Identity von [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 Privacy Link aus. Sie werden zur Anmeldeseite umgeleitet.

Erkunden Identity

Weitere Informationen finden Sie Identity hier:

Identity Komponenten

Alle Identity -abhängigen NuGet-Pakete sind im Identityenthalten.

Das primäre Paket für Identity ist Identity Identity /" data-linktype="external">Microsoft.AspNetCore. Identity . Dieses Paket enthält den Kernsatz von Schnittstellen für ASP.NET Core Identity und ist in Microsoft.AspNetCore.Identity.EntityFrameworkCore enthalten.

Migrieren zu ASP.NET Core Identity

Weitere Informationen und Anleitungen zum Migrieren Ihres vorhandenen Identity Speichers finden Sie unter Migrate Authentication and Identity .

Festlegen der Kennwortstärke

Ein Beispiel zum Festlegen der Mindestanforderungen für Kennwörter finden Sie unter Konfiguration.

AddDefault Identity und HinzufügenIdentity

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

Weitere Informationen finden Sie unter Identity /UI/src/ Identity ServiceCollectionUIExtensions.cs#L47-L63" data-linktype="external">AddDefault Identity source.

Verhindern der Veröffentlichung statischer Identity Ressourcen

Fügen Sie Identity der Projektdatei der App die folgende Eigenschaft und das Ziel hinzu, um zu verhindern, dass statische Objekte (Stylesheets und JavaScript-Dateien für die Benutzeroberfläche) im Webstamm veröffentlicht IdentityResolveStaticWebAssetsInputsDependsOnRemoveIdentityAssets werden:

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

  • Eine API, die Anmeldefunktionen für die Benutzeroberfläche (UI) unterstützt.
  • Verwaltet Benutzer, Kennwörter, Profildaten, Rollen, Ansprüche, Token, E-Mail-Bestätigungen und vieles mehr.

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

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

Die Identität "data-linktype="external">Identity Quellcode ist auf GitHub verfügbar. Scaffold Identity und zeigen die generierten Dateien an, um die Vorlageninteraktion mit zu Identity überprüfen.

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

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

Microsoft Identity Platform ist:

  • Eine Weiterentwicklung der Azure Active Directory (Azure AD) Entwicklerplattform.
  • Steht 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 Welcome to IdentityServer4.

Anzeigen oder Herunterladen des Beispielcodes (Herunterladen von).

Erstellen einer Web-App mit Authentifizierung

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

  • Wählen Sie DateiNeuProjekt aus.
  • Wählen Sie ASP.NET Core-Webanwendung aus. Geben Sie dem Projekt den Namen WebApp1, damit es den gleichen Namespace wie der Projektdownload hat. Klicken Sie auf OK.
  • Wählen Sie eine ASP.NET Core Webanwendungund dann Authentifizierung ändernaus.
  • Wählen Sie Einzelne Benutzerkonten aus, und klicken Sie auf OK.

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

  • /Identity/Account/Login
  • /Identity/Account/Logout
  • /Identity/Account/Manage

Anwenden von Migrationen

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

Testregistrierung und -anmeldung

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 die Option SQL Server Objekt-Explorer (SSOX) aus.
  • Navigieren Sie zu (localdb)MSSQLLocalDB(SQL Server 13). Klicken Sie mit der rechten Maustaste auf dbo. AspNetUsers View Data (AspNetUsers-Ansichtsdaten):

Contextual menu on AspNetUsers table in SQL Server Object 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 oben hervorgehobene Code wird mit Identity Standardoptionswerten konfiguriert. Dienste werden der App durch Abhängigkeitsinjektion zur Verfügung gestellt.

Identity wird durch Aufrufen von UseAuthentication aktiviert. UseAuthentication fügt der UseAuthentication 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 vorangehende Code wird mit Identity Standardwerten für Optionen konfiguriert. Dienste werden der App durch Abhängigkeitsinjektion zur Verfügung gestellt.

Identitywird durch Aufrufen von Identity UseAuthentication fügt der UseAuthentication 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 es in der richtigen Reihenfolge hinzugefügt wird, wenn die App die Autorisierung hinzufüge. UseRouting, , und müssen in der im vorherigen Code UseAuthenticationUseAuthorizationUseEndpoints gezeigten Reihenfolge aufgerufen werden.

Weitere Informationen zu und IdentityOptions finden Sie unter und StartupIdentityOptionsIdentityOptions

Gerüst für Register, Login, LogOut und RegisterConfirmation

Fügen Sie Register die Dateien , , und LoginLogOutRegisterConfirmation hinzu. Befolgen Sie Scaffold identity into a Razor project with authorization die Anweisungen, um den in diesem Abschnitt gezeigten Code zu generieren.

Überprüfen der Registrierung

Wenn ein Benutzer auf der Seite auf die Schaltfläche Registrieren klickt, wird RegisterModel.OnPostAsync die Aktion aufgerufen. Der Benutzer wird von Identity _UserManager_1_CreateAsync__0_System_String_" data-linktype="absolute-path">CreateAsync für das Objekt _userManager 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 zu dem umgeleitet, wo er einen Link auswählen Account.RegisterConfirmation kann, um das Konto bestätigen zu lassen. Die Account.RegisterConfirmation Standardeinstellung wird Account.RegisterConfirmation Tests verwendet. Die automatische Kontoüberprüfung sollte in einer Produktions-App deaktiviert werden.

Legen Sie in DisplayConfirmAccountLink = falseDisplayConfirmAccountLink = falsefest, um ein bestätigtes Konto zu verlangen und eine sofortige Anmeldung bei der Registrierung zu verhindern:

[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 zu zugreifen, für die er nicht autorisiert ist oder auf die er nicht vom System authentifiziert wurde.

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

Abmelden

Der Link Abmelden ruft die 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 vorangehenden Code muss der Code eine Umleitung sein, damit der Browser eine neue Anforderung ausführt und die Identität für den return RedirectToPage(); Benutzer aktualisiert wird.

_SignInManager_1_SignOutAsync" data-linktype="absolute-path">SignOutAsync löschen die in einem gespeicherten Ansprüche des cookie Benutzers.

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

Test Identity

Die Standardvorlagen für Webprojekt ermöglichen anonymen Zugriff auf die Startseiten. Fügen Sie zum Identity Testen [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 Privacy Link aus. Sie werden zur Anmeldeseite umgeleitet.

Erkunden Identity

Ausführlichere Identity Informationen finden Sie hier:

Identity Komponenten

Alle von Identity abhängigen NuGet sind im freigegebenen Framework ASP.NET Core Identity

Das primäre Paket für Identity ist Identity Identity /" data-linktype="external">Microsoft.AspNetCore. Identity . Dieses Paket enthält den Kernsatz von Schnittstellen für ASP.NET Core Identity und ist in Microsoft.AspNetCore.Identity.EntityFrameworkCore enthalten.

Migrieren zu ASP.NET Core Identity

Weitere Informationen und Anleitungen zum Migrieren Ihres vorhandenen Speichers Identity finden Sie unter Migrate Authentication and Identity .

Festlegen der Kennwortstärke

Unter Konfiguration finden Sie ein Beispiel, in dem die Mindestanforderungen für Kennwörter definiert werden.

AddDefault Identity und AddIdentity

AddDefaultIdentitywurde in ASP.NET Core 2.1 eingeführt. Das AddDefaultIdentity Aufrufen von ähnelt dem Aufrufen der folgenden:

Weitere Informationen finden Sie unter Identity /UI/src/ Identity ServiceCollectionUIExtensions.cs#L47-L63" data-linktype="external">AddDefault Identity source".

Verhindern der Veröffentlichung von statischen Identity Ressourcen

Um zu verhindern, dass statische Objekte (Stylesheets und JavaScript-Dateien für die Benutzeroberfläche) im Webstamm veröffentlicht werden, fügen Sie der Projektdatei der App die folgende Eigenschaft und IdentityIdentity das folgende Ziel ResolveStaticWebAssetsInputsDependsOnRemoveIdentityAssets hinzu:

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

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

Nächste Schritte