J'ai besoin d'invalider et de déconnecter immédiatement toutes les autres sessions connectées lorsqu'un utilisateur change son mot de passe, mais de permettre à la session active (qui vient de mettre à jour son mot de passe) de rester connectée.
Pour ce faire, j'utilise le UpdateSecurityStampAsync(currentUser.Id);
sur le UserManager. Toutes les autres sessions sont déconnectées avec succès, mais la session active est également déconnectée malgré l'appel à la méthode SignInAsync
après avoir mis à jour le timbre de sécurité.
La configuration de l'identité que j'utilise est la suivante :
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
validateInterval: TimeSpan.FromMinutes(0),
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
},
CookieHttpOnly = true,
CookieSecure = CookieSecureOption.SameAsRequest,
SlidingExpiration = false,
ExpireTimeSpan = TimeSpan.FromMinutes(10)
});
L'extrait de code du contrôleur qui met à jour le mot de passe, le cachet de sécurité et qui est censé reconnecter l'utilisateur actuel est le suivant :
var updateResult = await _userManager.ChangePasswordAsync(currentUser.Id, form.CurrentPassword, form.NewPassword);
if (!updateResult.Succeeded)
{
//handle update failure
}
_signInManager.AuthenticationManager.SignOut();
//updating the security stamp invalidates all other sessions
await _userManager.UpdateSecurityStampAsync(currentUser.Id);
await _signInManager.SignInAsync(currentUser, false, false);
En exécutant le code, le mot de passe est mis à jour avec succès et toutes les sessions sont déconnectées en raison de la mise à jour du timbre de sécurité. Mais d'après d'autres exemples que j'ai vus (comme celui-ci réponse de Chris ), le code ci-dessus devrait rafraîchir le cookie d'authentification et maintenir la connexion de l'utilisateur actif.
J'ai essayé différentes variantes du code ci-dessus :
- Déplacement de l'affichage après la mise à jour du timbre de sécurité.
- Suppression pure et simple de la signalisation
- Utilisation de la fonction synchrone
SignIn
au lieu de la méthode asynchrone
toutes les variations produisent le même résultat : L'utilisateur est obligé de se reconnecter après avoir changé son mot de passe.
Y a-t-il une erreur de configuration ou quelque chose d'autre que j'ai négligé ?
EDIT : J'ai involontairement corrigé le problème en ajoutant l'option DefaultAuthenticationTypes
dans le SignOut
appeler.
Le code pertinent se lit désormais comme suit :
//updating the security stamp invalidates all other sessions
await _userManager.UpdateSecurityStampAsync(currentUser.Id);
_signInManager.AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
await _signInManager.SignInAsync(currentUser, false, false);
Cependant, si quelqu'un pouvait expliquer pourquoi le type d'authentification est important dans ce cas ?