Custom MembershipProvider Y RoleProvider

El modelo de Proveedores desde su aparición con ASP.NET 2.0 ha sido un tema muy recurrente y se han escrito ríos de tinta sobre sus beneficios, pero ya sea porque realmente nos encontraremos en muchas ocasiones que los proveedores por defecto no cubren todas nuestras necesidades o porque hemos migrado una aplicación donde ya tenemos todos los datos o simplemente porque no tengo tanta imaginación, en este artículo mostraré como poder crear nuestro propio proveedor.

ASP.NET 2.0 ofrece soporte para el modelo de proveedores para diferentes servicios:

  • Membership
    • System.Web.Security.SqlMembershipProvider
    • System.Web.Security.ActiveDirectoryMembershipProvider
  • Roles
    • System.Web.Security.SqlRoleProvider
    • System.Web.Security.AuthorizationStoreRoleProvider
    • System.Web.Security.WindowsTokenRoleProvider
  • Profile
    • System.Web.Profile.SqlProfileProvider
  • SessionState
    • System.Web.SessionState.InProcSessionStateStore
    • System.Web.SessionState.OutOfProcSessionStateStore
    • System.Web.SessionState.SqlSessionStateStore
  • Configuration
    • System.Configuration.DPAPIProtectedConfigurationProvider
    • System.Configuartion.RSAProtectedConfigurationProvider
  • SiteMap
    • System.Web.XmlSiteMapProvider
  • WebEvents
    • System.Web.Management.EventLogWebEventProvider
    • System.Web.Management.SimpleMailWebEventProvider
    • System.Web.Management.SqlWebEventProvider
    • System.Web.Management.TemplatedMailWebEventProvider
    • System.Web.Management.WmiWebEventProvider
    • System.Web.Management.TraceWebEventProvider
  • WebParts
    • System.Web.UI.WebControls.WebParts.SqlPersonalizationProvider

La intención de este artículo no es profundizar en el modelo de proveedores sino aprovechar toda su potencia, imaginemos que tenemos una aplicación web que hemos migrado o que simplemente tiene que aprovechar los datos de otra aplicación, entonces crearemos nuestro proveedor basándonos en las clases MembershipProvider y RolProvider para que se adapte a nuestras necesidades.

Empezaremos con la base de datos en Access que hemos aprovechado de otra aplicación 😉

Como podéis observar simplemente tenemos una tabla de usuarios una de roles y una tabla intermedia de UsuariosPorRol.

Crearemos nuestro primer proveedor con la clase Usuarios que herede de MembershipProvider, que al ser una clase abstracta nos facilitara la manera de implementar un proveedor de este subsistema Membership.

No es necesario sobreescribir todos los métodos de esta clase, solo los que tengamos que utilizar posteriormente.

Por  ejemplo el método ValidateUser:

