Usando ASP.NET membrership en Winforms (3 / n)

El modelo de objetos de membresía (Membership object model)

Membershipom

O lo que es lo mismo, el pan nuestro de cada día en lo relativo a administrar la seguridad basada en membresía. Para acceder a este cojunto de clases es necesario agregar los namespaces System.Web y System.Web.Extensions, que contienen las clases necesarias para interactuar con la base de datos de membresía descrita en el artículo anterior.

References

Conocer este conjunto de clases es vital para poder aprovechar todas las características de este sistema, de modo que aquí va una tabla con las principales elementos y funcionalidades:

Clase/interfaz

Funciones

Membership

Proporciona los servicios de suscripción generales.

Crea un nuevo usuario.

Elimina un usuario.

Actualiza un usuario con nueva información.

Devuelve una lista de usuarios.

Encuentra un usuario por el nombre o el correo electrónico.

Valida (autentica) un usuario.

Obtiene el número de usuarios conectados.

Busca los usuarios por el nombre de usuario o la dirección de correo electrónico.

MembershipUser

Proporciona información sobre un usuario concreto.

Obtiene la contraseña y la pregunta de la contraseña.

Cambia la contraseña.

Determina si el usuario está conectado.

Determina si el usuario está validado.

Devuelve la fecha de la última actividad, del último inicio de sesión y del último cambio de contraseña.

Desbloquea un usuario.

MembershipProvider

Define la funcionalidad de los proveedores de datos que el sistema de suscripción puede utilizar.

Define los métodos y las propiedades que necesita implementar un proveedor utilizado en la suscripción.

MembershipProviderCollection

Devuelve una colección de todos los proveedores disponibles.

MembershipUserCollection

Almacena las referencias a los objetos MembershipUser.

MembershipCreateStatus

Proporciona los valores descriptivos de éxito o error al crear un nuevo usuario suscrito.

MembershipCreateUserException

Define la excepción que se produce si no se puede crear un usuario. Hay un valor de enumeración MembershipCreateStatus disponible a través de la propiedad StatusCode que describe el motivo de la excepción.

MembershipPasswordFormat

Especifica los posibles formatos de almacenamiento de contraseñas utilizados por los proveedores de suscripciones incluidos con ASP.NET (Clear, Hashed, Encrypted).

Configurando nuestra aplicación

Nota: Esto pensaba dejarlo para más adelante, pero lo posteo aquí también por si alguien quiere animarse a hacer pruebas 😉

Para poder acceder al modelo de objetos, además de agregar las dos referencias que hemos comentado antes, también es necesario modificar el fichero de configuración de la aplicación (Web.config en un proyecto Web y App.config en un proyecto WinForms). Existen multitud de artículos que describen cómo hacerlo en el primero de los casos, así que nos vamos a centrar en el segundo.

Empezaremos con la configuración mínima para que funcione nuestra aplicación, y posteriormente iremos viendo distintas opciones para permitir que el sistema de seguridad se comporte de un modo distinto, por ejemplo, pidiendo una contraseña no tan restrictiva, o que no sea necesario indicar el email del usuario, o la pregunta y respuesta de seguridad.

El primer paso para configurar nuestra aplicación es agregar un fichero de configuración (App.config) a nuestro proyeco, o si ya tenemos uno, abrirlo para su edición. Toda la configuración se va a centrar en dos secciones: <connectionStrings> y <system.web>. En la primera es especificará una entrada que apunte a la base de datos de membresía, mientras que en la segunda se especificarán los valores para los proveedores de usuarios y roles:

<configuration>
  <connectionStrings>
    <add name="MemberShipConnectionString"
         connectionString="data source=.\SQLEXPRESS;Integrated Security=True;DataBase=Test"
         providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <system.web>
    <roleManager enabled="true">
      <providers>
        <clear/>
        <add name="AspNetSqlRoleProvider"
             type="System.Web.Security.SqlRoleProvider"
             connectionStringName="MemberShipConnectionString"
             applicationName="Test"/>
      </providers>
    </roleManager>
    <membership defaultProvider="SqlProvider">
      <providers>
        <clear/>
        <add name="SqlProvider" 
             type="System.Web.Security.SqlMembershipProvider"
             connectionStringName="MemberShipConnectionString"
             applicationName="Test"/>
      </providers>
    </membership>
  </system.web>
</configuration>

Oservemos que la cadena de configuración apunta a la BD que creamos en el post anterior, y que esta cadena de conexión se usa en la configuración de los proveedores de usuarios y roles. Otro detalle muy importante es que la clave applicationName contiene el nombre de nuestra aplicación para el sistema de membresía, de modo que todos los usuarios y roles que se creen estarán agrupados bajo este nombre de aplicación.

