none
Autenticar app windows store winrt con web service o WCF RRS feed

  • Pregunta

  • Hola buen día,

    Siempre me han ayudado de forma implicita cuando leo el foro pero ya llevo algo de tiempo y sigo mas perdido que nunca.

    Estoy tratando de autenticar a usuarios mediante Web Service o WCF, los mismos si hacen su función, me regresan un true/false segun sea, el verdadero problema vienen por el echo de que no puedo generar las cookies para mantener viva la sesión, me podran recomendar como mantener la sesiójn de un usuario, ya trate con System.Web y con System.Net y no he dado con la forma. uso C# y XAML

    Tengo un servidor aparte con IIS que me sirve para publicar los servicios, una estructura con Active directory con usuarios, espero me haya explicado correctamente,

    Saludos.

    jueves, 24 de enero de 2013 23:19

Todas las respuestas

  • Hola Victor

    Desconozco el sistema que usas de autenticacion, de modo que voy a intentar poner un ejemplo sencillo del que partir.

    Supongamos que tenemos un servicio WCF al cual tiene acceso cualquier usuario y en el una funcion de login como esta:

    /// <summary>
    /// Función para logearse en el sistema
    /// </summary>
    /// <param name="username">Nombre de usuario</param>
    /// <param name="password">Contraseña</param>
    /// <returns>Estado</returns>
    public bool logon(string username, string password)
    {
        // Valida el nombre de usuario y la contraseña
        //if (Membership.ValidateUser(_user.UserName, _user.UserPassword))     // Sistema de pertenencias
        if (System.Web.Security.FormsAuthentication.Authenticate(username, password))   // autenticacion forms en webconfig
        {
            // Crear el vale de autenticacion de usuario bajo ASPNET y establecer la cookie de autenticacion en modo FORMS
            System.Web.Security.FormsAuthentication.SetAuthCookie(username, true);
            return true;
        }
        return false;
    }

    Como no se el metodo que usas de autenticacion, en el ejemplo he usado 2 validaciones, una usando el sistema de pertenencas de ASPNET y la otra usando autenticacion forms en la cual puedes tener los usuarios en el webconfig bajo el tag authenticacion, algo como esto:

        <authentication mode="Forms">
          <forms loginUrl="error.aspx">
            <credentials>
              <user name="root" password="997395901303578bec0519850225jd274d30200e" />
            </credentials>
          </forms>
        </authentication>
        <authorization>

    Bien, hasta aqui la parte del servicio, que solo verifica que el usuario existe y añade una cookie de autenticacion de aspnet en la respuesta de la peticion al servicio.

    Ahora supongamos que queremos llamar a un servicio que esta en un directorio protegido, un directorio que tenga una configuracion como esta en el web.config:

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <authorization>
          <!-- No permitir el acceso a ningun usuario no logeado -->
          <deny users="?"/>
        </authorization>
      </system.web>
    </configuration>

    Al llamar a este servicio te daria error, de echo si se pusiera en la url la direccion al servicio, te redirigiria a la pagina de logueo o la que se haya configurado, de modo que es necesario llamar al servicio mediante una cookie de autenticacion que sera creada llamando al servicio con la funcion logon que he puesto al principio.

    para ello se puede usar un codigo como el siguiente:

    /// <summary>
    /// Funcion de prueba para llamar a un servicio seguro
    /// </summary>
    /// <returns></returns>
    public void callSecureService()
    {
        // obtener cookie mediante el servicio web de autenticacion
        string cookie = getAuthCookie("user", "password");
    
        // verificar cookie
        if (string.IsNullOrWhiteSpace(cookie)) return;
    
        // crear objetos para modificar la cabecera de la peticion al servicio seguro y enviarle la cookie de autenticacion
        System.ServiceModel.Channels.HttpRequestMessageProperty httpRequestProperty = new System.ServiceModel.Channels.HttpRequestMessageProperty();
        httpRequestProperty.Headers.Add(System.Net.HttpRequestHeader.Cookie, cookie);
    
        // Cliente WCF para invocar el servicio restringido
        ServiceReference2.IaaaClient securedService = new ServiceReference2.IaaaClient();
    
        // inicializar el ambito para la llamada al servicio restringido
        string result = null;
        using (new System.ServiceModel.OperationContextScope(securedService.InnerChannel))
        {
            // establecer la cabecera con la cookie de autenticacion
            System.ServiceModel.OperationContext.Current.OutgoingMessageProperties[System.ServiceModel.Channels.HttpRequestMessageProperty.Name] = httpRequestProperty;
            // llamar a la funcion del servicio restringido
            result = securedService.funcionServicioSeguro("parametros");
        }
    
        // mostrar el resultado en un mensage
        MessageBox.Show(result);
    }
    
    /// <summary>
    /// Funcion para obtener una cookie de autenticacion de un servicio web
    /// </summary>
    /// <param name="_nombre">Nombre para la autenticacion</param>
    /// <param name="_password">Contraseña para la autenticacion</param>
    /// <returns>Cookie de autenticacion o null si no se ha podido autenticar</returns>
    public static string getAuthCookie(string _nombre, string _password)
    {
        // variable para almacenar la cookie de autenticacion
        string authCookie = null;
    
        // crear el cliente WCF para el invocar el servicio de logon
        ServiceReference1.IlogClient authClient = new ServiceReference1.IlogClient();
    
        // inicializar un ambito para la operacion de autenticacion
        using (new System.ServiceModel.OperationContextScope(authClient.InnerChannel))
        {
            // llamar a la funcion del servicio de logon
            bool isValid = authClient.logon(_nombre, _password);
            // verificar que se ha logueado para continuar
            if (!isValid) return authCookie;
    
            // obtener el mensage de respuesta
            System.ServiceModel.Channels.HttpResponseMessageProperty response = 
                (System.ServiceModel.Channels.HttpResponseMessageProperty)System.ServiceModel.OperationContext.Current.IncomingMessageProperties[System.ServiceModel.Channels.HttpResponseMessageProperty.Name];
            // guardar la cookie del mensage de respuesta
            authCookie = response.Headers["Set-Cookie"];
        }
    
        // retornar la cookie de autenticacion
        return authCookie;
    }

    En este codigo existen 2 funciones, 'callSecureService' es la funcion principal que logueara al usuario y llamara al servicio seguro, 'getAuthCookie' es la funcion que llama al servicio de logon y obtiene la cookie de autenticacion.

    El codigo esta bien comentado, de modo que no hace falta explicacion.

    Una vez obtenida la cookie no hace falta llamar de nuevo al servicio de logon si se guarda y dependiendo de su ciclo de vida dado por el servicio de logon tendra mas o menos duracion.

    Hay que tener cuidado con las cookies, ya que son eviadas a traves de la red al cliente, de modo que aunque vayan encriptadas/codificadas, no es necesario desencriptar para poder suplantar el usuario.

    Si tienes alguna duda comentalo.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    lunes, 28 de enero de 2013 13:26
  • Hola David_González,

    Gracias por tu apoyo, en winRT no puedo agregar ninguna referencia mas cuando pongo la linea

    System.Web.Security.FormsAuthentication.SetAuthCookie(username, true);

    Me aparece -The type or namespace name 'Web' does not exist in the namespace- por lo cual no puedo seguir adelante, tengo un Web Service que me valida a los usuarios y lo hace correctamente, he pensado usar el panel de Charms para poner ahí un user control para la validación y a la antigua usansa tener una variable global para guardar el UserName ya que es lo unico que necesito, todos los demás servicios filtran la información en base al UserName.

    Seguiré buscando infomación ya que me parece que si se puede tener cookies en WinRT.

    Saludos en unos días mas me reporto.

    martes, 29 de enero de 2013 16:09
  • Hola Victor.

    Ese codigo es el codigo de servidor donde reside el servicio web de autenticacion, he puesto el ejemplo de una funcion de un servicio wcf de logon que debe correr bajo un servidor, la parte de cliente son las 2 ultimas funciones.


    Saludos
    David González
    MCP, MCTS
    Visita mi Blog en: http://www.dgzornoza.com/

    martes, 29 de enero de 2013 16:19