none
Authentification & webApp RRS feed

  • Question

  • Salut,

    je voudrais savoir comment je peux, dans mon application, m'authentifier à un site.

    Je m'explique : j'ai une application qui récupère les données d'un site web (pas de soucis), mais j'aimerais permettre à l'utilisateur de se connecter à son compte pour qu'il accède au contenu personnel comme le font la casi-totalité des sites web actuels. Le site auquel je veux me connecter n'utilise pas de connection https.
    J'ai cherché un peu et les moteurs de recherche m'ont mené sur la voie d'un httpWebRequest, mais j'aimerais plus d'informations sur le sujet.






    lundi 9 avril 2012 23:41

Réponses

  • Voici un exemple de code:

    WebClient client = new WebClient();
    client.UploadStringCompleted += (object sUploadStringCompleted, UploadStringCompletedEventArgs eUploadStringCompleted) =>
    {
        if (eUploadStringCompleted.Error != null)
        {
            // Error occured !
        }
        else
        {
            // Do something...
        }
    };
    client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
    client.Encoding = Encoding.UTF8;
    client.UploadStringAsync(new Uri("http://example.com/sample.htm"), "POST", "foo=bar");

    Donc le premier paramètre de la méthode UploadStringAsync prend l'adresse de la page contenant le formulaire d'authentification, le second paramètre indique que les données vont être envoyés par forumaire (POST) et non pas par url (GET), le troisième paramètre correspond au champs de ta page (input).

    L'évènement UploadStringCompleted va te permettre de récupérer la page vers laquelle tu sera redirigé après l'authentification réussie (ou non), le résultat (code html de la page) se trouve dans la propriété eUploadStringCompleted.Result, à toi après de, soit le parser, soit afficher dans un contrôle WebBrowser.

    Si t'a d'autres questions ou si ce n'est pas clair n'hésite pas à poser tes questions :)


    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    mardi 10 avril 2012 19:22
  • Après de longues heures de lutte, je suis enfin arrivé à mes fins.

    Je poste ici la solution complète étant donné que ce n'est pas évident, surtout pour les débutants.

    La première chose à faire est de créer une classe ExtendedWebClient dans votre projet. 
    Cette classe est la classe WebClient avec une méthode surchargée pour gérer les cookies. A la base la classe WebClient ne sauvegarde pas les cookies, du coup même si vous vous authentifiez, impossible de bénéficier des pages personnalisées (rubrique "mon compte" par ex). La classe ExtendedWebClient s'occupera donc de sauvegarder et d'utiliser automatiquement les cookies (sur chaque page) après authentification.

    public class ExtendedWebClient : WebClient
        {
            public CookieContainer CookieContainer { get; private set; }
    
            [SecuritySafeCritical]
            public ExtendedWebClient()
            {
                this.CookieContainer = new CookieContainer();
            }
    
            protected override WebRequest GetWebRequest(Uri address)
            {
                WebRequest request = base.GetWebRequest(address);
    
                if (request is HttpWebRequest)
                    (request as HttpWebRequest).CookieContainer = this.CookieContainer;
    
                return request;
            }
        }
    La classe ExtendedWebClient contient [SecuritySafeCritical] suivi du constructeur, ce qui est indispensable sinon vous rencontrez une exception.

    Et ensuite on utilise la méthode décrite par Jérôme précédemment pour se connecter (sans oublier d'utiliser la classe ExtendedWebClient à la place de WebClient)

    public void Connect()
            {
                
               ExtendedWebClient client = new ExtendedWebClient(); 
                client.UploadStringCompleted += (object sUploadStringCompleted, UploadStringCompletedEventArgs eUploadStringCompleted) =>
                {
                    if (eUploadStringCompleted.Error != null)
                    {
                        // Error occured !
                    }
                    else
                    {
                        // Do something...
                        //Parser le résultat avec html agility pack par ex.
                        
                        //On peut ensuite accéder a d'autres pages en réutilisant l'objet client
    		   //avec un évènement client.DownloadStringCompleted par ex
    		  //ce qui va nous permettre de naviguer sur le site en étant connecté
                        
                    }
                };
                client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
                client.Encoding = Encoding.UTF8;
                client.UploadStringAsync(new Uri("http://mon_site/connexion"), "POST", "email=votre_email&password=votre_pass");
            }

    Voili, voilou!
    Merci à Jérôme Dupuy pour ton aide :)



    jeudi 12 avril 2012 00:59