Por defecto, esta configuración hace que al momento de crear un usuario sea necesario proporcionar: Nombre, contraseña de un mínimo de 7 carácteres y uno de ellos ‘especial’ (por ejemplo: @#$%), email, pregunta de seguridad, respuesta de seguridad, y si va a estar aprobado o no. No está nada mal, de hecho podríamos decir que la configuración predeterminada es a su vez, la más segura.

Si deseamos cambiar esta configuración, par permitir que un usuario no pueda preguntarle al sistema cuál es su contraseña (sólo pueda resetearla), o por ejemplo para ‘relajar’ un poco la seguridad (que quede claro que esto no lo recomiendo en absoluto, y que es simplemente un ejercicio didáctico) podemos agregar atributos al fichero de configuración:

<membership defaultProvider="SqlProvider">
  <providers>
    <clear/>
    <add name="SqlProvider" 
         type="System.Web.Security.SqlMembershipProvider"
         connectionStringName="MemberShipConnectionString"
         applicationName="Test"
         enablePasswordRetrieval="false" 
         enablePasswordReset="true" 
         requiresQuestionAndAnswer="false" 
         requiresUniqueEmail="false" 
         passwordFormat="Hashed"/>
  </providers>
</membership>

Tenéis una lista completa de los atributos en las propiedades de la clase SqlMemberShipProvider.

Y ahora, un poco de ‘chicha’ en forma de código:

Ejemplos a cholón:

Crear un usuario:

MembershipUser user = Membership.CreateUser("admin", "$admin123");

Más sencillo imposible, verdad? Ahora bien, hay que tener presente que este código fallará con la configuración predeterminada, ya que debe suministrarse email, y la pregunta y respuesta de seguridad. En su lugar debería usarse este código:

MembershipCreateStatus status;
MembershipUser user = Membership.CreateUser(
    "admin", "$admin123", "admin@test.com",
    "pregunta de seguridad?", "respuesta de seguridad", 
    true, out status);
if (status == MembershipCreateStatus.Success)
{
    MessageBox.Show("Usuario creado correctamente!");
}

Bueno, tampoco no es demasiado complicado. La única diferencia es que se proporcionan más argumentos y que devuelve un objeto que define el estado de la creación del usuario, para saber si se ha creado con éxito.

Eliminar un usuario:

Membership.DeleteUser("admin");

Casi demasiado facil 😛

Obtener un usuario:

MembershipUser user = Membership.GetUser("admin");

A partir de este usuario recuperado podemos efectuar cualquier operación soportada.

Obtener todos los usuarios:

MembershipUserCollection users = Membership.GetAllUsers();
foreach (MembershipUser user in users)
{
    Console.WriteLine(user.UserName);
}

Obtenemos una colecció e iteramos por ella para mostrar los nombres.

Validar un usuario:

if (Membership.ValidateUser("admin", "$admin123"))
{
    MessageBox.Show("usuario correcto!");
}
else
{
    MessageBox.Show("usuario o contraseña incorrecto!");
}

Ideal para formularios de inicio de sesión. Tened cidado, que si se introduce mal 3 veces se bloquea el usuario.

Obtiene el número de usuarios conectados:

int num = Membership.GetNumberOfUsersOnline();

Sin comentarios.

Busca usuarios por el nombre de usuario o la dirección de correo electrónico:

MembershipUserCollection users = Membership.FindUsersByName("pepe");
MembershipUserCollection users = Membership.FindUsersByEmail("pepe@test.com");

Del mismo modo que GetAllUsers devuelve una colección de usuarios.

Obtiene la contraseña de un usuario:

MembershipUser user = Membership.GetUser("admin");
string pwd = user.GetPassword();
string pwd = user.GetPassword("respuesta de seguridad");

Tiene dos sobrecargas, en la segunda debe especificarse la respuesta de seguridad.

Sólo es válido si se ha especificado el atributo EnablePasswordRetrieval.

Cambia la contraseña de un usuario:

MembershipUser user = Membership.GetUser("admin");
user.ChangePassword("$admin123", "@nuevapassword2010");

Resetea la contraseña de un usuario:

MembershipUser user = Membership.GetUser("admin");
string pwd = user.ResetPassword();
string pwd = user.ResetPassword("respuesta de seguridad");

Tiene dos sobrecargas, en la segunda debe especificarse la respuesta de seguridad.

Sólo es válido si se ha especificado el atributo EnablePasswordReset.

Desbloquea un usuario:

MembershipUser user = Membership.GetUser("admin");
bool success = user.UnlockUser();

Particularmente útil cuando tenemos un usuario bloqueado, ya sea por un intento de intrusión, como por la típica amnesia matutina.

Y esto es todo por hoy, la semana que viene más 🙂

Espero que esto anime a más de uno a usar este sistema de gestión de usuarios, ya veis que no es nada complicado.

Saludos a 0º (hoy ni frío ni calor),

Nota: Es la primera vez que escribo en el blog todos los días de una semana, así que esto hay que celebrarlo con un cafelito. Hasta luego! 🙂


Artículos anteriores de la serie:

Usando ASP.NET membrership en Winforms (1 / n)

Usando ASP.NET membrership en Winforms (2 / n)

** crossposting desde el blog de Lluís Franco en geeks.ms **

One thought on “Usando ASP.NET membrership en Winforms (3 / n)

  1. Hola.Muchas Gracias por el post.La verdad que me esta siendo muy util.Por favor continua con una nueva version.Un saludo.

Leave a Reply

Your email address will not be published. Required fields are marked *