Windows 8 «Consumer Preview»

Logo de Windows 8

Logo oficial de Windows 8

Hace una semanas Microsoft puso disponible para la descarga una versión de su próximo a ser lanzado, sistema operatico Windows 8 que fue denominada «Consumer Preview». Esta versión tiene la intención de funcionar a modo de Beta para que le gente puede ir experimentando sus nuevas funcionalidades y, sobre todo, la interfaz Metro aparecida por primera vez en Zune, heredada por Windows Phone 7, y ahora utilizada en Windows 8.

Para descargar esta versión de prueba, pueden entrar aquí:

http://windows.microsoft.com/es-AR/windows-8/download

Categorías: General Etiquetas: , ,

Visual Studio 2010 RTM

Visual Studio 2010

Finalmente estamos llegando a las versiones finales del tan esperado Visual Studio 2010. Para esta ocasión, Microsoft ha lanzado las versiones express y las versiones trial, las cuales ya están disponibles desde aquí.

¡A darle!

Categorías: General Etiquetas: , ,

Visual Studio 2010 RC

Visual Studio 2010

Visual Studio 2010

Hola a todos.

Desde hace unas semanas ya está disponible para la descarga el Visual Studio 2010 Release Candidate. Este nuevo y mejorado IDE viene integrado para trabajar con el nuevo .NET Framework 4.0.

Esta versión pueden conseguirla en la página de la MSDN.

Categorías: General Etiquetas: , ,

Proveedores de Membresía en ASP.NET

Uno de los aspectos más importantes en el desarrollo de un portal o sitio web suele ser generalmente la autenticación y autorización de usuarios. En primer lugar hay que diferenciar estos dos conceptos. La autenticación es el proceso de identificación de los usuarios que acceden a la aplicación; y la autorización es el proceso de establecer qué es lo que puede hacer o a qué datos puede acceder este usuario. Los proveedores de membresía en ASP.NET se relacionan con el primer punto: la autenticación. Tienen por objetivo gestionar e identificar a los usuarios que van ingresando.

En .NET aparecen incorporados ya algunos proveedores de membresía, como el SqlMembershipProvider, los cuales permiten agilizar notablemente el desarrollo de los sitios y aplicaciones. Este proveedor permite almacenar y recuperar los usuarios utilizando como almacén de datos a SQL Server.

Sin embargo, puede darse el caso en el que se requiera trabajar con otra fuente de datos, por ejemplo Oracle o MySQL. En tales casos se puede realizar todo este proceso de autenticación en forma manual y a pulmón a lo largo de la aplicación, o bien podemos también implementar nuestro propio proveedor de membresía adaptándolo a nuestro gusto. Esta última opción puede resultar larga y engorrosa en el corto plazo, pero a largo plazo nos veremos beneficiados con los frutos de la reusabilidad. Este componente que se crea aquí puede ser implementado en cualquier otra aplicación web que posea un proceso de autenticación similar o con requerimientos similares.

Para implementar un nuevo proveedor sólo debemos crear una clase que herede de la clase abstracta MembershipProvider en el espacio de nombres System.Web.Security. Una documentación detallada sobre la implementación la podemos encontrar en MSDN, y un buen ejemplo fue hecho por Mads Kristensen y publicado en su blog. Este ejemplo es quizás el más útil y práctico. Básicamente, creo un proveedor de membresía basado en XML. Con ciertas modificaciones, podemos llevarlo a cualquier almacén de datos que queramos.

Categorías: General Etiquetas: , ,

Incorporar Live ID en nuestro sitio – Segunda Parte

18 diciembre 2009 4 comentarios

Después de un tiempo, vamos a cerrar el tema de la utilización de Windows Live ID en nuestra aplicación Web. En el post anterior expliqué que para poder utilizar esta API necesitábamos del una App ID provista por Azure y el SDK de autenticación web. Me voy a basar en estos dos elementos para desarrollar lo que sigue.