public override bool ValidateUser(

string username, string password){    bool userExists = false;    OleDbCommand command = new OleDbCommand();   try    {      command.Connection = connection;      command.CommandText = “SELECT IDUsuario FROM Usuarios Where Nombre=@Nombre AND Pass=@Pass”;      command.Parameters.AddWithValue(“@Nombre”, username);      command.Parameters.AddWithValue(“@Pass”, password);      command.Connection.Open();       OleDbDataReader rd = command.ExecuteReader();      if (rd.HasRows)         userExists = true;     }    Catch…

 

O CreateUser:

public override MembershipUser CreateUser(

string username, string password, string email,

string passwordQuestion, string passwordAnswer, bool isApproved,

object providerUserKey, out MembershipCreateStatus status){   MembershipUser newUser = null;   OleDbCommand command = new OleDbCommand();    try   {     command.Connection = connection;     command.CommandText = @”INSERT INTO Usuarios ( Nombre, Mail, Pass)                    VALUES (@Nombre, @Mail, @Pass )”;     command.Parameters.AddWithValue(“@Nombre”, username);     command.Parameters.AddWithValue(“@Mail”, email);     command.Parameters.AddWithValue(“@Pass”, password);     command.Connection.Open();     command.ExecuteNonQuery();      newUser = new MembershipUser(“Usuarios”, username, null, String.Empty, String.Empty,String.Empty, true, false, DateTime.Now,DateTime.Now, DateTime.Now, DateTime.Now,DateTime.Now);       status = MembershipCreateStatus.Success;  }  Catch…

La clase Roles que hereda de RoleProvider e implementaremos métodos como:

public override string[] GetAllRoles(){    OleDbCommand command = new OleDbCommand();    List<string> resultado = new List<string>();    try    {      command.Connection = connection;      command.CommandText = “SELECT Rol FROM Roles”;      command.Connection.Open();      OleDbDataReader rd = command.ExecuteReader();      while (rd.Read())         resultado.Add(rd.GetString(0));      return resultado.ToArray();    }    Catch…

Una vez que tenemos nuestros proveedores creados ya los podemos utilizar y para eso los  tenemos que definir en el web.config de nuestra aplicación.

<membership defaultProvider=Usuarios>  <providers>   <clear/><add name=Usuariostype=Demo.Seguridad.UsuariosconnectionStringName=MyProviderConnectionStringminRequiredNonalphanumericCharacters=0requiresQuestionAndAnswer=falseenablePasswordReset=true/>  </providers>

</membership>

Definimos nuestro proveedor como proveedor por defecto y sus propiedades.

<roleManager enabled=true defaultProvider=Roles> <providers>  <clear/>  <add name=Roles connectionStringName=MyProviderConnectionString type=Demo.Seguridad.Roles/> </providers></roleManager>

Para probar nuestros proveedores crearemos una página de login con un control asp:Login, una página de registro para crear nuevos usuarios con un control asp:CreateUserWizard.

Y el proyecto funcionando se mostraría como

 

Para que podáis estudiar mejor el proyecto os lo podéis bajar desde: geeks.ms/…/entry67524.aspx

CrossPosting de http://mrubino.net

 

28 comentarios en “Custom MembershipProvider Y RoleProvider”

  1. Muchas gracias por el minitutorial, con unos pequenios cambios nos ha servido para hacer el login de nuestra aplicacion con SQLServer y storedprocedure!!

  2. Excelente esto lo necesitaba con urgencia me resuelve mi problema ya que necesito implementar roles que ya tengo definido en mi base de datos.

    Gracias.

  3. hola, tengo dos tablas de usuarios diferentes….

    como puedo hacer para los roles y usuarios?!

    tabla
    clientes
    id_cliente
    nombre
    pass
    agentes
    id_agente
    nombre
    pass

    no se como hacer para juntaros para el tema de roles

    gracias de antemano

  4. No entiendo eso de type=”Demo.Seguridad.Usuarios” e marca error de que no puede cargarlo no entiendo eso del namespace que tengo que hacer

  5. Ok para no complicar utilice ese namespace al principio de la clase para que quedara igual pero me marca error!!!

    Dice error al cargar el type=Demo.Seguridad.Usuarios

    Que estoy haciendo mal, la clase donde se agrega en el app_code??? GRACIAS por Responder!!!!

  6. Hola amigo quisiera saber si me podes dar una ayuda, tengo una pagina web creada y tengo usuarios y administradores, los usuarios pueden ver determinadas paginas, el problema es que no se como hacer que cuando agregue una pagina con una tabla puedan modificar el contenido de la tabla solo los administradores y que los usuarios registrados solamente puedan ver esa tabla y los anonimos que no la puedan ver directamente, desde ya si tenes algun ejemplo te lo agradeceria mucho, yo tengo echo todo mi sitio con Visual Web Developer.

    mi correo si me podes ayudar es c_cydejko@hotmail.com

  7. Hola, el aporte me parece muy bueno, sin embargo tengo algunas dudas, por ejemplo, en mi caso estoy intentando implementar un custom membership y el almacén de usuarios tiene campos diferentes que los que tiene el paquete de membresia, entonces no se bien como hacer para cambiar los campos que tiene. Estuve mirando tu ejemplo y esta muy bien explicado, solo que la parte que trata la creación del Usuario, guarda el usuario que trae el membership por defecto (así lo entendí yo), es decir no agrega ni quita ningún campo. Y como hacer que el repositorio a su vez refleje estos cambios

  8. Hola, muy bueno tu aporte man, he empezado a entender un poco pero lo q pasa es q soy nuevo en el asp y quisiera si no es mucha molestia me mandes a mi correo (rodlesc@hotmail.com) unos ejemplos de MembershipProvider Y RoleProvider interactuando con una bd en sql y si tienes un video tutorial seria magnifico; quiero aprender esto para luego aplicarlo en mis proyectos, aparte trabajo con capas (entidad, negocio, data y presentacion) como podria haecrlo?..
    Gracias de antemano, de verdad necesito ayuda y se nota que tu sabes bastante de esto, otra vez gracias..

  9. Queria hacerte una consulta: MembershipProvider Y RoleProvider solo se usa con una bd creada en el mismo proyecto? o tambien se puede usar con una bd aparte en sql2005. Yo tengo mi bd en sql con la tabla usuario y quisiera q se conecte a esa usando MembershipProvider Y RoleProvider, si tendrias un tutorial de como hacerlo te agradeceria bastante, gracias de antemano y si puedes me lo mandas a rodlesc@hotmail.com
    Gracias por compartir tu conocimiento

  10. Puedes utilizar cualquier origen de datos y si es una base de datos cualquier proveedor.

    Solo tienes que configurar tu cadena de conexión y lo tendrás funcionando.

    Yo hice el ejemplo con Access para variar un poco de lo habitual.

    Si tengo un poco de tiempo haré un vídeo explicativo 😉

  11. Marc, tu post es lo que necesitaba, la claridad es excelente. Se que en la Web hay informacion muy buena pero presuponen que ya conoces la tecnologia y algunos apenas vamos comenzando. Deseo agregar autenticacion a mi aplicacion pero queria apalancar lo que nos brinda el Membership de MS, tu informacion me permitio lograrlo, muchas gracias 😀

  12. Hola como estas, quiciera poder implementar esto de los roles, y menbership, pero con mis propias tablas, tengo una de Usuarios, y otra de Grupos, como puedo hacer para hacer estas tablas las predeterminadas para el registro y manejo de roles? espero tu respuesta muchas gracias.

  13. Ops!ahí vi el enlace que le sugeriste a Miguel 🙂

    Te consulto otra cosita, estoy tratando de integrar membresía a una aplicación que se encuentra dividida en capas, por las dudas conoces algún ejemplo de eso al que puedas?

    Gracias!

  14. Hola Marc, soy nuevo en esto, y me gustaría hacerte una pregunta, te pido por anticipado que tengas paciencia, please.

    Estoy haciendo un aplicación web basada en la seguridad de ASP.Net utilizando los controles que .Net ofrece.

    Cree las tablas de seguridad utilizando aspnet_regsql y desde mi ordenador no tengo ningún problema, puedo crear usuarios, eliminarlos… Pero cuando subo la aplicación a un servidor que tengo contratado no me permite validar ni crear ningún usuario. Aparece el problema siguiente:

    No se encontró el procedimiento almacenado ‘dbo.aspnet_CheckSchemaVersion’.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.Data.SqlClient.SqlException: No se encontró el procedimiento almacenado ‘dbo.aspnet_CheckSchemaVersion’.

    No se si el servidor funciona bajo IIS, puede ser ese el problema? En mi máquina funciona a la perfección.

    De ser así, como debería gestionar el control de usuarios en mi aplicación?

    Muchas gracias.

  15. Hola Fernando, puedo entender que al subir la BD al servidor no has ejecutado la instalación de los storeds y tablas del Menbership.

    Asegurate que igual que lo instalaste en tu máquina local lo tengas instalado en el servidor web.

    Saludos

  16. Hola Marc,

    para subir la BD utilizo la herramienta que ofrece SQLExpress, no me da ningún error de que no haya podido subir alguna tabla o algún Procedimiento, pero ciertamente, el mensaje que lanza es que no encuentra el procedimiento dbo.aspnet_CheckSchemaVersion.

    Gracias

  17. Hola Marc, un saludo, excelente ejemplo, fijate que lo hice con SQL con mis propias tablas, pero en ocaciones me aparece la excepción de “Error al consultar los roles por usuario. “, y la sesión dura muy poco tiempo, a que se deberá este error, saludos, y gracias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *