Iniciar sesion en web con C#

Iniciado por Kaxperday, 24 Noviembre 2014, 16:33 PM

0 Miembros y 1 Visitante están viendo este tema.

Kaxperday

Hola a todos, he encontrado el siguiente código que según pone el que lo posteo debería iniciar sesión en una página web llevando a cabo todas las redirecciones y cookies necesarias hasta llegar a la cookie de sesión JSESSIONID.

Link: http://stackoverflow.com/questions/14758917/c-sharp-download-file-from-the-web-with-login

Código (csharp) [Seleccionar]

CookieCollection cookies = new CookieCollection();
       HttpWebRequest cookieRequest = (HttpWebRequest)WebRequest.Create("https://www.loginpage.com/");
       cookieRequest.CookieContainer = new CookieContainer();
       cookieRequest.CookieContainer.Add(cookies);
       HttpWebResponse cookieResponse = (HttpWebResponse)cookieRequest.GetResponse();
       cookies = cookieResponse.Cookies;

       string postData = "name=********&password=*********&submit=submit";
       HttpWebRequest loginRequest = (HttpWebRequest)WebRequest.Create("https://www.loginpage.com/");
       loginRequest.CookieContainer = new CookieContainer();
       loginRequest.CookieContainer.Add(cookies);
       loginRequest.Method = WebRequestMethods.Http.Post;
       loginRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
       loginRequest.AllowWriteStreamBuffering = true;
       loginRequest.ProtocolVersion = HttpVersion.Version11;
       loginRequest.AllowAutoRedirect = true;
       loginRequest.ContentType = "application/x-www-form-urlencoded";

       byte[] byteArray = Encoding.ASCII.GetBytes(postData);
       loginRequest.ContentLength = byteArray.Length;
       Stream newStream = loginRequest.GetRequestStream(); //open connection
       newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
       newStream.Close();


Ahora bien, ¿esto funciona? porque lo he probado para iniciar sesión en una web y no hizo nada.
¿Cómo puedo ver las cookies que tiene?, ¿cómo saber si ha recogido algo o no? ¿Cómo funciona?

Lo he depurado y no cargaban nada de respuesta las variables.

Viendo todo esto me pregunto si este es el camino correcto para iniciar sesión en una web usando C#, de ser así ¿podríais guiarme un poco para conseguir la cookie de sesión JESESSIONID?.

Saludos y gracias.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

kub0x

Hombre si copias y pegas el código tal cual no vas a poder logearte en ninguna web. Tienes que conocer bien las variables enviadas al servidor, así como el método utilizado por el protocolo HTTP para enviar dichos datos.

Con la extensión FireBug puedes ver fácilmente que variables envías al servidor y los métodos empleados. En ese código el método es POST y te falta definir la url destino (página del login) y la cadena de variables (postData). Pon de tu parte y te ayudaremos ;)

Saludos.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Kaxperday

Hola kubox agradezco enormemente tu respuesta, me acabo de instalar el firebug ya aprenderé a usarlo, hasta ahora para ver las variables me iba al código fuente y buscaba las etiquetas del form, allí estaban las variables para iniciar sesión que necesitaba.

He puesto esas variables en el código de arriba, el hotmail y la contraseña y las he cargado con un hotmail y contraseña auténticos, y he puesto la url de la página de login.

Estoy en la página de login y hago POST a las variables que necesito para iniciar sesión pero qué ocurre? ¿cómo se si me ha funcionado?, antes pensaba en hacer algo que vaya haciendo POST de una url a otra (pues al iniciar sesión te redirige a varias páginas dónde te carga cookies etc).
Pero al leer esto parece que no es necesario que con esto funcionaría con la colección de cookies.

Pero vaya entiendo poco, y no se si he iniciado sesión o nisiquiera si funciona, en la página el método es POST, vaya preferiría no darte la url y variables reales de la página, si quieres te mando un privado.

Estoy en ello, gracias.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

kub0x

Cita de: Kaxperday en 24 Noviembre 2014, 23:17 PM
Pero vaya entiendo poco, y no se si he iniciado sesión o nisiquiera si funciona, en la página el método es POST, vaya preferiría no darte la url y variables reales de la página...