Antes de comenzar a explicar tengo que algo con respecto a Live ID y su utilización: el hecho de que manejemos este servicio de Microsoft no implica que tendremos acceso a los datos e información referente a los usuarios que inicien sesión con él. Con la aplicación combinada de una clase provista por el SDK y del App ID, lo que obtendremos será un User ID. Este User ID es única para cada App ID, y es el identificador de usuarios que se almacenará en la base de datos.

El SDK trae consigo una clase llamada WindowsLiveLogin. Esta clase tiene métodos para la obtención automática de las URL de inicio y cierre de sesión de Windows Live en base a ciertos parámetros, como el algoritmo de seguridad y el App ID. En verdad que para lo que quiero mostrar, no hace falta escarbar mucho en la funcionalidad que nos da esta clase. Al menos en mi caso pude hacer funcionar el proceso de autenticación sin mayores problemas y con un conocimiento bastante superficial sobre su funcionamiento. Si a alguien le interesa hacerse el guapo y largarse a tunear el código… be my guest.

En el SDK podemos encontrar los siguientes elementos:

  1. El acuerdo de licencia del SDK. (WindowsLiveSDKLicenseAgreement.htm).
  2. Un Léeme con información sobre documentación.
  3. Una carpeta Sample.
  4. La carpeta App_Code de ASP.NET.

Lo esencial para poder trabajar y hacer un ejemplo de alta de usuarios está contenido en estas dos últimas carpetas. En la carpeta App_Code se encuentra la clase WindowsLiveLogin que mencioné anteriormente, y en la carpeta Sample hay dos páginas ASPX y un archivo de configuración.

La página webauth-handler.aspx es la página que crea, destruye o limpia la cookie de autenticación dependiendo de la acción enviada por el proceso de autenticación de Windows Live.

La página default.aspx es la que (en este caso) contiene el control de inicio de sesión de Windows Live ID. Este control no es más que un iframe que apunta a un URL de inicio de sesión. El código de este iframe es:

<iframe id="WebAuthControl" name="WebAuthControl" src="http://login.live.com/controls/WebAuth.htm?appid=<%=AppId%>&style=font-size%3A+10pt%3B+font-family%3A+verdana%3B+background%3A+white%3B"
  width="80px" height="20px" marginwidth="0" marginheight="0" align="middle" frameborder="0"
            scrolling="no"></iframe>

El App ID es enviado en la URL que apunta al iframe. Si vemos el código de default.aspx se puede ver que este App ID se lo extrae de una instancia de WindowsLiveLogin, y que ésta lo saca del archivo de configuración. En el archivo de configuración podemos encontrar un App ID por defecto. Si se quiere, se lo puede modificar con el que obtuvimos en los servicios Azure, pero para lo que quiero mostrar no tiene sentido. Esto es porque el que obtuve en Azure me redireccionará la página hasta el URL de redirección que establecí cuando creé el proyecto. El App ID que trae por defecto el SDK nos redirecciona a la página:

 http://localhost/webauth/Sample/webauth-handler.aspx

De esta forma, a los fines de prueba, nos limitaremos a trabajar con este App ID. Una vez que el sitio entre en producción, se podrá trabajar con el App ID real, y por ende con los usuarios reales.

Dicho todo esto, paso a explicar como viene la mano con el inicio de sesión. El funcionamiento lógico es el siguiente:

  1. Una página (la llamaremos Login.aspx) tiene incorporado el iframe con el inicio de sesión de Windows Live. Aquí aparece un link para que iniciemos sesión o la cerremos si es que ya está abierta.
  2. El usuario (que no ha iniciado sesión) hace click para iniciar sesión y se le presenta la página de inicio de sesión de Windows Live.
  3. Cuando el usuario ingresa sus credenciales, Windows Live redirecciona al usuario a otra página, de acuerdo al App ID que recibió. Si es que le dejamos el App ID por defecto, el explorar será redireccionado al webauth-handler.aspx en nuestra máquina (la dirección por defecto que puse arriba), sino lo hará al que corresponda. Es por este motivo que en el sitio que hice aparece la carpeta Sample con webauth-handler.aspx dentro.
  4. La página webauth-handler.aspx, después de terminar con acción correspondiente, redirecciona al explorador hacia otra página. En el ejemplo, la página es la Default.aspx que está en la raíz del sitio.
  5. Es en esta página en donde voy a incorporar la lógica para el reconocimiento de usuarios. Si el usuario no existe, pasará directamente a ser registrado. Todo esto se hace utilizando el User ID creado en la cookie, que se puede obtener con la clase WindowsLiveLogin.

