Marc Rubiño

ASP.NET, C#, AJAX.NET, JavaScript, etc.

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="Usuarios" type="Demo.Seguridad.Usuarios" connectionStringName="MyProviderConnectionString" minRequiredNonalphanumericCharacters="0" requiresQuestionAndAnswer="false" enablePasswordReset="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

 

Posted: 27/1/2008 22:49 por Marc Rubiño | con 27 comment(s)
Comparte este post:

Comentarios

Miguel ha opinado:

Hola, no se puede bajar el archivo puedes enviarlo a malabanto@hotmail.com

Gracias

# January 29, 2008 6:00 PM

Marc Rubiño ha opinado:

Hola Miguel,

Prueba en geeks.ms/.../entry67524.aspx

Saludos ;-)

# January 29, 2008 10:34 PM

Jorge Ernesto ha opinado:

hola:

No pudieras hacer un video explicativo con una base de datos sql server 2005.

por que necesito hacer un sistema que implemente usuarios, roles entre otras cosas.

muchas gracias.

mi correo es:

el_doctor55@hotmail.com

# May 20, 2008 9:12 PM

javier ha opinado:

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

# June 3, 2008 6:03 PM

Marc Rubiño ha opinado:

Me alegro muchísimo Javier, ;-)

Nos vemos.

# June 3, 2008 6:40 PM

René Bonilla ha opinado:

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.

# July 31, 2008 7:03 AM

javi ha opinado:

holasss

tengo usuarios separados en varias tablas, como lo podria hacer para los roles???

ejem

tabla

  clientes

      usuario

      pass

  franquicia

      usuario

      pass

# December 15, 2008 10:21 AM

girion ha opinado:

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

# December 15, 2008 12:26 PM

Marc Rubiño ha opinado:

Supongo que tendrías que hacer un tabla intermedia que una tus usuarios con los usuarios de ASP.NET.

Saludos.

# December 17, 2008 10:53 PM

Marcos ha opinado:

Che,

Y qué hago con el Profile?

Lo dejo como está?

# August 20, 2009 10:57 PM

juan ha opinado:

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

# October 9, 2009 7:03 AM

Marc Rubiño ha opinado:

Esto es el namespace que utilices en tu proyecto y el nombre de la clase, es para que el proveedor encuentre tu clase y la utilice.

# October 9, 2009 9:09 AM

Juan ha opinado:

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!!!!

# October 9, 2009 6:32 PM

Cristian ha opinado:

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

# October 13, 2009 1:34 AM

guacharaca ha opinado:

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

# February 26, 2010 11:53 PM

Rodolfo ha opinado:

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..

# May 27, 2010 11:07 AM

Rodolfo ha opinado:

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

# May 27, 2010 12:14 PM

Marc Rubiño ha opinado:

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 ;-)

# May 27, 2010 12:32 PM

Abraham ha opinado:

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 :D

# October 5, 2010 6:00 PM

jhoel ha opinado:

Hola bueno tu ejenplo es de bien todo péro lo podrias poner para descargarlo uno es que lo nesecito para estudiarlo por fa vuelvelo a subir o si me lo puede enviar a mi correo estilofatalico123456@hotmail.com

muchas gracias

# January 24, 2011 4:29 PM

Juan Manuel Lopez ha opinado:

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.

# June 20, 2011 6:00 PM

Laura ha opinado:

Hola Marc, podrías volver a subir el ejemplo? El enlace actual está roto :(

Gracias!

# July 29, 2011 4:53 AM

Laura ha opinado:

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!

# July 30, 2011 5:10 PM

Fernando Ruiz ha opinado:

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.

# March 4, 2012 10:18 PM

Marc Rubiño ha opinado:

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

# March 6, 2012 11:06 AM

Fernando Ruiz ha opinado:

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

# March 7, 2012 9:54 AM

Marc Rubiño ha opinado:

Pues yo creo que solo pueden ser dos cosas, que no se ha creado correctamente los storeds, vistas y tablas que necesita ASP.NET o que el usuario que utilizas no tiene permisos para ejecutarlos.

Aseguraté que el usuario tiene permisos blog.dampee.be/.../EXECUTE-permission-denied-on-object-aspnet_CheckSchemaVersion-database-myDB-schema-dbo.aspx

Saludos.

# March 7, 2012 10:33 AM