Concernant le glissement de l'expiration de ASP.NET's formes d'authentification et de session
Nous avons une ASP.NET 4.5 WebForms application à l'aide des formes natives d'authentification et de session de la fonctionnalité. Les deux ont un délai d'attente de 20 minutes avec le glissement de l'expiration.
Imaginez le scénario suivant. Un utilisateur a travaillé dans notre application pendant un certain temps et puis continue à faire d'autres choses, en laissant notre application inactif pendant 20 minutes. Ensuite, l'utilisateur retourne à notre demande de rédiger un rapport. Toutefois, lorsque l'utilisateur tente d'enregistrer, il/elle est traitée avec l'écran de connexion, et le rapport est perdu.
Évidemment, c'est non. Au lieu de ce scénario, nous voulons que le navigateur sera redirigé vers la page de connexion le moment soit de l'authentification ou de la session a expiré. Pour réaliser cela, nous avons construire une Api Web service qui peut être appelé à vérifier si c'est le cas.
public class SessionIsActiveController : ApiController
{
///<summary>
///Gets a value defining whether the session that belongs with the current HTTP request is still active or not.
///</summary>
///<returns>True if the session, that belongs with the current HTTP request, is still active; false, otherwise./returns>
public bool GetSessionIsActive()
{
CookieHeaderValue cookies = Request.Headers.GetCookies().FirstOrDefault();
if (cookies != null && cookies["authTicket"] != null && !string.IsNullOrEmpty(cookies["authTicket"].Value) && cookies["sessionId"] != null && !string.IsNullOrEmpty(cookies["sessionId"].Value))
{
var authenticationTicket = FormsAuthentication.Decrypt(cookies["authTicket"].Value);
if (authenticationTicket.Expired) return false;
using (var asdc = new ASPStateDataContext()) //LINQ2SQL connection to the database where our session objects are stored
{
var expirationDate = SessionManager.FetchSessionExpirationDate(cookies["sessionId"].Value + ApplicationIdInHex, asdc);
if (expirationDate == null || DateTime.Now.ToUniversalTime() > expirationDate.Value) return false;
}
return true;
}
return false;
}
}
Cette Api Web service est appelé toutes les 10 secondes par le client pour vérifier si l'authentification ou la session a expiré. Si oui, le script redirige le navigateur vers la page de connexion. Cela fonctionne comme un charme.
Cependant, l'appel de ce service déclenche le glissement de l'expiration de l'authentification et de session. Donc, essentiellement, la création de jamais de fin d'authentification et de session. J'ai mis un point d'arrêt au début du service pour vérifier si il est l'un de nos propres fonctions qui déclenche cette. Mais ce n'est pas le cas, il semble se produire quelque part plus loin dans ASP.NET avant l'exécution de la prestation.
- Est-il un moyen de désactiver le déclenchement de ASP.NET s'authentification et de session de glissement expirations pour une demande spécifique?
- Si non, quelles sont les meilleures pratiques pour s'attaquer à un tel scénario?
Je suis conscient de cela, et nous sommes en train de considérer l'élimination de la session d'utilisation, mais même dans ce parfait sessionless monde, le problème serait toujours pour le ticket d'authentification...
Pas vraiment. Lorsque l'utilisateur-les agents sont autorisés à faire de la auth poignée de main correctement, l'utilisateur ne perd pas de leur état actuel. C'est le navigateur rediriger vers un formulaire de connexion qui provoque la perte de leur travail.
C'est malheureusement la façon dont les formes d'authentification dans ASP.NET les œuvres, lorsqu'un auth ticket expire le user-agent est toujours redirigé vers un autre, prédéfinis page. Vos suggestions fondamentalement suggèrent que nous n'utilisons pas ASP.NET's formes d'authentification et de session (qui, je vous donne, a un certain mérite à elle). Toutefois, dans l'intérêt de ne pas avoir de revoir notre cadre de ce diplôme, je suis toujours intéressé à la réponse à ma première question.
nous n'essayons pas de les empêcher d'expiration pour des demandes spécifiques. Nous voulons éviter le renouvellement de l' coulissantes expiration pour les demandes spécifiques (qui n'ont pas encore expiré).
OriginalL'auteur maartendekker | 2013-01-31
Vous devez vous connecter pour publier un commentaire.
Cela semble être impossible. Une fois coulissantes date d'expiration est activé, il est toujours déclenché. Si il existe un moyen d'accéder à la session sans l'étendre, nous n'avons pas été en mesure de le trouver.
Alors, comment s'attaquer à ce scénario? Nous sommes venus avec les personnes suivantes solution alternative à celui proposé à l'origine dans la question. Celui-ci est en fait plus efficace car elle permet de ne pas utiliser un service web pour téléphone à la maison, toutes les x secondes.
Si nous voulons avoir un moyen de savoir quand ASP.NET s'authentification de formulaires ou de la session a expiré, de sorte que nous pouvons pro-activement la déconnexion de l'utilisateur. Un simple javascript timer sur chaque page (comme l'a proposé par Khalid Abuhakmeh) ne suffirait pas, car l'utilisateur pourrait être de travailler avec l'application en plusieurs fenêtres de navigateur/onglets en même temps.
La première décision que nous avons fait pour rendre le problème plus simple est de prendre le temps d'expiration de la session, quelques minutes de plus que le temps d'expiration de l'authentification de formulaires. De cette façon, la session n'expire jamais avant l'authentification de formulaires. Si il y a une attente ancienne session la prochaine fois que l'utilisateur essaie d'ouvrir une session, nous abandonner à forcer une nouvelle une nouvelle.
Tout droit, donc, maintenant, nous n'avons qu'à prendre l'authentification de formulaires d'expiration en compte.
Ensuite, nous avons décidé de désactiver l'authentification par formulaires automatiques coulissantes expiration (tel que défini dans le web.config) et de créer notre propre version de celui-ci.
Nous appelons cette méthode à partir de la
OnPreRenderComplete
cas dans notre application BasePage classe, à partir de laquelle toutes les autres pages hérite. Il fait exactement la même chose que la normale coulissantes expiration de la fonctionnalité, mais nous avons la chance de faire quelques trucs supplémentaires; par exemple appeler notreSetAuthenticationExpirationTicket
méthode.Maintenant, nous avons un cookie supplémentaire à notre disposition que représente toujours la forme correcte de l'authentification des temps d'expiration, même si l'utilisateur travaille dans différentes fenêtres de navigateur/onglets. Après tout, les cookies ont un navigateur large champ d'application. Maintenant, la seule chose qui reste est une fonction javascript pour vérifier la valeur du cookie.
(Notez que nous utilisons jQuery Plugin Cookie récupérer le cookie.)
Mettre cette fonction dans un intervalle, et les utilisateurs seront connectés pour le moment, ses formes d'authentification a expiré. Voilà 🙂 Un supplément avantage de cette application est que vous pouvez maintenant contrôler lors de l'authentification de formulaires d'expiration est agrandi. Si vous souhaitez un tas de services web qui ne s'étendent pas à l'expiration d'un délai, il suffit de ne pas appeler la
RenewAuthenticationTicket
méthode pour eux.Merci de laisser un commentaire si vous avez quelque chose à ajouter!
est-il sensé de cette ligne
var newAuthTicket = oldAuthTicket;
de la routine appeléeRenewAuthenticationTicket()
je suppose que pouvons-nous peut omettrenewAuthTicket = oldAuthTicket
à la recherche pour votre commentaire.1. Oui, c'est de cette façon coulissante expiration fonctionne. 2. Si je me souviens bien, la ligne ne peut pas être omis, parce que la ligne ci-dessous il
FormsAuthentication.RenewTicketIfOld(oldAuthTicket);
donne un résultat dans le cas où le billet est "vieille". Si l'attribution de vous en parler, permet de s'assurernewAuthTicket
a toujours une valeur (références quelque chose, pour être plus exact). Vous pouvez expérimenter avec vous-même pour voir.il y a deux ligne 1er
var newAuthTicket = oldAuthTicket; and second one newAuthTicket = FormsAuthentication.RenewTicketIfOld(oldAuthTicket);
donc, quelle que soit la valeur sera stockée dans newAuthTicket la ligne suivante va écraser....si j'ai raison, alors quel est le sens de la première lignevar newAuthTicket = oldAuthTicket;
pas très clair pour moi.merci pour votre préoccupation. La suggestion que vous donnez comme une solution de contournement possible, est ce qui est en réalité déjà là. Le cookie qui a
HttpOnly
la valeur false (authenticationExpirationTicketCookie
), est en fait un séparé temps d'expiration du cookie. La réelle cookie d'authentification (authenticationTicketCookie
), elle a explicitement définie à vrai, comme vous pouvez le voir dans le premier bloc de code. Il devrait donc y avoir aucun problème de sécurité, d'accord?OriginalL'auteur maartendekker
Cela peut être résolu côté client, sans avoir à revenir en arrière sur le serveur.
En JavaScript ce faire.
Le délai sera fixé à 20 minutes sur chaque actualisation de la page. Cela garantit que l'utilisateur doit obtenir tous leurs travaux avant le délai d'attente se produit. Beaucoup de sites utilisent cette méthode, et il vous permet d'économiser inutile de faire des demandes de serveur.
Je suis d'accord avec vous que ce scénario est possible, mais nous n'avons aucune idée de ce que l'utilisateur l'utilisation de la question ci-dessus.
OriginalL'auteur Khalid Abuhakmeh
Votre site web, la fonctionnalité devrait fonctionner sans JavaScript ou vous venez de remplacer un problème par un autre. J'ai abordé ce problème aussi, et voici comment il a été résolu:
Lorsque vous vous authentifiez puis cookie de session est créé avec la durée de vie par défaut sur 20 min. Lorsque cette expire, l'utilisateur sera déconnecté.
Lorsque l'utilisateur sélectionne "se souvenir de moi" dans le signe dans formulaire supplémentaire persistance cookie [AuthCookie] est créé à côté client et dans la base de données. Ce cookie a une durée de vie de 1 mois. Chaque fois que la page est chargée, de la session et de la persistance des données de cookie est recréé avec une nouvelle vie (normalement, vous souhaitez décrypter/crypt le billet).
Une façon de faire cela est d'étendre mondiale.aspx pour gérer prerequest. Quelque chose dans le genre de:
AuthenticateUserFromExternalSource doit vérifier si les données de cookie correspond avec la base de données, parce que tout ce qui est stocké dans le côté client peut être changé. Si vous avez payé des services avec des droits d'accès alors vous devez vérifier si l'utilisateur a toujours ces droits, et vous pouvez ensuite recréer la session.
OriginalL'auteur Margus