Toutes les réponses

  • Bonjour,

    Tout dépend du mode d'authentification du site web: classique (POST), OAuth, ...

    Si c'est du "classique", alors effectivement l'utilisation de HttpWebRequest (et encore plus simplement de WebClient) est très simple à mettre en oeuvre avec une requête POST, je pourrai te donner des exemples le cas échéant :)


    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    mardi 10 avril 2012 07:45
  • Ce serait sympa d'avoir un exemple de connexion a un site web à partir d'une application, la méthode d'authentification du site est classique (POST).

    EDIT : 

    J'ai trouvé ce bout de code sur stackoverflow

    string URI = "http://www.myurl.com/post.php";
    string myParamters = "param1=value1&param2=value2";
    
    WebClient wc = new WebClient();
    wc.Headers["Content-type"] = "application/x-www-form-urlencoded";
    string HtmlResult = wc.UploadString(URI, myParameters);

    Mais quelques questions tout d'abord :

    • string myParamters contient le login et le mot de passe?
    • string URI est l'uri de la page sur laquelle on s'identifie (je présume), il faut forcément mettre "post.php" à la fin?
    • A la fin de l'exécution de ce code l'utilisateur sera connecté au site depuis mon application?
    • Alors je peux intégrer les liens accessibles seulement aux utilisateurs connectés au site web dans mon app ?

    Je découvre tout juste le langage C#.


    mardi 10 avril 2012 17:15
  • Voici un exemple de code:

    WebClient client = new WebClient();
    client.UploadStringCompleted += (object sUploadStringCompleted, UploadStringCompletedEventArgs eUploadStringCompleted) =>
    {
        if (eUploadStringCompleted.Error != null)
        {
            // Error occured !
        }
        else
        {
            // Do something...
        }
    };
    client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
    client.Encoding = Encoding.UTF8;
    client.UploadStringAsync(new Uri("http://example.com/sample.htm"), "POST", "foo=bar");

    Donc le premier paramètre de la méthode UploadStringAsync prend l'adresse de la page contenant le formulaire d'authentification, le second paramètre indique que les données vont être envoyés par forumaire (POST) et non pas par url (GET), le troisième paramètre correspond au champs de ta page (input).

    L'évènement UploadStringCompleted va te permettre de récupérer la page vers laquelle tu sera redirigé après l'authentification réussie (ou non), le résultat (code html de la page) se trouve dans la propriété eUploadStringCompleted.Result, à toi après de, soit le parser, soit afficher dans un contrôle WebBrowser.

    Si t'a d'autres questions ou si ce n'est pas clair n'hésite pas à poser tes questions :)


    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    mardi 10 avril 2012 19:22
  • J'arrive bien à m'authentifier avec ta méthode, mais comment ensuite accéder aux pages du site en restant authentifié?

    J'ai essayé ceci mais évidemment ça ne marche pas

            public void aConnect()
            {
                WebClient client = new WebClient();
    
                client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
                client.Encoding = Encoding.UTF8;
                client.UploadStringAsync(new Uri("monsiteweb/connexion"), "POST", "email=mon_email.com&password=mon_pass");
    
                client.UploadStringCompleted += (object sUploadStringCompleted, UploadStringCompletedEventArgs eUploadStringCompleted) =>
                {
                    if (eUploadStringCompleted.Error != null)
                    {
                        // Error occured !
                    }
                    else
                    {
                        HtmlDocument doc = new HtmlDocument();
                        doc.LoadHtml(eUploadStringCompleted.Result);
    
                        //parse la page redirigée
    
    //A ce moment je veux accéder aux parametres de mon compte
                        client.DownloadStringAsync(new Uri("monsiteweb/mon_compte"));
    
                        client.DownloadStringCompleted += (sender, e) =>
                            {
                                if (e.Error != null)
                                {
                                    //Error!
                                }
                                HtmlDocument doc2 = new HtmlDocument();
                                doc2.LoadHtml(e.Result);
                                
    //parse le résultat
                            };
                    }
                };
            }

    EDIT : Visiblement il me faut sauvegarder les données utilisateurs dans des cookies (?) 
    mercredi 11 avril 2012 17:32
  • Y'a déjà un soucis avec ton code, tu attache les évènements (client.UploadStringCompleted et client.DownloadStringCompleted) après avoir invoqué les méthodes (client.UploadStringAsync() et  client.DownloadStringAsync()) qui vont les lever :)

    Pour que la discussion puisse être identifiée comme résolue merci de marquer les réponses qui vous ont aidées à solutionner votre problème comme "réponse".

    mercredi 11 avril 2012 19:10
  • Okay, j'ai modifié en gardant la structure de base que tu m'avais donné.

    Sinon j'ai vérifier le contenu de la variable "webClient client" et je suis bien redirigé vers la page "Connexion réussie". Le problème est que dans cette page redirigée, il n'y a aucune donné utilisateur.




    mercredi 11 avril 2012 20:19
  • Après de longues heures de lutte, je suis enfin arrivé à mes fins.

    Je poste ici la solution complète étant donné que ce n'est pas évident, surtout pour les débutants.

    La première chose à faire est de créer une classe ExtendedWebClient dans votre projet. 
    Cette classe est la classe WebClient avec une méthode surchargée pour gérer les cookies. A la base la classe WebClient ne sauvegarde pas les cookies, du coup même si vous vous authentifiez, impossible de bénéficier des pages personnalisées (rubrique "mon compte" par ex). La classe ExtendedWebClient s'occupera donc de sauvegarder et d'utiliser automatiquement les cookies (sur chaque page) après authentification.

    public class ExtendedWebClient : WebClient
        {
            public CookieContainer CookieContainer { get; private set; }
    
            [SecuritySafeCritical]
            public ExtendedWebClient()
            {
                this.CookieContainer = new CookieContainer();
            }
    
            protected override WebRequest GetWebRequest(Uri address)
            {
                WebRequest request = base.GetWebRequest(address);
    
                if (request is HttpWebRequest)
                    (request as HttpWebRequest).CookieContainer = this.CookieContainer;
    
                return request;
            }
        }
    La classe ExtendedWebClient contient [SecuritySafeCritical] suivi du constructeur, ce qui est indispensable sinon vous rencontrez une exception.

    Et ensuite on utilise la méthode décrite par Jérôme précédemment pour se connecter (sans oublier d'utiliser la classe ExtendedWebClient à la place de WebClient)

    public void Connect()
            {
                
               ExtendedWebClient client = new ExtendedWebClient(); 
                client.UploadStringCompleted += (object sUploadStringCompleted, UploadStringCompletedEventArgs eUploadStringCompleted) =>
                {
                    if (eUploadStringCompleted.Error != null)
                    {
                        // Error occured !
                    }
                    else
                    {
                        // Do something...
                        //Parser le résultat avec html agility pack par ex.
                        
                        //On peut ensuite accéder a d'autres pages en réutilisant l'objet client
    		   //avec un évènement client.DownloadStringCompleted par ex
    		  //ce qui va nous permettre de naviguer sur le site en étant connecté
                        
                    }
                };
                client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
                client.Encoding = Encoding.UTF8;
                client.UploadStringAsync(new Uri("http://mon_site/connexion"), "POST", "email=votre_email&password=votre_pass");
            }

    Voili, voilou!
    Merci à Jérôme Dupuy pour ton aide :)



    jeudi 12 avril 2012 00:59