Para saber si has logeado tendrás que comprobar el código fuente de la respuesta HTML que te envía el servidor del login. Ahí habrá un mensaje de error en el caso de no haberte conectado. En el caso de haberte conectado, tendrás que ver si el HTML tiene el apartado de "Correo Outlook" o otro servicio que solo salga en el HTML al estar logeado. Es decir, toca parsear HTML.

Te recomiendo que uses Firebug para ver las peticiones que envías al servidor, sean GET o POST, para así tener una referencia directa y real de los datos que se envían al server, además, Firebug te saca las cookies, para que puedas comprobar si las cookies están siendo recogidas por tu code.

Para coger la respuesta del servidor haz lo siguiente, ten en cuenta que lo he escrito al momento, sin testear:

Código (csharp) [Seleccionar]

HttpWebResponse response = (HttpWebResponse)newStream.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
String responseHtml = sr.ReadToEnd();
sr.Close();
responseStream.Close();
response.Close();
//Aquí harías la validación del código fuente
//Buscarías errores de login dentro del HTML (Ejemplo: User y pass no validos..)


Un saludo.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Kaxperday

#4
OMG, lo acabo de probar tenías un error que lo corregí o eso creo.
Lo he mostrado por pantalla y me acaba de salir un santo HTML de 1000 lineas xD.
Supongo que querrías decir esto:

Código (csharp) [Seleccionar]

CookieCollection cookies = new CookieCollection();
HttpWebRequest cookieRequest = (HttpWebRequest)WebRequest.Create("http://pagina.com/login");
cookieRequest.CookieContainer = new CookieContainer();
cookieRequest.CookieContainer.Add(cookies);
HttpWebResponse response = (HttpWebResponse)cookieRequest.GetResponse();
Stream responseStream = response.GetResponseStream();
StreamReader sr = new StreamReader(responseStream);
String responseHtml = sr.ReadToEnd();
sr.Close();
responseStream.Close();
response.Close();


Supongo y solo supongo, puse MessageBox.Show(responseHtml), y me salio un pedazo de html, pero como puedo ver las cookies que tengo, las cookies que he recibido y saber si está la de inicio de sesión supongo que esa será una de las maneras de validar si se ha iniciado sesión correctamente, saludos y gracias.

Sigo con ello.

Edito: Las cookies las suelo ver con el HTTP HEADERS, busco uno llamada JESSESIONID, aunque probaré también con el firebug, aunque no se como verlas con el código, no deja pasarlo a cadena xd

Vaya con el firebug acabo de ver las cookies, me sale alguna cookie de otra web, pensaba que trabajaba con una página solo xd, entre otras tiene:

__insp_norec_sess
__insp_nv
__insp_ref
__insp_slim
__insp_wid
_ga
_gat
_gat_newTracker

Me extraño no ver la de JSESSIONID, pues al iniciar sesion con HTTP LIVE HEADERS aparece quizás sea temporal, bueno entonces son esas de ahí las que parecen interesar.

Aaamigo mio parece que no he iniciado bien la sesión porque en el HTML devuelto me pone esta dulzura:

<div class="error_arrow-absolute nerror error_password_not_valid none">Contraseña incorrecta<div class="arrow-up"></div>

Así que nada, luego vi algo de las cookies todas ellas embebidas en funciones de javascript (pues claro es lo que se usa para inyectarlas xD), supongo que debería rascar cada cookie con sus atributos si mi inicio de sesión hubiera sido correcto e intentar hacer el POST con la sesión utilizando las cookies recibidas.

Saludos, sigo en ello.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

kub0x

Hazme caso, antes de codear analiza el escenario, codear es lo último, te recomiendo que uses Firebug para ver la info que estás enviando, a que web, que método (POST) y las cookies. Luego ya introduces esos valores dentro del código.

Para saber que cookies has recibido en la respuesta, simplemente consulta la propiedad Cookies del objeto HttpWebResponse (response.Cookies), ahí está el contenedor de las cookies, así que puedes comprobarlas iterando esa estructura.

La respuesta HTML que recibes sirve para validar si hay algún mensaje de error dentro de la respuesta. El MsgBox obviamente te desplegará una ventana enorme, tienes que idear un método para encontrar posibles errores de login dentro de la página. Esto último es fácil, haz mal el login en tu correo de forma normal (con firefox/chrome whatever) y apunta el mensaje de error. Ahora en C# sólo te falta buscar ese mensaje de error en la variable responseHtml.

Saludos.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Kaxperday

