none
Modèle de licences utilisateurs Web - ASP.NET RRS feed

  • Question

  • Bonjour,

    Tout d'abord désolé si la question a déjà été posée... et désolé également si vous avez déjà vu cette question sur un autre forum, j'essaye de multiplier les pistes :-)

    Ma boîte développe et distribue des application Web (ASP.NET, Silverlight...).
    Ces applications ne sont pas des spécifiques par client, une même application peut-être vendue et installée chez plusieurs clients.

    J'aurai besoin de gérer et de contrôler les accès des utilisateurs à ces applications. Comment identifier les postes clients (navigateurs) qui se connectent, connaître leur nombre, et afficher un message si celui-ci dépasse une certaine limite?

    Je précise bien, je ne souhaite pas contrôler le fait que l'application web a été "achetée", puisqu'une action manuelle est obligatoire de notre part pour l'installer chez notre client. 
    Je ne parle pas non plus de "l'authentification" des utilisateurs, grâce à un login / mot de passe enregistrés en base de données, puisque N utilisateurs sont susceptibles de se connecter à la même application avec un même login / mot de passe.

    Ce que je souhaite savoir, c'est une fois que l'installation a été réalisée CHEZ le client, comment contrôler le nombre d'utilisateur qui consulte ce site?? Le nombre de connexions simultanées en quelque sorte...

    Merci d'avance!

    PS: Je suis ouvert à toute méthode, même une solution logicielle, une sorte de serveur de licence installée chez le client en même temps que l'application Web... Je ne sais pas.
    mercredi 17 mars 2010 09:14

