Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
ASP.NET Core Identity :
- Est une API qui prend en charge la fonctionnalité de connexion par interface utilisateur.
- Gère les utilisateurs, les mots de passe, les données de profil, les rôles, les revendications, les jetons, la confirmation par e-mail, etc.
Les utilisateurs peuvent créer un compte avec les informations de connexion stockées dans Identity ou utiliser un fournisseur de connexion externe. Les fournisseurs de connexion externes pris en charge incluent Facebook, Google, Compte Microsoft et Twitter.
Pour plus d’informations sur la façon d’exiger l’authentification globale de tous les utilisateurs, consultez la section Exiger des utilisateurs authentifiés.
Le code source Identity est disponible sur GitHub. Générez automatiquement des modèles Identity et affichez les fichiers générés pour passer en revue l’interaction du modèle avec Identity.
Identity est généralement configuré à l’aide d’une base de données SQL Server pour stocker les noms d’utilisateur, les mots de passe et les données de profil. Vous pouvez également utiliser un autre magasin persistant, par exemple Stockage Table Azure.
Dans cette rubrique, vous allez apprendre à utiliser Identity pour inscrire, connecter et déconnecter un utilisateur. Remarque : les modèles traitent le nom d’utilisateur et l’adresse e-mail comme étant identiques pour les utilisateurs. Pour obtenir des instructions plus détaillées sur la création d’applications qui utilisent Identity, consultez la section Étapes suivantes.
Pour plus d'informations sur Identity dans les applications Blazor, consultez ASP.NET Core Blazor l’authentification et l’autorisation et les articles qui les suivent dans la documentation Blazor.
ASP.NET Core Identity n’est pas lié à la plateforme d’identités Microsoft . La plateforme d’identités Microsoft est la suivante :
- Une évolution de la plateforme de développement Azure Active Directory (Azure AD).
- Solution d’identité alternative pour l’authentification et l’autorisation dans les applications ASP.NET Core.
ASP.NET Core Identity ajoute la fonctionnalité de connexion de l’interface utilisateur aux applications web ASP.NET Core. Pour sécuriser les API web et SPA, utilisez l’une des options suivantes :
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Serveur Identity Duende
Duende Identity Server est un framework OpenID Connect et OAuth 2.0 pour ASP.NET Core. Duende Identity Server active les fonctionnalités de sécurité suivantes :
- Authentification en tant que service (AaaS)
- Authentification/déconnexion unique (SSO) sur plusieurs types d’applications
- Contrôle d’accès pour les API
- Passerelle de fédération
Importante
Duende Software peut vous demander de payer des frais de licence pour une utilisation en production de Duende Identity Server. Pour plus d’informations, consultez Migrer de ASP.NET Core dans .NET 5 vers .NET 6.
Pour plus d’informations, consultez la documentation Duende Identity Server (site web de Duende Software).
Affichez ou téléchargez l’exemple de code (procédure de téléchargement).
Créer un Blazor Web App avec authentification
Créez un projet ASP.NET Core Blazor Web App avec des comptes individuels.
Remarque
Pour une Razor expérience Pages, consultez la section Créer une Razor application Pages avec authentification .
Pour une expérience MVC, consultez la section Créer une application MVC avec authentification .
- Sélectionnez le Blazor Web App modèle. Cliquez sur Suivant.
- Effectuez les sélections suivantes :
- Type d’authentification : Comptes individuels
- Mode de rendu interactif : Serveur
- Emplacement d’interactivité : Global
- Cliquez sur Créer.
Le projet généré inclut des IdentityRazor composants. Les composants se trouvent dans le Components/Account
dossier. Par exemple :
/Components/Account/Pages/Register
/Components/Account/Pages/Login
/Components/Account/Pages/Manage/ChangePassword
Identity
Razor les composants sont décrits individuellement dans la documentation pour des cas d’usage spécifiques et sont susceptibles de modifier chaque version. Lorsque vous générez un projet avec des comptes individuels, les composants Blazor Web AppIdentity sont inclus dans le projet généré. Les IdentityRazor composants peuvent également être inspectés dans le modèle deBlazor projet dans la source de référence ASP.NET Core (dotnet/aspnetcore
référentiel GitHub).
Remarque
Les liens de documentation vers la source de référence .NET chargent généralement la branche par défaut du référentiel, qui représente le développement actuel pour la prochaine version de .NET. Pour sélectionner une balise pour une version spécifique, utilisez la liste déroulante Échanger les branches ou les balises. Pour plus d’informations, consultez Comment sélectionner une balise de version du code source ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Pour plus d’informations, consultez ASP.NET Core Blazor l’authentification et l’autorisation et les articles qui le suivent dans la Blazor documentation. La plupart des articles dans la section de la documentation principale ASP.NET Core sur la sécurité et Identity s'appliquent aux applications Blazor. Toutefois, le Blazor jeu de documentation contient des articles et des conseils qui remplacent ou ajoutent des informations. Nous vous recommandons de commencer par étudier la documentation générale sur ASP.NET Core, puis de consulter les articles de la documentation BlazorSécurité et Identity
Créer une Razor application Pages avec authentification
Créez un projet d’application web principale (Razor pages) ASP.NET avec des comptes individuels.
- Sélectionnez le modèle ASP.NET Core Web App (RazorPages). Cliquez sur Suivant.
- Pour le type d’authentification, sélectionnez Comptes individuels.
- Cliquez sur Créer.
Le projet généré fournit ASP.NET Core Identity en tant que Razor bibliothèque de classes (RCL). La bibliothèque de classes IdentityRazor expose les points de terminaison avec la zone Identity
. Par exemple :
Areas/Identity/Pages/Account/Register
Areas/Identity/Pages/Account/Login
Areas/Identity/Pages/Account/Manage/ChangePassword
Les pages sont décrites individuellement dans la documentation pour des cas d’usage spécifiques et sont susceptibles de modifier chaque version. Pour afficher toutes les pages du RCL, consultez la source de référence ASP.NET Core (dotnet/aspnetcore
référentiel GitHub, Identity/UI/src/Areas/Identity/Pages
dossier). Vous pouvez générer une structure de pages individuelles ou toutes les pages dans l’application. Pour plus d’informations, consultez Génération de modèles automatiqueIdentity dans les projets ASP.NET Core.
Créer une application MVC avec authentification
Créez un projet ASP.NET Core MVC avec des comptes individuels.
- Sélectionnez le modèle ASP.NET Core Web App (Model-View-Controller). Cliquez sur Suivant.
- Pour le type d’authentification, sélectionnez Comptes individuels.
- Cliquez sur Créer.
Le projet généré fournit ASP.NET Core Identity en tant que Razor bibliothèque de classes (RCL). La bibliothèque de classes IdentityRazor est basée sur Razor Pages et expose des points de terminaison avec la zone Identity
. Par exemple :
Areas/Identity/Pages/Account/Register
Areas/Identity/Pages/Account/Login
Areas/Identity/Pages/Account/Manage/ChangePassword
Les pages sont décrites individuellement dans la documentation pour des cas d’usage spécifiques et sont susceptibles de modifier chaque version. Pour afficher toutes les pages du RCL, consultez la source de référence ASP.NET Core (dotnet/aspnetcore
référentiel GitHub, Identity/UI/src/Areas/Identity/Pages
dossier). Vous pouvez générer une structure de pages individuelles ou toutes les pages dans l’application. Pour plus d’informations, consultez Génération de modèles automatiqueIdentity dans les projets ASP.NET Core.
Appliquer des migrations
Appliquez les migrations pour initialiser la base de données.
Exécutez la commande suivante dans la console du Gestionnaire de package (PMC) :
Update-Database
Tester l’inscription et la connexion
Exécutez l’application et inscrivez un utilisateur. Selon la taille de votre écran, vous devrez peut-être sélectionner le bouton bascule de navigation pour afficher les liens d’inscription et de connexion.
Afficher la base de données Identity
- Dans le menu Affichage, sélectionnez Explorateur d’objets SQL Server (SSOX).
- Accédez à (localdb)MSSQLLocalDB(SQL Server 13). Cliquez avec le bouton droit sur dbo.AspNetUsers>Afficher les données :
Configurer les services Identity
Les services sont ajoutés dans Program.cs
. Le modèle classique consiste à appeler les méthodes dans l’ordre suivant :
Add{Service}
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();
Le code précédent configure Identity avec les valeurs d’option par défaut. Les services sont accessibles à l’application au moyen de l’injection de dépendances.
Identity est activé en appelant UseAuthentication.
UseAuthentication
ajoute un intergiciel d’authentification au pipeline de requêtes.
L’application générée par un modèle n’utilise pas l’autorisation.
app.UseAuthorization
est inclus pour s’assurer qu’il est ajouté dans l’ordre correct si l’application ajoute une autorisation.
UseRouting
, UseAuthentication
et UseAuthorization
doivent être appelés dans l’ordre indiqué dans le code précédent.
Pour plus d’informations sur IdentityOptions
, consultez les articles IdentityOptions et Démarrage d’une application.
Générer automatiquement les modèles Register, Login, LogOut et RegisterConfirmation
Ajoutez les fichiers Register
, Login
, LogOut
et RegisterConfirmation
. Suivez les instructions de Générer l’identité dans un projet Razor avec des instructions d’autorisation pour générer le code montré dans cette section.
Examiner l’inscription
Quand un utilisateur clique sur le bouton d’inscription sur la page Register
, l’action RegisterModel.OnPostAsync
est appelée. L’utilisateur est créé par CreateAsync(TUser) sur l’objet _userManager
:
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();
}
Désactiver la vérification du compte par défaut
Avec les modèles par défaut, l’utilisateur est redirigé vers Account.RegisterConfirmation
où il peut sélectionner un lien pour que le compte soit confirmé. La valeur par défaut Account.RegisterConfirmation
est utilisée uniquement à des fins de test. La vérification automatique du compte doit être désactivée dans une application de production.
Pour exiger un compte confirmé et empêcher la connexion immédiate lors de l’inscription, définissez DisplayConfirmAccountLink = false
dans /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
[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();
}
}
Se connecter
Le formulaire de connexion s’affiche dans les cas suivants :
- Le lien de connexion est sélectionné.
- Un utilisateur tente d’accéder à une page restreinte à laquelle il n’est pas autorisé à accéder ou quand il n’a pas été authentifié par le système.
Quand le formulaire de la page de connexion est envoyé, l’action OnPostAsync
est appelée.
PasswordSignInAsync
est appelé sur l’objet _signInManager
.
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();
}
Pour plus d’informations sur la prise de décisions en ce qui concerne l’autorisation, consultez l’article Présentation de l’autorisation dans ASP.NET Core.
Se déconnecter
Le lien de déconnexion appelle l’action LogoutModel.OnPost
.
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();
}
}
}
}
Dans le code précédent, le code return RedirectToPage();
doit être une redirection afin que le navigateur effectue une nouvelle requête et que l’identité de l’utilisateur soit mise à jour.
SignOutAsync efface les revendications de l’utilisateur stockées dans un cookie.
Post est spécifié dans 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>
Tester Identity
Les modèles de projet web par défaut autorisent l’accès anonyme aux pages d’accueil. Pour tester Identity, ajoutez [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()
{
}
}
}
Si vous êtes connecté, déconnectez-vous. Exécutez l'application et sélectionnez le lien Privacy. Vous êtes redirigé vers la page de connexion.
Explorer Identity
Pour explorer Identity en détail :
- Créer la source complète de l’interface utilisateur d’identité
- Examinez la source de chaque page et effectuez la procédure du débogueur.
Identity Composants
Tous les packages NuGet dépendants d’Identity sont inclus dans l’infrastructure partagée ASP.NET Core.
Le package principal pour Identity est Microsoft.AspNetCore.Identity. Ce package contient l’ensemble d’interfaces de base pour ASP.NET Core Identity et est inclus par Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migration vers ASP.NET Core Identity
Pour plus d’informations et pour obtenir de l’aide sur la migration de votre magasin Identity existant, consultez l’article Migrer l’authentification et Identity.
Définition de la force du mot de passe
Consultez la section sur la configuration pour obtenir un exemple qui définit les exigences minimales relatives aux mots de passe.
AddDefaultIdentity et AddIdentity
AddDefaultIdentity a été introduit dans ASP.NET Core 2.1. L’appel de AddDefaultIdentity
est similaire à l’appel de ce qui suit :
Pour plus d’informations, consultez la section AddDefaultIdentity sources.
Empêcher la publication de ressources Identity statiques
Pour empêcher la publication de ressources Identity statiques (feuilles de style et fichiers JavaScript pour l’interface utilisateur Identity) sur la racine web, ajoutez la propriété et la cible ResolveStaticWebAssetsInputsDependsOn
suivantes RemoveIdentityAssets
au fichier projet de l’application :
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Étapes suivantes
- Authentification et autorisation avec ASP.NET Core Blazor
- Code source ASP.NET Core Identity
- Comment utiliser les rôles dans ASP.NET Core Identity
- Pour plus d’informations sur la configuration Identity à l’aide de SQLite, consultez Comment configurer Identity SQLite (
dotnet/AspNetCore.Docs
#5131) - Configuration de Identity
- Créer une application ASP.NET Core avec des données utilisateur protégées par une autorisation
- Ajouter, télécharger et supprimer des données utilisateur dans Identity dans un projet ASP.NET Core
- Activer la génération de code QR pour les applications d’authentification TOTP dans ASP.NET Core
- Migrer l’authentification et Identity vers ASP.NET Core
- Account confirmation and password recovery in ASP.NET Core (Confirmation de compte et récupération de mot de passe dans ASP.NET Core)
- Authentification multifacteur dans ASP.NET Core
- Hôte ASP.NET Core dans une batterie de serveurs web
Par Rick Anderson
ASP.NET Core Identity :
- Est une API qui prend en charge la fonctionnalité de connexion par interface utilisateur.
- Gère les utilisateurs, les mots de passe, les données de profil, les rôles, les revendications, les jetons, la confirmation par e-mail, etc.
Les utilisateurs peuvent créer un compte avec les informations de connexion stockées dans Identity ou utiliser un fournisseur de connexion externe. Les fournisseurs de connexion externes pris en charge incluent Facebook, Google, Compte Microsoft et Twitter.
Pour plus d’informations sur la façon d’exiger l’authentification globale de tous les utilisateurs, consultez la section Exiger des utilisateurs authentifiés.
Le code source Identity est disponible sur GitHub. Générez automatiquement des modèles Identity et affichez les fichiers générés pour passer en revue l’interaction du modèle avec Identity.
Identity est généralement configuré à l’aide d’une base de données SQL Server pour stocker les noms d’utilisateur, les mots de passe et les données de profil. Vous pouvez également utiliser un autre magasin persistant, par exemple Stockage Table Azure.
Dans cette rubrique, vous allez apprendre à utiliser Identity pour inscrire, connecter et déconnecter un utilisateur. Remarque : les modèles traitent le nom d’utilisateur et l’adresse e-mail comme étant identiques pour les utilisateurs. Pour obtenir des instructions plus détaillées sur la création d’applications qui utilisent Identity, consultez la section Étapes suivantes.
ASP.NET Core Identity n’est pas lié à la plateforme d’identités Microsoft . La plateforme d’identités Microsoft est la suivante :
- Une évolution de la plateforme de développement Azure Active Directory (Azure AD).
- Solution d’identité alternative pour l’authentification et l’autorisation dans les applications ASP.NET Core.
ASP.NET Core Identity ajoute la fonctionnalité de connexion de l’interface utilisateur aux applications web ASP.NET Core. Pour sécuriser les API web et SPA, utilisez l’une des options suivantes :
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Serveur Identity Duende
Duende Identity Server est un framework OpenID Connect et OAuth 2.0 pour ASP.NET Core. Duende Identity Server active les fonctionnalités de sécurité suivantes :
- Authentification en tant que service (AaaS)
- Authentification/déconnexion unique (SSO) sur plusieurs types d’applications
- Contrôle d’accès pour les API
- Passerelle de fédération
Importante
Duende Software peut vous demander de payer des frais de licence pour une utilisation en production de Duende Identity Server. Pour plus d’informations, consultez Migrer de ASP.NET Core dans .NET 5 vers .NET 6.
Pour plus d’informations, consultez la documentation Duende Identity Server (site web de Duende Software).
Affichez ou téléchargez l’exemple de code (procédure de téléchargement).
Créer une application web avec authentification
Créez un projet d’application web ASP.NET Core avec des comptes d’utilisateur individuels.
- Sélectionnez le modèle Application web ASP.NET Core. Nommez le projet WebApp1 pour que l’espace de noms soit le même que le téléchargement du projet. Cliquez sur OK.
- Dans l’entrée Type d’authentification, sélectionnez Comptes d’utilisateur individuels.
Le projet généré fournit ASP.NET Core Identity en tant que bibliothèque de classes Razor. La bibliothèque de classes IdentityRazor expose les points de terminaison avec la zone Identity
. Par exemple :
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Compte/Gérer
Appliquer des migrations
Appliquez les migrations pour initialiser la base de données.
Exécutez la commande suivante dans la console du Gestionnaire de package (PMC) :
Update-Database
Tester l’inscription et la connexion
Exécutez l’application et inscrivez un utilisateur. Selon la taille de votre écran, vous devrez peut-être sélectionner le bouton bascule de navigation pour afficher les liens d’inscription et de connexion.
Afficher la base de données Identity
- Dans le menu Affichage, sélectionnez Explorateur d’objets SQL Server (SSOX).
- Accédez à (localdb)MSSQLLocalDB(SQL Server 13). Cliquez avec le bouton droit sur dbo.AspNetUsers>Afficher les données :
Configurer les services Identity
Les services sont ajoutés dans Program.cs
. Le modèle classique consiste à appeler les méthodes dans l’ordre suivant :
Add{Service}
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();
Le code précédent configure Identity avec les valeurs d’option par défaut. Les services sont accessibles à l’application au moyen de l’injection de dépendances.
Identity est activé en appelant UseAuthentication.
UseAuthentication
ajoute un intergiciel d’authentification au pipeline de requêtes.
L’application générée par un modèle n’utilise pas l’autorisation.
app.UseAuthorization
est inclus pour s’assurer qu’il est ajouté dans l’ordre correct si l’application ajoute une autorisation.
UseRouting
, UseAuthentication
et UseAuthorization
doivent être appelés dans l’ordre indiqué dans le code précédent.
Pour plus d’informations sur IdentityOptions
, consultez les articles IdentityOptions et Démarrage d’une application.
Générer automatiquement les modèles Register, Login, LogOut et RegisterConfirmation
Ajoutez les fichiers Register
, Login
, LogOut
et RegisterConfirmation
. Suivez les instructions de Générer l’identité dans un projet Razor avec des instructions d’autorisation pour générer le code montré dans cette section.
Examiner l’inscription
Quand un utilisateur clique sur le bouton d’inscription sur la page Register
, l’action RegisterModel.OnPostAsync
est appelée. L’utilisateur est créé par CreateAsync(TUser) sur l’objet _userManager
:
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();
}
Désactiver la vérification du compte par défaut
Avec les modèles par défaut, l’utilisateur est redirigé vers Account.RegisterConfirmation
où il peut sélectionner un lien pour que le compte soit confirmé. La valeur par défaut Account.RegisterConfirmation
est utilisée uniquement à des fins de test. La vérification automatique du compte doit être désactivée dans une application de production.
Pour exiger un compte confirmé et empêcher la connexion immédiate lors de l’inscription, définissez DisplayConfirmAccountLink = false
dans /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
[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();
}
}
Se connecter
Le formulaire de connexion s’affiche dans les cas suivants :
- Le lien de connexion est sélectionné.
- Un utilisateur tente d’accéder à une page restreinte à laquelle il n’est pas autorisé à accéder ou quand il n’a pas été authentifié par le système.
Quand le formulaire de la page de connexion est envoyé, l’action OnPostAsync
est appelée.
PasswordSignInAsync
est appelé sur l’objet _signInManager
.
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();
}
Pour plus d’informations sur la prise de décisions en ce qui concerne l’autorisation, consultez l’article Présentation de l’autorisation dans ASP.NET Core.
Se déconnecter
Le lien de déconnexion appelle l’action LogoutModel.OnPost
.
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();
}
}
}
}
Dans le code précédent, le code return RedirectToPage();
doit être une redirection afin que le navigateur effectue une nouvelle requête et que l’identité de l’utilisateur soit mise à jour.
SignOutAsync efface les revendications de l’utilisateur stockées dans un cookie.
Post est spécifié dans 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>
Tester Identity
Les modèles de projet web par défaut autorisent l’accès anonyme aux pages d’accueil. Pour tester Identity, ajoutez [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()
{
}
}
}
Si vous êtes connecté, déconnectez-vous. Exécutez l'application et sélectionnez le lien Privacy. Vous êtes redirigé vers la page de connexion.
Explorer Identity
Pour explorer Identity en détail :
- Créer la source complète de l’interface utilisateur d’identité
- Examinez la source de chaque page et effectuez la procédure du débogueur.
Identity Composants
Tous les packages NuGet dépendants d’Identity sont inclus dans l’infrastructure partagée ASP.NET Core.
Le package principal pour Identity est Microsoft.AspNetCore.Identity. Ce package contient l’ensemble d’interfaces de base pour ASP.NET Core Identity et est inclus par Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migration vers ASP.NET Core Identity
Pour plus d’informations et pour obtenir de l’aide sur la migration de votre magasin Identity existant, consultez l’article Migrer l’authentification et Identity.
Définition de la force du mot de passe
Consultez la section sur la configuration pour obtenir un exemple qui définit les exigences minimales relatives aux mots de passe.
AddDefaultIdentity et AddIdentity
AddDefaultIdentity a été introduit dans ASP.NET Core 2.1. L’appel de AddDefaultIdentity
est similaire à l’appel de ce qui suit :
Pour plus d’informations, consultez la section AddDefaultIdentity sources.
Empêcher la publication de ressources Identity statiques
Pour empêcher la publication de ressources Identity statiques (feuilles de style et fichiers JavaScript pour l’interface utilisateur Identity) sur la racine web, ajoutez la propriété et la cible ResolveStaticWebAssetsInputsDependsOn
suivantes RemoveIdentityAssets
au fichier projet de l’application :
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Étapes suivantes
- Consulter ce problème GitHub pour plus d’informations sur la configuration d’Identity à l’aide de SQLite
- Configuration de Identity
- Créer une application ASP.NET Core avec des données utilisateur protégées par une autorisation
- Ajouter, télécharger et supprimer des données utilisateur dans Identity dans un projet ASP.NET Core
- Activer la génération de code QR pour les applications d’authentification TOTP dans ASP.NET Core
- Migrer l’authentification et Identity vers ASP.NET Core
- Account confirmation and password recovery in ASP.NET Core (Confirmation de compte et récupération de mot de passe dans ASP.NET Core)
- Authentification à deux facteurs avec SMS dans ASP.NET Core
- Hôte ASP.NET Core dans une batterie de serveurs web
Par Rick Anderson
ASP.NET Core Identity :
- Est une API qui prend en charge la fonctionnalité de connexion par interface utilisateur.
- Gère les utilisateurs, les mots de passe, les données de profil, les rôles, les revendications, les jetons, la confirmation par e-mail, etc.
Les utilisateurs peuvent créer un compte avec les informations de connexion stockées dans Identity ou utiliser un fournisseur de connexion externe. Les fournisseurs de connexion externes pris en charge incluent Facebook, Google, Compte Microsoft et Twitter.
Pour plus d’informations sur la façon d’exiger l’authentification globale de tous les utilisateurs, consultez la section Exiger des utilisateurs authentifiés.
Le code source Identity est disponible sur GitHub. Générez automatiquement des modèles Identity et affichez les fichiers générés pour passer en revue l’interaction du modèle avec Identity.
Identity est généralement configuré à l’aide d’une base de données SQL Server pour stocker les noms d’utilisateur, les mots de passe et les données de profil. Vous pouvez également utiliser un autre magasin persistant, par exemple Stockage Table Azure.
Dans cette rubrique, vous allez apprendre à utiliser Identity pour inscrire, connecter et déconnecter un utilisateur. Remarque : les modèles traitent le nom d’utilisateur et l’adresse e-mail comme étant identiques pour les utilisateurs. Pour obtenir des instructions plus détaillées sur la création d’applications qui utilisent Identity, consultez la section Étapes suivantes.
Microsoft identity platform est :
- Une évolution de la plateforme de développement Azure Active Directory (Azure AD).
- Solution d’identité alternative pour l’authentification et l’autorisation dans les applications ASP.NET Core.
- Non liée à ASP.NET Core Identity.
ASP.NET Core Identity ajoute la fonctionnalité de connexion de l’interface utilisateur aux applications web ASP.NET Core. Pour sécuriser les API web et SPA, utilisez l’une des options suivantes :
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende IdentityServer. Duende IdentityServer est un produit tiers.
Duende IdentityServer est un framework OpenID Connect et OAuth 2.0 pour ASP.NET Core. Duende IdentityServer active les fonctionnalités de sécurité suivantes :
- Authentification en tant que service (AaaS)
- Authentification/déconnexion unique (SSO) sur plusieurs types d’applications
- Contrôle d’accès pour les API
- Passerelle de fédération
Pour plus d’informations, consultez la section Vue d’ensemble de Duende IdentityServer.
Pour plus d’informations sur les autres fournisseurs d’authentification, consultez Options d’authentification de la communauté Open Source pour ASP.NET Core
Affichez ou téléchargez l’exemple de code (procédure de téléchargement).
Créer une application web avec authentification
Créez un projet d’application web ASP.NET Core avec des comptes d’utilisateur individuels.
- Sélectionnez Fichier>Nouveau>Projet.
- Sélectionnez Application web ASP.NET Core. Nommez le projet WebApp1 pour que l’espace de noms soit le même que le téléchargement du projet. Cliquez sur OK.
- Sélectionnez une application web ASP.NET Core, puis sélectionnez Modifier l’authentification.
- Sélectionnez Comptes d’utilisateur individuels, puis cliquez sur OK.
Le projet généré fournit ASP.NET Core Identity en tant que bibliothèque de classes Razor. La bibliothèque de classes IdentityRazor expose les points de terminaison avec la zone Identity
. Par exemple :
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Compte/Gérer
Appliquer des migrations
Appliquez les migrations pour initialiser la base de données.
Exécutez la commande suivante dans la console du Gestionnaire de package (PMC) :
PM> Update-Database
Tester l’inscription et la connexion
Exécutez l’application et inscrivez un utilisateur. Selon la taille de votre écran, vous devrez peut-être sélectionner le bouton bascule de navigation pour afficher les liens d’inscription et de connexion.
Afficher la base de données Identity
- Dans le menu Affichage, sélectionnez Explorateur d’objets SQL Server (SSOX).
- Accédez à (localdb)MSSQLLocalDB(SQL Server 13). Cliquez avec le bouton droit sur dbo.AspNetUsers>Afficher les données :
Configurer les services Identity
Les services sont ajoutés dans ConfigureServices
. Le modèle par défaut consiste à appeler toutes les méthodes Add{Service}
, puis toutes les méthodes services.Configure{Service}
.
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;
});
}
Le code mise en surbrillance précédent configure Identity avec les valeurs d’option par défaut. Les services sont accessibles à l’application au moyen de l’injection de dépendances.
Identity est activé en appelant UseAuthentication.
UseAuthentication
ajoute un intergiciel d’authentification au pipeline de requêtes.
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;
});
}
Le code précédent configure Identity avec les valeurs d’option par défaut. Les services sont accessibles à l’application au moyen de l’injection de dépendances.
Identity est activé en appelant UseAuthentication.
UseAuthentication
ajoute un intergiciel d’authentification au pipeline de requêtes.
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();
});
}
L’application générée par un modèle n’utilise pas l’autorisation.
app.UseAuthorization
est inclus pour s’assurer qu’il est ajouté dans l’ordre correct si l’application ajoute une autorisation.
UseRouting
, UseAuthentication
, UseAuthorization
et UseEndpoints
doivent être appelés dans l’ordre indiqué dans le code précédent.
Pour plus d’informations sur IdentityOptions
et Startup
, consultez les articles IdentityOptions et Démarrage d’une application.
Générer automatiquement les modèles Register, Login, LogOut et RegisterConfirmation
Ajoutez les fichiers Register
, Login
, LogOut
et RegisterConfirmation
. Suivez les instructions de Générer l’identité dans un projet Razor avec des instructions d’autorisation pour générer le code montré dans cette section.
Examiner l’inscription
Quand un utilisateur clique sur le bouton d’inscription sur la page Register
, l’action RegisterModel.OnPostAsync
est appelée. L’utilisateur est créé par CreateAsync(TUser) sur l’objet _userManager
:
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();
}
Désactiver la vérification du compte par défaut
Avec les modèles par défaut, l’utilisateur est redirigé vers Account.RegisterConfirmation
où il peut sélectionner un lien pour que le compte soit confirmé. La valeur par défaut Account.RegisterConfirmation
est utilisée uniquement à des fins de test. La vérification automatique du compte doit être désactivée dans une application de production.
Pour exiger un compte confirmé et empêcher la connexion immédiate lors de l’inscription, définissez DisplayConfirmAccountLink = false
dans /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
[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();
}
}
Se connecter
Le formulaire de connexion s’affiche dans les cas suivants :
- Le lien de connexion est sélectionné.
- Un utilisateur tente d’accéder à une page restreinte à laquelle il n’est pas autorisé à accéder ou quand il n’a pas été authentifié par le système.
Quand le formulaire de la page de connexion est envoyé, l’action OnPostAsync
est appelée.
PasswordSignInAsync
est appelé sur l’objet _signInManager
.
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();
}
Pour plus d’informations sur la prise de décisions en ce qui concerne l’autorisation, consultez l’article Présentation de l’autorisation dans ASP.NET Core.
Se déconnecter
Le lien de déconnexion appelle l’action LogoutModel.OnPost
.
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();
}
}
}
}
Dans le code précédent, le code return RedirectToPage();
doit être une redirection afin que le navigateur effectue une nouvelle requête et que l’identité de l’utilisateur soit mise à jour.
SignOutAsync efface les revendications de l’utilisateur stockées dans un cookie.
Post est spécifié dans 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>
Tester Identity
Les modèles de projet web par défaut autorisent l’accès anonyme aux pages d’accueil. Pour tester Identity, ajoutez [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()
{
}
}
}
Si vous êtes connecté, déconnectez-vous. Exécutez l'application et sélectionnez le lien Privacy. Vous êtes redirigé vers la page de connexion.
Explorer Identity
Pour explorer Identity en détail :
- Créer la source complète de l’interface utilisateur d’identité
- Examinez la source de chaque page et effectuez la procédure du débogueur.
Identity Composants
Tous les packages NuGet dépendants d’Identity sont inclus dans l’infrastructure partagée ASP.NET Core.
Le package principal pour Identity est Microsoft.AspNetCore.Identity. Ce package contient l’ensemble d’interfaces de base pour ASP.NET Core Identity et est inclus par Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migration vers ASP.NET Core Identity
Pour plus d’informations et pour obtenir de l’aide sur la migration de votre magasin Identity existant, consultez l’article Migrer l’authentification et Identity.
Définition de la force du mot de passe
Consultez la section sur la configuration pour obtenir un exemple qui définit les exigences minimales relatives aux mots de passe.
Empêcher la publication de ressources Identity statiques
Pour empêcher la publication de ressources Identity statiques (feuilles de style et fichiers JavaScript pour l’interface utilisateur Identity) sur la racine web, ajoutez la propriété et la cible ResolveStaticWebAssetsInputsDependsOn
suivantes RemoveIdentityAssets
au fichier projet de l’application :
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Étapes suivantes
- Code source ASP.NET Core Identity
- Source AddDefaultIdentity
- Consulter ce problème GitHub pour plus d’informations sur la configuration d’Identity à l’aide de SQLite
- Configuration de Identity
- Créer une application ASP.NET Core avec des données utilisateur protégées par une autorisation
- Ajouter, télécharger et supprimer des données utilisateur dans Identity dans un projet ASP.NET Core
- Activer la génération de code QR pour les applications d’authentification TOTP dans ASP.NET Core
- Migrer l’authentification et Identity vers ASP.NET Core
- Account confirmation and password recovery in ASP.NET Core (Confirmation de compte et récupération de mot de passe dans ASP.NET Core)
- Authentification à deux facteurs avec SMS dans ASP.NET Core
- Hôte ASP.NET Core dans une batterie de serveurs web