La página Login.aspx tiene incorporado el iframe de inicio de sesión, y en el code behind sólo tiene el siguiente código:

static WindowsLiveLogin wll = new WindowsLiveLogin(true);
protected static string AppId = wll.AppId;

protected void Page_Load(object sender, EventArgs e)
{

}

Esto es para poder extraer el valor de la variable AppID desde la página mediante un binding.

La página Default.aspx tiene el siguiente code behind:

const string LoginCookie = "webauthtoken";
    protected string UserId;
    static WindowsLiveLogin wll = new WindowsLiveLogin(true);

    protected void Page_Load(object sender, EventArgs e)
    {
        HttpRequest req = HttpContext.Current.Request;
        HttpCookie loginCookie = req.Cookies[LoginCookie];

        if (loginCookie != null)
        {
            string token = loginCookie.Value;
            if ((token != null) && (token.Length != 0))
            {
                WindowsLiveLogin.User user = wll.ProcessToken(token);
                if (user != null)
                {
                    UsuariosDAL udal = new UsuariosDAL();
                    if (!udal.ExisteUsuario(user.Id))
                    {
                        Response.Redirect("Registrarse.aspx");
                    }
                    else
                    {
                        Response.Write(String.Format("<b>Bienvenido usuario {0}</b><br/>", user.Id));
                        Response.Write(String.Format("Su nombre de usuario es <strong>{0}</strong>", udal.RecuperarNombreUsuario(user.Id)));
                    }
                }
                else
                {
                    Response.Redirect("Login.aspx");
                }
            }
            else
            {
                Response.Redirect("Login.aspx");
            }
        }
        else
        {
            Response.Redirect("Login.aspx");
        }

    }

Lo que se hace aquí básicamente es intentar extraer el usuario que se encuentra autenticado actualmente. Si no se puede, entonces lo mandamos a la página de inicio de sesión (Login.aspx). Si el usuario está autenticado, pero no está registrado, lo enviamos a la página de registro (Registrarse.aspx). Si el usuario está registrado, entonces muestra su User ID y su nombre de usuario.

La página de registración es

Dibujo

Los cuadros de texto son los datos que debe completar un nuevo usuario. Esto sólo se muestra si el usuario que tiene la sesión abierta actualmente no está registrado en nuestro sitio. El code behind es

const string LoginCookie = "webauthtoken";
static WindowsLiveLogin wll = new WindowsLiveLogin(true);
protected static string AppId = wll.AppId;

protected void Page_Load(object sender, EventArgs e)
{

    HttpRequest req = HttpContext.Current.Request;
    HttpCookie loginCookie = req.Cookies[LoginCookie];
    if (loginCookie != null)
    {
        string token = loginCookie.Value;
        if ((token != null) && (token.Length != 0))
        {
            WindowsLiveLogin.User user = wll.ProcessToken(token);
            if (user != null)
            {
                UsuariosDAL udal = new UsuariosDAL();
                if (udal.ExisteUsuario(user.Id))
                {
                    Response.Redirect("Default.aspx");
                }
            }
            else
            {
                Response.Redirect("Login.aspx");
            }
        }
        else
        {
            Response.Redirect("Login.aspx");
        }
    }
    else
    {
        Response.Redirect("Login.aspx");
    }
}