#6
Vaya estaba modificando el último mensaje cuando ya habías escrito la nueva respuesta.

Si ya he encontrado que hay un error de login, si en firebug ya he iniciado sesión y tengo todas las cookies (las he encontrado alli si xD), ahora lo que busco es comprobar si las cookies que obtengo son las mismas que las de firefox, para ello he probado maneras para mostrarlas, pero (se que es una chorrada pero no la encuentro), como puedo saber que cookies tengo si no las see mostrar por pantalla xD, no se como obtener el string para poderlo mostrar response.Cookies.*?

Gracias, sigo con ello.

Edito: Aaamigo ya he encontrado la cookie JSESSIONID, resultaba ser de otro dominio, OMG que cosa más rara es una cookie de otro dominio que se crea cuando inicias sesion en la página, una cookie externa, ¿por que? Tambien hay otra cookie que le ocurre lo mismo __cfduid esa tambien pertenece a otro dominio pero se crea al iniciar sesion en la página,  luego algunas de youtube (jeje) y las demás son de la pagina.

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

kub0x

Supongo que te conectarás a un sitio pasarela estilo login.live.com. Esos dominios suelen redireccionarte a otros, por lo que las cookies corresponden al dominio destino realmente. Las cookies de terceros pueden ser trackers que estén absorbiendo información tuya, o pueden pertenecer a plataformas o servicios adjuntos.

Para ver las cookies en C# -> http://msdn.microsoft.com/es-es/library/system.net.httpwebresponse.cookies%28v=vs.110%29.aspx

Sigue posteando tu progreso ;)

Saludos.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Kaxperday

#8
Código usado (no asustarse):

Código (csharp) [Seleccionar]

CookieCollection cookies = new CookieCollection();
           HttpWebRequest cookieRequest = (HttpWebRequest)WebRequest.Create("http://paginar/login");
           cookieRequest.CookieContainer = new CookieContainer();
           cookieRequest.CookieContainer.Add(cookies);
           HttpWebResponse cookieResponse = (HttpWebResponse)cookieRequest.GetResponse();
           cookies = cookieResponse.Cookies;

           string postData = "action=login&ref=&email=nombre%40hotmail.com&password=apellido";
           HttpWebRequest loginRequest = (HttpWebRequest)WebRequest.Create("http://pagina/login");
           loginRequest.CookieContainer = new CookieContainer();
           loginRequest.CookieContainer.Add(cookies);
           loginRequest.Method = WebRequestMethods.Http.Post;
           loginRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
           loginRequest.AllowWriteStreamBuffering = true;
           loginRequest.ProtocolVersion = HttpVersion.Version11;
           loginRequest.AllowAutoRedirect = true;
           loginRequest.ContentType = "application/x-www-form-urlencoded";

           byte[] byteArray = Encoding.ASCII.GetBytes(postData);
           loginRequest.ContentLength = byteArray.Length;
           Stream newStream = loginRequest.GetRequestStream(); //open connection
           newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
           newStream.Close();

           HttpWebResponse response = (HttpWebResponse)cookieRequest.GetResponse();
           Stream responseStream = response.GetResponseStream();
           StreamReader sr = new StreamReader(responseStream);
           String responseHtml = sr.ReadToEnd();
           foreach (Cookie cook in response.Cookies)
           {
               tb_instrucciones.Text += ("Cookie:");
               tb_instrucciones.Text +=("{0} = {1}"+ cook.Name+ cook.Value);
               tb_instrucciones.Text +=("Domain: {0}"+ cook.Domain);
               tb_instrucciones.Text +=("Path: {0}"+ cook.Path);
               tb_instrucciones.Text +=("Port: {0}"+ cook.Port);
               tb_instrucciones.Text +=("Secure: {0}"+ cook.Secure);

               tb_instrucciones.Text += ("When issued: {0}" + cook.TimeStamp);
               tb_instrucciones.Text += ("Expires: {0} (expired? {1})" +
                   cook.Expires+ cook.Expired);
               tb_instrucciones.Text += ("Don't save: {0}" + cook.Discard);
               tb_instrucciones.Text += ("Comment: {0}" + cook.Comment);
               tb_instrucciones.Text += ("Uri for comments: {0}" + cook.CommentUri);
               tb_instrucciones.Text += ("Version: RFC {0}  cook.Version == 1 ? \"2109\" : \"2965\"");

               // Show the string representation of the cookie.
               tb_instrucciones.Text = ("String: {0}" + cook.ToString());
           }
           sr.Close();
           responseStream.Close();
           response.Close();
           MessageBox.Show(responseHtml);
           //tb_instrucciones.Text = responseHtml;


