J'ai un site Web asp.net qui utilise l'authentification par formulaires. Je conserve quelques éléments dans les sessions, tels que nom d'utilisateur, identifiant utilisateur, courrier électronique, etc.
J'autorise l'utilisateur à rester connecté au site Web en définissant une longue date d'expiration sur le cookie d'authentification. Il est donc très courant que la session expire alors que l'utilisateur est toujours authentifié.
Le problème que je rencontre est que parfois la session de l'utilisateur expire, mais ils sont toujours authentifiés. Ainsi, par exemple, une de mes pages utilisateur (qui nécessite une authentification) dira "Bienvenue Mike" lorsque leur session sera active, mais une fois celle-ci expirée, elle indiquera "Bienvenue [blanc]" car les informations ne sont plus dans la session, mais sont toujours authentifiés.
Quelle est la meilleure façon de gérer cela? Dois-je resynchroniser les informations de session lorsque les informations ne sont plus là? Ou devrais-je déplacer les informations de l'utilisateur (nom d'utilisateur, ID utilisateur, email) dans les cookies et ne pas m'inquiéter des délais de session?
Je ne veux pas définir la durée de la session à 60 minutes ou plus. Ce que je veux, c'est que mes utilisateurs puissent se connecter une fois et ne craignent pas de devoir se connecter à nouveau jusqu'à ce qu'ils se déconnectent explicitement.
Évitez d’utiliser la session autant que vous le pouvez. Si vous pouvez vous en sortir sans passer, cela facilite un peu les déploiements multi-serveurs. Probablement, Nom et email sont des candidats faciles pour les cookies. Il est facile de simuler un cookie. Par conséquent, l'ID utilisateur peut ne pas être une bonne idée en fonction de vos besoins en matière de sécurité.
Les cookies d'authentification de formulaires sont cryptés et vous pouvez ajouter des données supplémentaires à ces cookies (voir détails ci-dessous). C'est probablement piratable mais pas aussi facilement qu'un simple cookie.
Voici le code que j'ai utilisé dans le passé légèrement modifié pour supprimer certains détails spécifiques au projet. Appelez-le dans l'événement LoggedIn du contrôle de connexion.
void AddUserIDToAuthCookie(string userID)
{
//There is no way to directly set the userdata portion of a FormAuthenticationTicket
//without re-writing the login portion of the Login control
//
//I find it easier to pull the cookie that the Login control inserted out
//and create a new cookie with the userdata set
HttpCookie authCookie = Response.Cookies[AUTH_COOKIE];
if(authCookie == null)
{
return;
}
Response.Cookies.Remove(AUTH_COOKIE);
FormsAuthenticationTicket oldTicket = FormsAuthentication.Decrypt(authCookie.Value);
var newTicket =
new FormsAuthenticationTicket(oldTicket.Version, oldTicket.Name, oldTicket.IssueDate, oldTicket.Expiration,
oldTicket.IsPersistent, userID, oldTicket.CookiePath);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
Response.Cookies.Add(authCookie);
}
Pour votre information, je l'ai copiée à partir d'un ancien projet et l'édite ici pour supprimer certains éléments spécifiques du projet. Ainsi, la compilation risque de ne pas être compilée, mais ce sera très proche.
Pour obtenir l'ID dans votre page Web ...
FormsAuthenticationTicket ticket = ((FormsIdentity) Page.User.Identity).Ticket;
string id = ticket.UserData;
J'ai utilisé ce mécanisme pour stocker un identifiant qui ne faisait pas partie des données utilisateur aspnetdb. Si toutes les données d’identité sont gérées par aspnetdb, il vous suffira peut-être d’accéder à l’objet Page.User.Identity.
Personnellement, je garderais la valeur par défaut de 20 minutes et ajouterais une fonctionnalité "Keep Alive" à votre site. Créez un code javascript simple qui interroge toutes les 5 minutes, par exemple, heartbeat.aspx, pour maintenir la session active. Cela étendra la session et l'authentification sans conserver de jetons d'authentification fous.
Il y a quelques exemples (mauvais à mon avis) de la façon de procéder. J'ai fini par utiliser quelque chose basé sur Prévention du délai d'expiration de session d'AjaxLines . Au lieu d’utiliser la bibliothèque ajax, j’ai simplement utilisé directement une requête xhtml. Rien n'est vraiment plus nécessaire qu'un appel javascript chronométré à une GET
sur la page de pulsation.
Techniquement, en raison du délai de session asp.net, votre utilisateur ne doit pas être déconnecté. Cela devrait/est contrôlé par le cookie d'authentification par formulaires.
Toutes les informations essentielles relatives à l'authentification de l'utilisateur doivent être conservées dans la propriété USERDATA du ticket d'authentification par formulaires. Cette valeur ne doit pas être conservée en session en tant que session.
Ne conservez que les valeurs de la session pouvant être reproduites.
Ainsi, lorsque vous créez un cookie d’authentification des formulaires, vous pouvez transmettre toutes les informations essentielles dans le cadre du ticket.
-
La solution rapide consiste à conserver le délai d'expiration de l'authentification de session et de formulaire. Ce sera une bonne pratique à faire.
Le délai de session est automatiquement prolongé à chaque demande adressée au site.
Alors qu'une authentification par formulaire ne prolonge son temps qu'après 50% du temps écoulé.
Voici une information détaillée à ce sujet: Authentification par formulaires FAQ
La solution la plus simple consiste à étendre la durée d'authentification des formulaires dans un HttpModule ou une page de base personnalisée, quelle que soit votre conception.
De cette façon, votre délai d'attente sera toujours synchronisé, même s'il peut y avoir un léger intervalle.
Sans essayer quoi que ce soit moi-même, il y a quelques points que je voudrais vérifier.
Utilisez une méthode/surcharge de la classe FormsAuthentication qui vous permet de définir un cookie persistant. Cependant, à mon humble avis, il est courant de permettre à vos utilisateurs de cocher une case "Mémoriser mes informations" au lieu de les forcer à se connecter de manière persistante. Il existe un certain nombre de méthodes qui vous permettent de le faire en fonction du comportement souhaité SetAuthenticationCookie () et RedirectFromLoginPage () sont les premiers qui viennent à l’esprit.
Découvrez FormsAuthentication.GetAuthenticationCookie (). Cela générera un cookie HTTP avec le jeton d'authentification, mais ne le définira pas réellement, ce qui devrait vous permettre de changer ce que vous voulez - bien que, si le module FormsAuthentication recherche une valeur spécifique, il pourrait endommager l'authentification. Vous devrez ensuite ajouter le cookie à la collection de cookies dans la réponse manuellement.
Ma méthode préférée consiste à utiliser une session comme le cache. c'est-à-dire, essayez de lire à partir de la session, si la valeur est là, puis retournez-la; si ce n'est pas le cas, lisez-la à partir du magasin de persistance (base de données, etc.), mettez-la en session et renvoyez-la.
Pour simplifier cela, créez une classe, ajoutez une propriété pour chaque variable en session et stockez une instance de la classe en session. Créez ensuite une méthode statique pour obtenir une instance de la classe. J'ajouterai un exemple plus tard si je pouvais.