protected void OkButton_Click(object sender, EventArgs e)
{
    HttpRequest req = HttpContext.Current.Request;
    HttpCookie loginCookie = req.Cookies[LoginCookie];
    if (loginCookie != null)
    {
            string token = loginCookie.Value;
            if ((token != null) && (token.Length != 0))
            {
                WindowsLiveLogin.User user = wll.ProcessToken(token);
            if (user != null)
            {
                UsuariosDAL udal = new UsuariosDAL();
                if (!udal.ExisteUsuario(user.Id))
                {
                    udal.Agregar(NombreUsuarioTextBox.Text, EmailTextBox.Text, user.Id);
                    Response.Redirect("Default.aspx");
                }
            }
            else
            {
                Response.Redirect("Login.aspx");
            }
        }
        else
        {
            Response.Redirect("Login.aspx");
        }
    }
    else
    {
        Response.Redirect("Login.aspx");
    }
}

Aquí simplemente se intenta extraer el usuario que está autenticado. Si no existe o no se lo puede extraer, se pasa a la página de inicio de sesión. Si el usuario existe y está registrado, se redirecciona a Default.aspx. De otro modo se lo de de alta en la “base de datos”, pidiéndole su nombre de usuario y correo electrónico.

La base de datos que he manejado no es otra cosa que un archivo XML. Me decidí por esto debido a su simplicidad. A los fines de mostrar como agregar y autenticar usuarios utilizando Live ID, es más que suficiente. Aquí está el código de la clase UsuariosDAL:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Configuration;
using System.IO;
using System.Xml.Linq;

/// <summary>
/// Summary description for UsuariosDAL
/// </summary>
public class UsuariosDAL
{
    XmlDocument usuariosXml;
    const string baseXml = "<?xml version=’1.0′ encoding=’utf-8′ ?><Usuarios></Usuarios>";
    string fileName = ConfigurationManager.AppSettings["UsersFileName"];

    public UsuariosDAL()
    {
        usuariosXml = new XmlDocument();
        if (!File.Exists(fileName))
        {
            usuariosXml.LoadXml(baseXml);
            usuariosXml.Save(fileName);
        }
        else
        {
            usuariosXml.Load(fileName);
        }
    }

    public bool ExisteUsuario(string userId)
    {
        return usuariosXml.DocumentElement.ChildNodes.Cast<XmlElement>().Any(e => e.Attributes["userId"].Value == userId);
    }

    public string RecuperarNombreUsuario(string userId)
    {
        return usuariosXml.DocumentElement.ChildNodes.Cast<XmlElement>().First<XmlElement>(e => e.Attributes["userId"].Value == userId).Attributes["nombreUsuario"].Value;
    }

    public void Agregar(string nombreUsuario, string email, string userId)
    {
        XmlElement nuevoElemento = usuariosXml.CreateElement("Usuario");
        XmlAttribute atributo = usuariosXml.CreateAttribute("userId");
        atributo.Value = userId;
        nuevoElemento.Attributes.Append(atributo);

        atributo = usuariosXml.CreateAttribute("nombreUsuario");
        atributo.Value = nombreUsuario;
        nuevoElemento.Attributes.Append(atributo);

        atributo = usuariosXml.CreateAttribute("email");
        atributo.Value = email;
        nuevoElemento.Attributes.Append(atributo);

        usuariosXml.DocumentElement.AppendChild(nuevoElemento);

        usuariosXml.Save(fileName);
    }
}

La idea también podría ser implementar esta autenticación con el proveedor de membresía provisto por ASP.NET: el SqlMembershipProvider. En este caso se tendrían que manejar los perfiles para manejar cada User ID asociado a cada usuario.

Si quieren ver el código completo (de todas maneras creo que no me olvidé nada) de la aplicación, pueden descargarlo de la carpeta "Código" de mi SkyDrive; el archivo es "Autenticacion.rar". Espero les sea útil.

Categorías: General