Sigo en ello, con gente como tu da gusto me aprendía todo en un día  ;-)

Edito: vale me sale que tiene 2 cookies en la colección usé esto: MessageBox.Show(response.Cookies.Count.ToString());

Edito: La madre que lo pario, la linea 47 igualaba y no añadia fail mio xD, sigue teniendo olo 2 cookies.
Ahora si me salen todas las cookies buena parrafada:

Cookie:{0} = {1}dsi=15c551cc68647dcf586e60d50f9485cf15c55f1c%7Ew08%2BrKK6Bkh1hE%2B%2Fb3rYk8fvkl0oSJpdzDsf5U4BzKGx%2BI1jRcY9Qelpl36x%2FMJS14eBS%2BJDdoOM9c8UMPu%2FTQfyrz4jaoQ%2FJ6ghK%2B%2BHmoCX37vxqLw1MWfDP50awAIqqqDRTb22fTpklZH8%3DDomain: {0}pag.comPath: {0}/Port: {0}Secure: {0}FalseWhen issued: {0}25/11/2014 1:07:10Expires: {0} (expired? {1})25/11/2014 13:07:15FalseDon't save: {0}FalseComment: {0}Uri for comments: {0}Version: RFC {0}  cook.Version == 1 ? "2109" : "2965"String: {0}dsi=15c551cc68647dcf586e60d50f9485cf15c55f1c%7Ew08%2BrKK6Bkh1hE%2B%2Fb3rYk8fvkl0oSJpdzdDs5U4BzKGx%2BI1jRcY9Qelpl36x%2FMJS14eBS%2BJDdoOM9c8UMPu%2FTQfyrz4jaoQ%2FJ6ghK%2B%2BHmoCX37vxqLw1MWfDP50awAIqqqDRTb22fTpklZH8%3DCookie:{0} = {1}dgbs%5B%5DDomain: {0}pagina.comPath: {0}/Port: {0}Secure: {0}FalseWhen issued: {0}25/11/2014 1:07:10Expires: {0} (expired? {1})25/12/2014 1:07:15FalseDon't save: {0}FalseComment: {0}Uri for comments: {0}Version: RFC {0}  cook.Version == 1 ? "2109" : "2965"String: {0}dgbs=%5B%5D

Parece ser que obtendo 2 cookies llamadas dsi, Algo que no me extraña pues intenté hacer este programa en C++ y al hacer el post sobre la url del login, me devolvía 2 cookies llamadas dsi, pero por otro lado me asusta porque quizás indique que esto no haga las redirecciones donde va cogiendo y soltando cookies, como las cookies de dominios de terceros.

Cambio y corto, mañana vuelvo con ello, gracias kub0x.

Edito: Bueno sigue sin iniciar sesión, pero tengo una duda esto simplemente hace un POST la url del login con las variables del POST para loguearse (hotmail, pass...) cosa que no iniciaría sesión ya que tras ese POST hay que hacer varios más a otras páginas de otros dominios para obtener otras cookies y poder llegar a logurarse realemente, O este código me haría ya todas las redirecciones para iniciar sesión como ponía el que lo creó?, cosa que cada vez me creo menos xS

Si obtengo las 2 cookies dsi (me debería quedar solo con la segunda según RFC), pero ahora ¿que viene después?, saludos y gracias.

Edito: La única solución que veo factible ya que no me aplica redirecciones automáticas a pesar de esto: (Pues es como si no pongo nada)

Código (csharp) [Seleccionar]
loginRequest.AllowAutoRedirect = true;
loginRequest.MaximumAutomaticRedirections = 300;


Es copiar con HTTP LIVE HEADERS el mecanismo de firefox cuando inicia sesión en la web y copiar los mismos POST aunque la dificultad estará en encontrar los vitales, y los que son prescindibles, los navegadores automatizan este proceso de redireccionamiento, podemos codearlo (muy complejo) o copiar a firefox para esa página y ya nos funcionará el inicio de sesión para esa página solo pero habremos cumplido el objetivo, no se si voy bien encaminado.