Réponses

  • POur répondre à ta question, voici la structure que j'utiliserai dans ton cas.
    Le numéro de session est en principe unique on peut donc l'utiliser comme clef primaire d'une table. Tu as besoin de savoir le début et la fin de la session mais tu n'as pas besoin de savoir quel utilisateur était connecté.

    Tu as donc besoin d'une table avec ce format :
    SessionID VARCHAR(20) NOT NULL PRIMARY KEY,
    SessionStart DATETIME NOT NULL
    SessionEnd DATETIME NULL

    A démarrage de la session, tu appelles un webservice qui rempli SessionID et SessionStart.
    A la fin de la session, tu appelles un webService qui rempli SessionEnd (auquel tu retranches éventuellement le temps d'expiration).

    J'ai eu des cas où le sessionEnd ne fonctionne pas correctement en cas d'arrêt de l'application. Dans ce cas, il faut gérer le remplissage des SessionEnd l'ors de l'évènement ApplicationEnd. Si tu n'as vraiement pas confiance dans le système, tu peux aussi faire ça sur le applicationStart.

    Sinon, il y a également moyen de gérer les session dans des bases SQL Server et dans ce cas, tu peux capturer la création et la suppression d'une session dans la base de gestion des sessions.
    Olivier MARTY
    • Marqué comme réponse Corentin A_ jeudi 18 mars 2010 14:23
    • Non marqué comme réponse Corentin A_ lundi 29 mars 2010 08:03
    • Marqué comme réponse Alex Petrescu mardi 30 mars 2010 13:02
    jeudi 18 mars 2010 08:44
  • Le sessionID est unique par session même quand le serveur est un TSE. C'est une information qui est portée par le client dans son cookie de session qui permet de retrouver son contexte créé sur le serveur lors du chargement d'une page. Tu peux même faire le test suivant : sur une même session, ouvrir ton site sous IE et Firefox, tu auras deux sessionID distincts.
    Le webservice permet de découpler ton application de vérification des sessions et de la mettre sur un serveur externe et distant... chez toi par exemple si tu veux centraliser l'utilisation de l'esemble de tes clients.
    Olivier MARTY
    • Marqué comme réponse Corentin A_ jeudi 18 mars 2010 14:23
    • Non marqué comme réponse Corentin A_ lundi 29 mars 2010 08:03
    • Marqué comme réponse Alex Petrescu mardi 30 mars 2010 13:02
    jeudi 18 mars 2010 14:14

Toutes les réponses

  • Salut,

    Il faut monter un service Web sur un serveur que tu maïtrises. Dans les applications tu te connectes au site Web à chaque connexion d'un utilisateur et tu remonte les informations que tu veux.

    Je te rappelle tout de même, si tu déploie ton application en France, que la collecte d'information permettant d'indentifier une personne doit être déclarée à la CNIL et doit être portée à la connaissance des personnes impliquée par cette collecte.

    Olivier MARTY
    Olivier MARTY
    mercredi 17 mars 2010 10:33
  • Dans les applications tu te connectes au site Web à chaque connexion d'un utilisateur et tu remonte les informations que tu veux.


    Merci pour la réponse... 

    Justement la question est: Comment savoir qu'un utilisateur se connecte, se déconnecte, que c'est un nouvel utilisateur et non un ancien qui se reconnecte, etc. Le session_start, session_end, c'est pas hyper stable.
    Et cette question se pose peu importe que la gestion des connexions simultanées se fasse chez nous via un service web, ou directement chez le client.

    Ensuite, pour la question de la CNIL, il ne m'est pas nécessaire de savoir QUI se connecte exactement, son nom, etc. Juste un moyen t'identifier à l'instant T combien de personnes utilisent un site, et savoir faire évoluer ce nombre suivant les connexion, déconnexion, etc.

    EDIT: de façon robuste :-) un modèle commercial serait basé dessus...

    mercredi 17 mars 2010 11:26
  • Salut,
    J'utilise assez couramment le session_start et le session_end, ayant moi-même eu besoin d'un système de trace hyper complet (debut/fin de session+stat de visualisation ds pages+échange de données avec le client). Ca fonctionne parfaitement, mais il faut savoir que le session_end se fait à l'expiration de la session, c'est à dire, par défaut, 20mn après la dernière action du client.
    Olivier MARTY
    mercredi 17 mars 2010 13:55
  • Merci.
    Il n'y a pas une contrainte à l'utilisation du session_end?? Comme quoi ça ne marche correctement que dans un cas particulier... Je n'arrive pas à retrouver la problématique, je sais que je l'avais rencontré. 

    Tu penses qu'utiliser le couple session_start, session_end permettrais de faire tout ça correctement?
    Même si la connexion au site se fait via un navigateur via une session TSE??
    mercredi 17 mars 2010 15:50
  • POur répondre à ta question, voici la structure que j'utiliserai dans ton cas.
    Le numéro de session est en principe unique on peut donc l'utiliser comme clef primaire d'une table. Tu as besoin de savoir le début et la fin de la session mais tu n'as pas besoin de savoir quel utilisateur était connecté.

    Tu as donc besoin d'une table avec ce format :
    SessionID VARCHAR(20) NOT NULL PRIMARY KEY,
    SessionStart DATETIME NOT NULL
    SessionEnd DATETIME NULL

    A démarrage de la session, tu appelles un webservice qui rempli SessionID et SessionStart.
    A la fin de la session, tu appelles un webService qui rempli SessionEnd (auquel tu retranches éventuellement le temps d'expiration).

    J'ai eu des cas où le sessionEnd ne fonctionne pas correctement en cas d'arrêt de l'application. Dans ce cas, il faut gérer le remplissage des SessionEnd l'ors de l'évènement ApplicationEnd. Si tu n'as vraiement pas confiance dans le système, tu peux aussi faire ça sur le applicationStart.

    Sinon, il y a également moyen de gérer les session dans des bases SQL Server et dans ce cas, tu peux capturer la création et la suppression d'une session dans la base de gestion des sessions.
    Olivier MARTY
    • Marqué comme réponse Corentin A_ jeudi 18 mars 2010 14:23
    • Non marqué comme réponse Corentin A_ lundi 29 mars 2010 08:03
    • Marqué comme réponse Alex Petrescu mardi 30 mars 2010 13:02
    jeudi 18 mars 2010 08:44
  • Merci beaucoup.
    Je vais essayer d'analyser ça, j'avais déjà essayé d'utiliser les session_start et session_end, mais j'avais trouvé des limitations.
    Il faudra notamment que je teste en TSE, si plusieurs sessions sont bien créées...

    Le SessionID, c'est sûr?? puisque c'est grâce à cela que je pourrai réellement déterminer les sessions "active" (sans date de fin) et celles qui sont terminées... Si c'est ok, ça résoudrait un des principaux problème, i.e. l'identification des sessions active (je pensais au départ à l'IP, mais ça ne peut pas fonctionner correctement (NAT))

    Par contre, pourquoi un Web service? Pour la réutilisabilité, ou pour faire en sorte que l'appel soit asynchrone et ainsi éviter que la gestion des sessions soit "bloquante", ou pour une autre raison??

    Peut-être que je pourrais faire intervenir le Session_End manuellement à la fermeture du navigateur grâce à un appel Javascript... Au pire ça ne marchera pas si l'utilisateur ne l'autorise pas, mais ce sera déjà ça...

    Sinon, pas de base SQL Server, les applications tournent sous Oracle.
    jeudi 18 mars 2010 09:43
  • Le sessionID est unique par session même quand le serveur est un TSE. C'est une information qui est portée par le client dans son cookie de session qui permet de retrouver son contexte créé sur le serveur lors du chargement d'une page. Tu peux même faire le test suivant : sur une même session, ouvrir ton site sous IE et Firefox, tu auras deux sessionID distincts.
    Le webservice permet de découpler ton application de vérification des sessions et de la mettre sur un serveur externe et distant... chez toi par exemple si tu veux centraliser l'utilisation de l'esemble de tes clients.
    Olivier MARTY
    • Marqué comme réponse Corentin A_ jeudi 18 mars 2010 14:23
    • Non marqué comme réponse Corentin A_ lundi 29 mars 2010 08:03
    • Marqué comme réponse Alex Petrescu mardi 30 mars 2010 13:02
    jeudi 18 mars 2010 14:14
  • Super, merci beaucoup, je vais tester tout ça!
    jeudi 18 mars 2010 14:23
  • Re-Bonjour,

    J'ai pu trouver un peu de temps pour me replonger dans tout ça.

    (Je me suis permis d'enlever le tag "réponse"...)

    Donc, voici une petite classe de gestion des sessions que j'ai faite: 

    SessionElement "étend" la session pour un utilisateur connecté (HttpSessionState est sealed, donc j'ai joué sur la composition plutôt que sur l'héritage). SessionManager (singleton) ajoute est supprime des SessionElement et sauvegarde la liste dans la variable Application.

    public class SessionElement
    {
        public HttpSessionState HttpSession { get; set; }
    
        public string SessionID { get { return HttpSession.SessionID; } }
        public string IP { get; set; }
        public string Browser { get; set; }
    
        public DateTime LastAccess { get; set; }
        public Boolean NewSession { get { return HttpSession.IsNewSession; } }
        public int Timeout { get { return HttpSession.Timeout; } }
        public DateTime FinPrevue { get { return LastAccess.AddMinutes(HttpSession.Timeout); } }
    
        public SessionElement(HttpSessionState httpSession)
        {
            HttpSession = httpSession;
        }
    }
    
    public class SessionManager
    {
        private static SessionManager _instance = null;
        private static readonly object lockInstance = new object();
        private const String ID_SESSIONS_APPLICATION = "Sessions";
    
        /// <summary>
        /// Propriété d'accès au SessionManager
        /// </summary>
        public static SessionManager getInstance
        {
            get
            {
                lock ((lockInstance))
                {
                    if (_instance == null)
                    {
                        _instance = new SessionManager();
                    }
                    return _instance;
                }
            }
        }
    
        public List<SessionElement> SessionsActives 
        {
            get { return (List<SessionElement>)Application[ID_SESSIONS_APPLICATION]; }
            set { Application[ID_SESSIONS_APPLICATION] = value; }
        }
    
        private static HttpApplicationState Application { get { return HttpContext.Current.Application; } }
    
        private SessionManager()
        {
            SessionsActives = new List<SessionElement>();
        }
    
        public void NewSession(HttpSessionState session)
        {
            try
            {
                Application.Lock();
    
                if (!SessionsActives.Exists( s => s.HttpSession.SessionID == session.SessionID ))
                    SessionsActives.Add(
                        new SessionElement(session)
                        {
                            Browser = HttpContext.Current.Request.Browser.Type + " " + HttpContext.Current.Request.Browser.Browser,
                            LastAccess = DateTime.Now,
                            IP = HttpContext.Current.Request.UserHostAddress
                        }
                    );
                else
                {
                    SessionsActives[SessionsActives.FindIndex(s => s.HttpSession.SessionID == session.SessionID)] =
                        new SessionElement(session)
                        {
                            Browser = HttpContext.Current.Request.Browser.Type + " " + HttpContext.Current.Request.Browser.Browser,
                            LastAccess = DateTime.Now,
                            IP = HttpContext.Current.Request.UserHostAddress
                        };
                }
    
                // - Sauvegarde
                Application[ID_SESSIONS_APPLICATION] = SessionsActives;
            }
            catch (Exception) { }
            finally
            {
                Application.UnLock();
            }
        }
    
        public void EndSession(HttpSessionState session)
        {
            try
            {
                Application.Lock();
                SessionElement sessionASupprimer = SessionsActives.Find(s => s.HttpSession.SessionID == session.SessionID);
                sessionASupprimer.HttpSession.Abandon();
                SessionsActives.Remove(sessionASupprimer);
    
                // - Sauvegarde
                Application[ID_SESSIONS_APPLICATION] = SessionsActives;
            }
            catch (Exception) { }
            finally
            {
                Application.UnLock();
            }
        }
    }

    Petit soucis:
    Quand j'ouvre un navigateur, et que je consulte la liste des sessions, j'ai bien une session de créée avec un ID unique.
    Si je ferme le navigateur, et que je l'ouvre de nouveau en suivant, une nouvelle session est créée, avec un nouvel ID.

    Le problème, c'est que je suis incapable de retrouver un l'ID de session précédent à chaque ouverture du navigateur afin de le mettre à jour par la nouvelle session dans la liste des sessions actives. A défaut de supprimer réellement la session quand le navigateur se ferme (impossible à moins d'utiliser du javascript), il faudrait que lorsque j'ouvre un navigateur, je puisse supprimer les sessions "anciennes" ou désynchronisées pour ce client là, puis créer la nouvelle session.

    Obligé de passer par des cookies pour sauvegarder l'ID de session?? :
    Exemple: à l'ouverture du site,
    - recherche de l'ancien ID de session dans les cookies,
    - suppression de l'ancienne session de ma liste de session grâce à l'ancien ID,
    - nouveau cookie avec le nouvel ID,
    - ajout de la nouvelle session...

    Une autre idée???
    Merci d'avance!!





    lundi 29 mars 2010 08:03
  • Up :-)
    mardi 30 mars 2010 10:46