Utiliser l'cookieauthentification sans ASP.NET CoreIdentity
Par Rick Anderson
ASP.NET Core Identity est un fournisseur d'authentification complet et complet pour la création et la maintenance des connexions. Cependant, un cookiefournisseur d'authentification basé sur – sans ASP.NET Core Identity peut être utilisé. Pour plus d’informations, consultez Présentation de Identity sur ASP.NET Core.
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
À des fins de démonstration dans l'exemple d'application, le compte d'utilisateur de l'utilisateur hypothétique, Maria Rodriguez, est codé en dur dans l'application. Utilisez l'adresseEmail maria.rodriguez@contoso.com
et un mot de passe pour vous connecter à l'utilisateur. L'utilisateur est authentifié dans la méthode AuthenticateUser
du fichier Pages/Account/Login.cshtml.cs
. Dans un exemple concret, l'utilisateur serait authentifié par rapport à un magasin de données.
Ajouter une authentification cookie
- Ajoutez les services Authentication Middleware avec les méthodes AddAuthentication et AddCookie.
- Appelez UseAuthentication et UseAuthorization pour définir la propriété
HttpContext.User
et exécuter le middleware d'autorisation pour les demandes.UseAuthentication
etUseAuthorization
doit être appelé avant de méthodesMap
telles que MapRazorPages et MapDefaultControllerRoute
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
builder.Services.AddHttpContextAccessor();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
AuthenticationScheme passé à AddAuthentication
définit le schéma d'authentification par défaut pour l'application. AuthenticationScheme
est utile lorsqu'il existe plusieurs instances d'authentification cookie et que l'application doit autoriser avec un schéma spécifique. La définition de AuthenticationScheme
sur CookieAuthenticationDefaults.AuthenticationScheme donne une valeur de "Cookies"
pour le schéma. Toute valeur de chaîne peut être utilisée pour distinguer le schéma.
Le schéma d'authentification de l'application est différent du schéma d'authentification de l'application cookie. Lorsqu'un schéma d'authentification cookie n'est pas fourni à AddCookie, il utilise CookieAuthenticationDefaults.AuthenticationScheme
. La CookieAuthenticationDefaults.AuthenticationScheme
source GitHub indique qu'elle est définie sur "Cookies"
.
La propriété cookie authentification IsEssential est définie sur true
par défaut. Les cookies d’authentification sont autorisés lorsque le visiteur du site n’a pas consenti à la collecte de données. Pour plus d’informations, consultez Prise en charge du règlement général sur la protection des données (RGPD) de l’Union Européenne dans ASP.NET Core.
La classe CookieAuthenticationOptions est utilisée pour configurer les options du fournisseur d'authentification.
Configurez CookieAuthenticationOptions dans la méthode AddCookie :
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.SlidingExpiration = true;
options.AccessDeniedPath = "/Forbidden/";
});
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
Cookie Intergiciel Azure Policy
L’intergiciel de stratégie Cookie (source GitHub) UseCookiePolicy active les fonctionnalités de stratégie cookie. Le middleware est traité dans l'ordre dans lequel il est ajouté :
app.UseCookiePolicy(cookiePolicyOptions);
Utilisez les CookiePolicyOptions fournies au middleware de stratégie de Cookie pour contrôler les caractéristiques globales du traitement des cookie et vous connecter aux gestionnaires de traitement des cookie lorsque des cookies sont ajoutés ou supprimés.
La valeur MinimumSameSitePolicy par défaut SameSiteMode.Lax
est d'autoriser l'authentification OAuth2. Pour appliquer strictement une politique de même site de SameSiteMode.Strict
, définissez le MinimumSameSitePolicy
. Bien que ce paramètre rompe OAuth2 et d'autres schémas d'authentification cross-origin, il élève le niveau de sécurité cookie pour d'autres types d'applications qui ne reposent pas sur le traitement des requêtes cross-origin.
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
};
Le paramètre Policy Middleware Cookie pour MinimumSameSitePolicy
peut affecter le paramètre de Cookie.SameSite
dans les paramètres CookieAuthenticationOptions
selon la matrice ci-dessous.
MinimumSameSitePolicy | Cookie.SameSite | Paramètre Cookie.SameSite résultant |
---|---|---|
SameSiteMode.None | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict SameSiteMode.Strict SameSiteMode.Strict |
Créer une authentification cookie
Pour créer un fichier d'informations sur l'utilisateur cookie, construisez un fichier ClaimsPrincipal. Les informations utilisateur sont sérialisées et stockées dans le fichier cookie.
Créez un ClaimsIdentity avec tous les Claim requis et appelez SignInAsync pour connecter l'utilisateur. Login.cshtml.cs
dans l’échantillon d’application contient le code suivant :
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
ReturnUrl = returnUrl;
if (ModelState.IsValid)
{
// Use Input.Email and Input.Password to authenticate the user
// with your custom authentication logic.
//
// For demonstration purposes, the sample validates the user
// on the email address maria.rodriguez@contoso.com with
// any password that passes model validation.
var user = await AuthenticateUser(Input.Email, Input.Password);
if (user == null)
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed.
//ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
// The time at which the authentication ticket expires. A
// value set here overrides the ExpireTimeSpan option of
// CookieAuthenticationOptions set with AddCookie.
//IsPersistent = true,
// Whether the authentication session is persisted across
// multiple requests. When used with cookies, controls
// whether the cookie's lifetime is absolute (matching the
// lifetime of the authentication ticket) or session-based.
//IssuedUtc = <DateTimeOffset>,
// The time at which the authentication ticket was issued.
//RedirectUri = <string>
// The full path or absolute URI to be used as an http
// redirect response value.
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
_logger.LogInformation("User {Email} logged in at {Time}.",
user.Email, DateTime.UtcNow);
return LocalRedirect(Url.GetLocalUrl(returnUrl));
}
// Something failed. Redisplay the form.
return Page();
}
Si vous souhaitez voir les commentaires de code traduits dans une langue autre que l’anglais, dites-le nous dans cette discussion GitHub.
SignInAsync
crée un crypté cookie et l'ajoute à la réponse actuelle. Si AuthenticationScheme
n'est pas spécifié, le schéma par défaut est utilisé.
RedirectUri n'est utilisé que sur quelques chemins spécifiques par défaut, par exemple, le chemin de connexion et les chemins de déconnexion. Pour plus d’informations, consultez la source CookieAuthenticationHandler.
Le système de protection des données ASP.NET Core est utilisé pour le chiffrement. Pour une application hébergée sur plusieurs machines, l'équilibrage de charge entre les applications ou l'utilisation d'une batterie de serveurs Web, configurez la protection des données pour utiliser le même trousseau de clés et le même identifiant d'application.
Se déconnecter
Pour déconnecter l'utilisateur actuel et supprimer son cookie, appelez SignOutAsync :
public async Task OnGetAsync(string returnUrl = null)
{
if (!string.IsNullOrEmpty(ErrorMessage))
{
ModelState.AddModelError(string.Empty, ErrorMessage);
}
// Clear the existing external cookie
await HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
ReturnUrl = returnUrl;
}
Si CookieAuthenticationDefaults.AuthenticationScheme
ou « Cookies » n’est pas utilisé comme schéma, indiquez le schéma utilisé lors de la configuration du fournisseur d’authentification. Sinon, le schéma par défaut est utilisé. Par exemple, si « ContosoCookie » est utilisé comme schéma, indiquez le schéma utilisé lors de la configuration du fournisseur d’authentification.
Lorsque le navigateur se ferme, il supprime automatiquement les cookies basés sur la session (cookies non persistants), mais aucun cookie n’est effacé lorsqu’un onglet individuel est fermé. Le serveur n'est pas averti des événements de fermeture d'onglet ou de navigateur.
Réagir aux modifications back-end
Une fois que le cookie a été créé, le cookie est la seule source d’identity. Si un compte utilisateur est désactivé dans les systèmes back-end :
- Le système cookie d'authentification de l'application continue de traiter les requêtes en fonction de l'authentification cookie.
- L'utilisateur reste connecté à l'application tant que l'authentification cookie est valide.
L’événement ValidatePrincipal peut être utilisé pour intercepter et remplacer la validation de l’identity du cookie. La validation du cookie à chaque requête réduit le risque que des utilisateurs révoqués accèdent à l'application.
Une approche de la validation cookie est basée sur le suivi du moment où la base de données utilisateur change. Si la base de données n'a pas été modifiée depuis la création de l'utilisateur cookie, il n'est pas nécessaire de ré-authentifier l'utilisateur si celui-ci cookie est toujours valide. Dans l'exemple d'application, la base de données est implémentée dans IUserRepository
et stocke une valeur LastChanged
. Lorsqu'un utilisateur est mis à jour dans la base de données, la valeur LastChanged
est définie sur l'heure actuelle.
Afin d'invalider un cookie lorsque la base de données change en fonction de la valeur LastChanged
, créez le cookie avec une revendication LastChanged
contenant la valeur actuelle LastChanged
de la base de données :
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("LastChanged", {Database Value})
};
var claimsIdentity = new ClaimsIdentity(
claims,
CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));
Pour implémenter un override pour l'événement ValidatePrincipal
, écrivez une méthode avec la signature suivante dans une classe qui dérive de CookieAuthenticationEvents :
ValidatePrincipal(CookieValidatePrincipalContext)
Voici un exemple d'implémentation de CookieAuthenticationEvents
:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
private readonly IUserRepository _userRepository;
public CustomCookieAuthenticationEvents(IUserRepository userRepository)
{
_userRepository = userRepository;
}
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
var userPrincipal = context.Principal;
// Look for the LastChanged claim.
var lastChanged = (from c in userPrincipal.Claims
where c.Type == "LastChanged"
select c.Value).FirstOrDefault();
if (string.IsNullOrEmpty(lastChanged) ||
!_userRepository.ValidateLastChanged(lastChanged))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
Enregistrez l'instance d'événements lors de l'enregistrement du service cookie. Fournissez une inscription au service étendu pour votre classe CustomCookieAuthenticationEvents
:
using Microsoft.AspNetCore.Authentication.Cookies;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.EventsType = typeof(CustomCookieAuthenticationEvents);
});
builder.Services.AddScoped<CustomCookieAuthenticationEvents>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapDefaultControllerRoute();
app.Run();
Considérez une situation dans laquelle le nom de l'utilisateur est mis à jour—une décision qui n'affecte en rien la sécurité. Si vous souhaitez mettre à jour de manière non destructive le principal de l'utilisateur, appelez context.ReplacePrincipal
et définissez la propriété context.ShouldRenew
sur true
.
Avertissement
L'approche décrite ici est déclenchée à chaque requête. La validation des cookies d’authentification pour tous les utilisateurs à chaque requête peut entraîner une baisse importante des performances de l’application.
Cookies persistants
Vous souhaiterez peut-être cookie que le persiste d'une session de navigateur à l'autre. Cette persistance ne doit être activée qu'avec le consentement explicite de l'utilisateur avec une case à cocher "Se souvenir de moi" lors de la connexion ou un mécanisme similaire.
L’extrait de code suivant crée une identity et un cookie correspondant qui survivent aux fermetures de navigateur. Tous les paramètres d'expiration glissants précédemment configurés sont honorés. Si le cookie expire alors que le navigateur est fermé, le navigateur efface le cookie une fois qu'il est redémarré.
Définissez IsPersistent sur true
dans AuthenticationProperties :
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true
});
Expiration absolue cookie
Un délai d'expiration absolu peut être défini avec ExpiresUtc. Pour créer un persistent cookie, IsPersistent
doit également être défini. Sinon, le cookie est créé avec une durée de vie basée sur la session et peut expirer avant ou après le ticket d'authentification qu'il contient. Lorsque ExpiresUtc
est défini, il remplace la valeur de l'option ExpireTimeSpan de CookieAuthenticationOptions, si elle est définie.
L’extrait de code suivant crée une identity et un cookie correspondant qui dure 20 minutes. Cela ignore tous les paramètres d'expiration glissants précédemment configurés.
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
});
ASP.NET Core Identity est un fournisseur d'authentification complet et complet pour la création et la maintenance des connexions. Cependant, un cookiefournisseur d'authentification basé sur – sans ASP.NET Core Identity peut être utilisé. Pour plus d’informations, consultez Présentation de Identity sur ASP.NET Core.
Affichez ou téléchargez l’exemple de code (procédure de téléchargement)
À des fins de démonstration dans l'exemple d'application, le compte d'utilisateur de l'utilisateur hypothétique, Maria Rodriguez, est codé en dur dans l'application. Utilisez l'adresseEmail maria.rodriguez@contoso.com
et un mot de passe pour vous connecter à l'utilisateur. L'utilisateur est authentifié dans la méthode AuthenticateUser
du fichier Pages/Account/Login.cshtml.cs
. Dans un exemple concret, l'utilisateur serait authentifié par rapport à une base de données.
Configuration
Dans la méthode Startup.ConfigureServices
, créez les services Authentication Middleware avec les méthodes AddAuthentication et AddCookie :
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie();
AuthenticationScheme passé à AddAuthentication
définit le schéma d'authentification par défaut pour l'application. AuthenticationScheme
est utile lorsqu'il existe plusieurs instances d'authentification cookie et que vous souhaitez autoriser avec un schéma spécifique. La définition de AuthenticationScheme
sur CookieAuthenticationDefaults.AuthenticationScheme donne une valeur de « Cookies » pour le schéma. Vous pouvez fournir n'importe quelle valeur de chaîne qui distingue le schéma.
Le schéma d'authentification de l'application est différent du schéma d'authentification de l'application cookie. Lorsqu’un schéma de cookie d’authentification n’est pas fourni à AddCookie, il utilise CookieAuthenticationDefaults.AuthenticationScheme
(« Cookies »).
La propriété cookie authentification IsEssential est définie sur true
par défaut. Les cookies d’authentification sont autorisés lorsque le visiteur du site n’a pas consenti à la collecte de données. Pour plus d’informations, consultez Prise en charge du règlement général sur la protection des données (RGPD) de l’Union Européenne dans ASP.NET Core.
Dans Startup.Configure
, appelez UseAuthentication
et UseAuthorization
pour définir la propriété HttpContext.User
et exécutez le middleware d'autorisation pour les demandes. Appelez les méthodes UseAuthentication
et UseAuthorization
avant d'appeler UseEndpoints
:
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
La classe CookieAuthenticationOptions est utilisée pour configurer les options du fournisseur d'authentification.
Défini CookieAuthenticationOptions
dans la configuration du service pour l'authentification dans la méthode Startup.ConfigureServices
:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
...
});
Cookie Intergiciel Azure Policy
Cookie L'intergiciel Azure Policy active les capacités de politiquecookie. L'ajout du middleware au pipeline de traitement des applications est sensible à l'ordre—il n'affecte que les composants en aval enregistrés dans le pipeline.
app.UseCookiePolicy(cookiePolicyOptions);
Utilisez les CookiePolicyOptions fournies au middleware de stratégie de Cookie pour contrôler les caractéristiques globales du traitement des cookie et vous connecter aux gestionnaires de traitement des cookie lorsque des cookies sont ajoutés ou supprimés.
La valeur MinimumSameSitePolicy par défaut SameSiteMode.Lax
est d'autoriser l'authentification OAuth2. Pour appliquer strictement une politique de même site de SameSiteMode.Strict
, définissez le MinimumSameSitePolicy
. Bien que ce paramètre rompe OAuth2 et d'autres schémas d'authentification cross-origin, il élève le niveau de sécurité cookie pour d'autres types d'applications qui ne reposent pas sur le traitement des requêtes cross-origin.
var cookiePolicyOptions = new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.Strict,
};
Le paramètre Policy Middleware Cookie pour MinimumSameSitePolicy
peut affecter le paramètre de Cookie.SameSite
dans les paramètres CookieAuthenticationOptions
selon la matrice ci-dessous.
MinimumSameSitePolicy | Cookie.SameSite | Paramètre Cookie.SameSite résultant |
---|---|---|
SameSiteMode.None | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Lax SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict | SameSiteMode.None SameSiteMode.Lax SameSiteMode.Strict |
SameSiteMode.Strict SameSiteMode.Strict SameSiteMode.Strict |
Créer une authentification cookie
Pour créer un fichier d'informations sur l'utilisateur cookie, construisez un fichier ClaimsPrincipal. Les informations utilisateur sont sérialisées et stockées dans le fichier cookie.
Créez un ClaimsIdentity avec tous les Claims requis et appelez SignInAsync pour vous connecter à l'utilisateur :
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("FullName", user.FullName),
new Claim(ClaimTypes.Role, "Administrator"),
};
var claimsIdentity = new ClaimsIdentity(
claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties
{
//AllowRefresh = <bool>,
// Refreshing the authentication session should be allowed.
//ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
// The time at which the authentication ticket expires. A
// value set here overrides the ExpireTimeSpan option of
// CookieAuthenticationOptions set with AddCookie.
//IsPersistent = true,
// Whether the authentication session is persisted across
// multiple requests. When used with cookies, controls
// whether the cookie's lifetime is absolute (matching the
// lifetime of the authentication ticket) or session-based.
//IssuedUtc = <DateTimeOffset>,
// The time at which the authentication ticket was issued.
//RedirectUri = <string>
// The full path or absolute URI to be used as an http
// redirect response value.
};
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
authProperties);
Si vous souhaitez voir les commentaires de code traduits dans une langue autre que l’anglais, dites-le nous dans cette discussion GitHub.
SignInAsync
crée un crypté cookie et l'ajoute à la réponse actuelle. Si AuthenticationScheme
n'est pas spécifié, le schéma par défaut est utilisé.
RedirectUri n'est utilisé que sur quelques chemins spécifiques par défaut, par exemple, le chemin de connexion et les chemins de déconnexion. Pour plus d’informations, consultez la source CookieAuthenticationHandler.
Le système de protection des données ASP.NET Core est utilisé pour le chiffrement. Pour une application hébergée sur plusieurs machines, l'équilibrage de charge entre les applications ou l'utilisation d'une batterie de serveurs Web, configurez la protection des données pour utiliser le même trousseau de clés et le même identifiant d'application.
Se déconnecter
Pour déconnecter l'utilisateur actuel et supprimer son cookie, appelez SignOutAsync :
await HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
Si CookieAuthenticationDefaults.AuthenticationScheme
(ou « Cookies ») n’est pas utilisé comme schéma (par exemple, « ContosoCookie »), indiquez le schéma utilisé lors de la configuration du fournisseur d’authentification. Sinon, le schéma par défaut est utilisé.
Lorsque le navigateur se ferme, il supprime automatiquement les cookies basés sur la session (cookies non persistants), mais aucun cookie n’est effacé lorsqu’un onglet individuel est fermé. Le serveur n'est pas averti des événements de fermeture d'onglet ou de navigateur.
Réagir aux modifications back-end
Une fois que le cookie a été créé, le cookie est la seule source d’identity. Si un compte utilisateur est désactivé dans les systèmes back-end :
- Le système cookie d'authentification de l'application continue de traiter les requêtes en fonction de l'authentification cookie.
- L'utilisateur reste connecté à l'application tant que l'authentification cookie est valide.
L’événement ValidatePrincipal peut être utilisé pour intercepter et remplacer la validation de l’identity du cookie. La validation du cookie à chaque requête réduit le risque que des utilisateurs révoqués accèdent à l'application.
Une approche de la validation cookie est basée sur le suivi du moment où la base de données utilisateur change. Si la base de données n'a pas été modifiée depuis la création de l'utilisateur cookie, il n'est pas nécessaire de ré-authentifier l'utilisateur si celui-ci cookie est toujours valide. Dans l'exemple d'application, la base de données est implémentée dans IUserRepository
et stocke une valeur LastChanged
. Lorsqu'un utilisateur est mis à jour dans la base de données, la valeur LastChanged
est définie sur l'heure actuelle.
Afin d'invalider un cookie lorsque la base de données change en fonction de la valeur LastChanged
, créez le cookie avec une revendication LastChanged
contenant la valeur actuelle LastChanged
de la base de données :
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.Email),
new Claim("LastChanged", {Database Value})
};
var claimsIdentity = new ClaimsIdentity(
claims,
CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity));
Pour implémenter un override pour l'événement ValidatePrincipal
, écrivez une méthode avec la signature suivante dans une classe qui dérive de CookieAuthenticationEvents :
ValidatePrincipal(CookieValidatePrincipalContext)
Voici un exemple d'implémentation de CookieAuthenticationEvents
:
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
private readonly IUserRepository _userRepository;
public CustomCookieAuthenticationEvents(IUserRepository userRepository)
{
// Get the database from registered DI services.
_userRepository = userRepository;
}
public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
{
var userPrincipal = context.Principal;
// Look for the LastChanged claim.
var lastChanged = (from c in userPrincipal.Claims
where c.Type == "LastChanged"
select c.Value).FirstOrDefault();
if (string.IsNullOrEmpty(lastChanged) ||
!_userRepository.ValidateLastChanged(lastChanged))
{
context.RejectPrincipal();
await context.HttpContext.SignOutAsync(
CookieAuthenticationDefaults.AuthenticationScheme);
}
}
}
Enregistrez l'instance d'événements lors cookie de l'enregistrement du service Startup.ConfigureServices
. Fournissez une inscription au service étendu pour votre classe CustomCookieAuthenticationEvents
:
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.EventsType = typeof(CustomCookieAuthenticationEvents);
});
services.AddScoped<CustomCookieAuthenticationEvents>();
Considérez une situation dans laquelle le nom de l'utilisateur est mis à jour—une décision qui n'affecte en rien la sécurité. Si vous souhaitez mettre à jour de manière non destructive le principal de l'utilisateur, appelez context.ReplacePrincipal
et définissez la propriété context.ShouldRenew
sur true
.
Avertissement
L'approche décrite ici est déclenchée à chaque requête. La validation des cookies d’authentification pour tous les utilisateurs à chaque requête peut entraîner une baisse importante des performances de l’application.
Cookies persistants
Vous souhaiterez peut-être cookie que le persiste d'une session de navigateur à l'autre. Cette persistance ne doit être activée qu'avec le consentement explicite de l'utilisateur avec une case à cocher "Se souvenir de moi" lors de la connexion ou un mécanisme similaire.
L’extrait de code suivant crée une identity et un cookie correspondant qui survivent aux fermetures de navigateur. Tous les paramètres d'expiration glissants précédemment configurés sont honorés. Si le cookie expire alors que le navigateur est fermé, le navigateur efface le cookie une fois qu'il est redémarré.
Définissez IsPersistent sur true
dans AuthenticationProperties :
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true
});
Expiration absolue cookie
Un délai d'expiration absolu peut être défini avec ExpiresUtc. Pour créer un persistent cookie, IsPersistent
doit également être défini. Sinon, le cookie est créé avec une durée de vie basée sur la session et peut expirer avant ou après le ticket d'authentification qu'il contient. Lorsque ExpiresUtc
est défini, il remplace la valeur de l'option ExpireTimeSpan de CookieAuthenticationOptions, si elle est définie.
L’extrait de code suivant crée une identity et un cookie correspondant qui dure 20 minutes. Cela ignore tous les paramètres d'expiration glissants précédemment configurés.
// using Microsoft.AspNetCore.Authentication;
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(claimsIdentity),
new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
});