Edito: Buenas gente decidí cambiar el método de inicio de sesión, y buscando y buscando y buscando encontré un código para iniciar sesión en twitter, y lo he traspasado a mi web a la que quiero iniciar sesión, esta no tiene authenticy_token luego podemos quitarlo pero para iniciar sesión en mi página es necesario cargar 2 cookies de terceros dominios para más seguridad será.

La salida esta en la clase WebBrowser he encontrado un posible camino pues.

LINK: http://eclipsed4utoo.com/blog/tag/website/

El caso es que no me va el inicio de sesión aún, me dice error 403, que he podido iniciar bien sesión pero que no tengo permiso para ver la página, de alguna manera me han detectado que soy un bot, o que me faltan cookies de terceros dominios, cuando se ejecuta el código te hacen ejecutar scripts js, probadlo si os interesa, sigo en ello.

Código (csharp) [Seleccionar]
string url = "http://pagina.com/login";
   string username = "larala";
   string password = "larali";
   string commit = "Sign+In"; //this matches the data from Tamper Data

private void botonIniciarSesion_Click(object sender, EventArgs e)
       {
           WebBrowser b = new WebBrowser();
           b.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(b_DocumentCompleted);
           b.Navigate(url);
       }


   private void b_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
   {
        WebBrowser b = sender as WebBrowser;
        string response = b.DocumentText;

        // unregisters the first event handler
       // adds a second event handler
        b.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(b_DocumentCompleted);
       b.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(b_DocumentCompleted2);

     // format our data that we are going to post to the server
      // this will include our post parameters.  They do not need to be in a specific
      // order, as long as they are concatenated together using an ampersand ( & )
       string postData = string.Format("action=login&ref=&email=larala&password=larali");
   
      ASCIIEncoding enc = new ASCIIEncoding();

      //  we are encoding the postData to a byte array
          b.Navigate("http://pagina.com/cuestiones", "", enc.GetBytes(postData), "Content-Type: application/x-www-form-urlencoded\r\n");
   }

   private void b_DocumentCompleted2(object sender, WebBrowserDocumentCompletedEventArgs e)
   {
        WebBrowser b = sender as WebBrowser;
        string response = b.DocumentText;
            tboxInstrucciones.Text = response;
        if (response.Contains("MINOMBREUSUARIO"))
        {
            MessageBox.Show("Login Successful");
        }
   }


ENJOY.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

kub0x

#9
La verdad, no me ha sido díficil logearme con el code que he hecho en C#, supongo que habrás seguido mal mis pasos o te habrás desviado del tema. HTTP Live Headers era el plugin que usaba antes de FireBug, ya que FireBug permite hasta consultas AJAX, javascript, Cookies además lo gestiona manera práctica.

Prueba lo siguiente en mi code:

1. Haz un intento de login falso y mira el mensaje. Deberia de ser "Login failed!"
2. Haz login con tus credenciales y mira el mensaje. Debería de ser "Login Successful!"

Código (csharp) [Seleccionar]
using System;
using System.IO;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace POSTLogin
{
   class Program
   {
       static void Main(string[] args)
       {
           SendRequest();
           Console.Read();
       }

       private static void SendRequest()
       {
           string postData = "email=tuemail@dominio.com&password=tupassword";
           byte[] byteData = ASCIIEncoding.ASCII.GetBytes(postData);
           HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create("http://login.web.com");
           req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
           //req.Connection = "keep-alive";
           req.ContentType = "application/x-www-form-urlencoded";
           req.ContentLength = byteData.Length;
           req.UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:33.0) Gecko/20100101 Firefox/33.0";
           req.Host = "login.web.com";
           req.Method = "POST";
           req.Proxy = null;
           using (Stream reqStream = req.GetRequestStream())
               reqStream.Write(byteData, 0, byteData.Length);
           GetResponse(req);
       }

       private static void GetResponse(HttpWebRequest req)
       {
           HttpWebResponse response = (HttpWebResponse) req.GetResponse();
           using (Stream responseStream = response.GetResponseStream())
           {
               using (StreamReader sr = new StreamReader(responseStream))
               {
                   string responseData = sr.ReadToEnd();
                   if (!responseData.Contains("Iniciar se"))
                       Console.WriteLine("Login successful!");
                   else
                       Console.WriteLine("Login failed!");
               }
           }
       }

   }
}


Saludos.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate