MSDN Library
Collapse the table of content
Expand the table of content

Cómo: Implementar IPrincipal

Publicado: 26 de junio de 2006

Consulte la Página de entrada como punto de partida y para obtener una descripción completa del documento Crear aplicaciones ASP.NET seguras.

Resumen: En este artículo se muestra cómo crear un objeto principal personalizado que proporciona funcionalidad extendida basada en funciones que se puede utilizar para la autorización de .NET.

En .NET Framework se proporcionan las clases WindowsPrincipal y GenericPrincipal, que ofrecen funcionalidad básica de comprobación de funciones para mecanismos de autenticación de Windows y distintos de Windows, respectivamente. En ambas clases se implementa la interfaz IPrincipal. Para que se puedan utilizar en la autorización, ASP.NET requiere que estos objetos se almacenen en HttpContext.User. Para las aplicaciones basadas en Windows, deben almacenarse en Thread.CurrentPrincipal.

La funcionalidad que ofrecen estas clases es suficiente para la mayoría de casos de las aplicaciones. Las aplicaciones pueden llamar explícitamente al método IPrincipal.IsInRole para realizar comprobaciones de funciones mediante programación. El método Demand de la clase PrincipalPermission, si se utiliza para exigir que un llamador pertenezca a una función determinada (ya sea de forma declarativa o imperativa), también da como resultado una llamada a IPrincipal.IsInRole.

En algunas circunstancias, puede que necesite desarrollar sus propias implementaciones principales mediante la creación de una clase que implemente la interfaz IPrincipal. Las clases que implementan IPrincipal se pueden utilizar para la autorización de .NET.

Algunas de las razones para implementar su propia clase IPrincipal son las siguientes:

Desea extender la funcionalidad de comprobación de funciones. Puede que necesite métodos que le permitan comprobar si un usuario determinado es miembro de varias funciones. Por ejemplo:

CustomPrincipal.IsInAllRoles( "Role1", "Role2", "Role3"    ) 
   CustomPrincipal.IsInAnyRole( "Role1", "Role2", "Role3"    )

Desea implementar un método o propiedad adicional que devuelva una lista de funciones en una matriz. Por ejemplo:

string[] roles = CustomPrincipal.Roles;

Desea que la aplicación exija la lógica de jerarquía de funciones. Por ejemplo, un miembro de la función Senior Manager (Director) se puede considerar que está en un nivel superior en la jerarquía que un Manager (Subdirector). Esto se puede probar con métodos como los siguientes.

CustomPrincipal.IsInHigherRole("Manager"); 
   CustomPrincipal.IsInLowerRole("Manager");

Desea implementar la inicialización lenta de las listas de funciones. Por ejemplo, puede cargar de forma dinámica la lista de funciones sólo cuando se solicite la comprobación de funciones.

En este artículo se describe cómo implementar una clase IPrincipal personalizada y utilizarla para la autorización basada en funciones en una aplicación de ASP.NET que utiliza autenticación mediante Formularios.

Requisitos

A continuación se describen las recomendaciones de hardware, software, infraestructura de red, conocimientos y Service Pack que se necesitan:
Sistema de desarrollo Microsoft® Visual Studio® .NET
Para llevar a cabo los procedimientos de este artículo, también es necesario que tenga conocimientos acerca del desarrollo Web en ASP.NET con la herramienta Microsoft Visual C#™.

En esta página

Crear una sencilla aplicación Web  Crear una sencilla aplicación Web
Configurar la aplicación Web para la autenticación mediante Formularios  Configurar la aplicación Web para la autenticación mediante Formularios
Generar un vale de autenticación para los usuarios autenticados Generar un vale de autenticación para los usuarios autenticados
Crear una clase que implemente y amplíe IPrincipal  Crear una clase que implemente y amplíe IPrincipal
Crear el objeto CustomPrincipal  Crear el objeto CustomPrincipal
Probar la aplicación Probar la aplicación
Recursos adicionales Recursos adicionales

Crear una sencilla aplicación Web

En este procedimiento se crea una nueva aplicación Web ASP.NET. La aplicación contendrá dos páginas: una página predeterminada a la que sólo pueden tener acceso los usuarios autenticados y una página de inicio de sesión que se utiliza para recopilar las credenciales de usuario.

Para crear una sencilla aplicación Web

  • Inicie Visual Studio .NET y cree una nueva aplicación Web ASP.NET en C# con el nombre CustomPrincipalApp.

  • Cambie el nombre de WebForm1.aspx por Logon.aspx.

  • Agregue a Logon.aspx los controles que se enumeran en la tabla 1 para crear un formulario de inicio de sesión.Tabla 1: Controles de Logon.aspx

    Tipo de control

    Texto

    Id.

    Etiqueta

    User Name:

    -

    Etiqueta

    Password:

    -

    Cuadro de texto

    -

    txtUserName

    Cuadro de texto

    -

    txtPassword

    Botón

    Logon

    btnLogon

  • Configure la propiedad TextMode del control de cuadro de texto de la contraseña en Password.

  • En el Explorador de soluciones, haga clic con el botón secundario del mouse (ratón) en CustomPrincipalApp, elija Agregar y, a continuación, haga clic en Agregar formulario Web.

  • Como nombre del nuevo formulario, escriba default.aspx y, después, haga clic en Abrir.

Configurar la aplicación Web para la autenticación mediante Formularios

Para modificar el archivo Web.config de la aplicación de forma que ésta admita la autenticación mediante Formularios

  1. Utilice el Explorador de soluciones para abrir Web.config.

  2. Busque el elemento <authentication> y cambie el atributo mode a Forms.

  3. Agregue el elemento <forms> siguiente como elemento secundario del elemento <authentication> y establezca los atributos loginUrl, name, timeout y path como se muestra a continuación:

    <authentication mode="Forms">
       <forms loginUrl="logon.aspx" name="AuthCookie" timeout="60"    path="/">
       </forms>
       </authentication>
    
  4. Agregue el siguiente elemento <authorization> debajo del elemento <authentication>. Esto permitirá que sólo los usuarios autenticados tengan acceso a la aplicación. El atributo loginUrl establecido anteriormente del elemento <authentication> redirigirá las solicitudes no autenticadas a la página Logon.aspx.

    <authorization> 
       <deny users="?" />
       <allow users="*" />
       </authorization>
    

Generar un vale de autenticación para los usuarios autenticados

En este procedimiento se escribe código para generar un vale de autenticación para los usuarios autenticados. El vale de autenticación es un tipo de cookie utilizado por FormsAuthenticationModule de ASP.NET.
El código de autenticación generalmente incluye la consulta del nombre de usuario y la contraseña suministrados en una base de datos personalizada o en el servicio de directorio Microsoft Active Directory®.

Para obtener información acerca de cómo realizar estas consultas, consulte los siguientes artículos en la sección Referencia de esta guía:

Para generar un vale de autenticación para los usuarios autenticados

  1. Abra el archivo Logon.aspx.cs y agregue la siguiente instrucción using al principio del archivo debajo de las instrucciones using existentes.

    using System.Web.Security;
    
  2. Agregue a la clase WebForm1 el siguiente método auxiliar privado llamado IsAuthenticated, que se utiliza para validar nombres de usuario y contraseñas en la autenticación de usuarios. En este código se supone que todas las combinaciones de nombre de usuario y contraseña son válidas.

    private bool IsAuthenticated( string username, string password )
       {
       // Lookup code omitted for clarity
       // This code would typically validate the user name and password
       // combination against a SQL database or Active Directory
       // Simulate an authenticated user
       return true;
       }
    
  3. Agregue el siguiente método auxiliar privado llamado GetRoles, que se utiliza para obtener el conjunto de funciones a las que pertenece el usuario.

    private string GetRoles( string username, string password )
       {
       // Lookup code omitted for clarity
       // This code would typically look up the role list from a database table.
       // If the user was being authenticated against Active Directory, the
       // Security groups and/or distribution lists that the user belongs to may be    
       // used instead
    
    // This GetRoles method returns a pipe delimited string containing roles
       // rather than returning an array, because the string format is convenient 
       // for storing in the authentication ticket / cookie, as user data
       return "Senior Manager|Manager|Employee";
       }
    
  4. Muestre el formulario Logon.aspx en el modo del diseñador y haga doble clic en el botón Logon para asociarle un controlador de eventos de clic.

  5. Agregue una llamada al método IsAuthenticated en la que se suministre el nombre de usuario y la contraseña capturados a través del formulario de inicio de sesión. Asigne el valor devuelto a una variable de tipo bool, que indique si el usuario se ha autenticado o no.

    bool isAuthenticated = IsAuthenticated( txtUserName.Text, 
       txtPassword.Text );
    
  6. Si el usuario se autentica, agregue una llamada al método GetRoles para obtener la lista de funciones del usuario.

    if (isAuthenticated == true )
       {
       string roles = GetRoles( txtUserName.Text, txtPassword.Text );
    
  7. Cree un nuevo vale de autenticación mediante Formularios que contenga el nombre de usuario, una fecha de caducidad y la lista de funciones a las que pertenece el usuario. Observe que la propiedad de datos de usuario del vale de autenticación se utiliza para almacenar la lista de funciones del usuario. Observe también que con el siguiente código se crea un vale no persistente, aunque el hecho de que el vale o la cookie sean persistentes o no depende del caso de la aplicación.

    // Create the authentication ticket
       FormsAuthenticationTicket authTicket = new 
       FormsAuthenticationTicket(1, // version
       txtUserName.Text, // user name
       DateTime.Now, // creation
       DateTime.Now.AddMinutes(60),// Expiration
       false, // Persistent
       roles ); // User data
    
  8. Agregue código para crear una representación de cadena cifrada del vale y almacenarla como datos en un objeto HttpCookie.

    // Now encrypt the ticket.
       string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
       // Create a cookie and add the encrypted ticket to the 
       // cookie as data.
       HttpCookie authCookie = 
       new HttpCookie(FormsAuthentication.FormsCookieName,
       encryptedTicket);
    
  9. Agregue la cookie a la colección de cookies que se devuelven al explorador del usuario.

    // Add the cookie to the outgoing cookies collection. 
       Response.Cookies.Add(authCookie);
    
  10. Redirija al usuario a la página solicitada originalmente

    // Redirect the user to the originally requested page
       Response.Redirect( FormsAuthentication.GetRedirectUrl(
       txtUserName.Text, 
       false ));
       }
    

Crear una clase que implemente y amplíe IPrincipal

En este procedimiento se crea una clase que implementa la interfaz IPrincipal. También se agregan métodos y propiedades adicionales a la clase para ampliar la funcionalidad de autorización basada en funciones.

Para crear una clase que implemente y amplíe IPrincipal

  1. Agregue una nueva clase llamada CustomPrincipal al proyecto actual.

  2. Agregue la siguiente instrucción using al principio del archivo CustomPrincipal.cs.

    using System.Security.Principal;
    
  3. Derive la clase CustomPrincipal de la interfaz IPrincipal.

    public class CustomPrincipal : IPrincipal
    
  4. Agregue a la clase las siguientes variables miembro privadas para mantener el objeto IIdentity asociado al principal actual y la lista de funciones del principal.

    private IIdentity _identity;
       private string [] _roles;
    
  5. Modifique el constructor predeterminado de la clase para aceptar un objeto IIdentity y una matriz de funciones. Utilice los valores suministrados para inicializar las variables miembro privadas como se indica a continuación.

    public CustomPrincipal(IIdentity identity, string [] roles)
       {
       _identity = identity;
       _roles = new string[roles.Length];
       roles.CopyTo(_roles, 0);
       Array.Sort(_roles);
       }
    
  6. Implemente el método IsInRole y la propiedad Identity definidos por la interfaz IPrincipal como se muestra a continuación.

    // IPrincipal Implementation
       public bool IsInRole(string role)
       {
       return Array.BinarySearch( _roles, role ) > 0 ? true : false;
       }
       public IIdentity Identity
       {
       get
       {
       return _identity;
       }
       }
    
  7. Agregue los dos métodos públicos siguientes que amplían la funcionalidad de comprobación basada en funciones.

    // Checks whether a principal is in all of the specified set of roles
       public bool IsInAllRoles( params string [] roles )
       {
       foreach (string searchrole in roles )
       {
       if (Array.BinarySearch(_roles, searchrole) < 0 )
       return false;
       }
       return true;
       }
       // Checks whether a principal is in any of the specified set of roles
       public bool IsInAnyRoles( params string [] roles )
       {
       foreach (string searchrole in roles )
       {
       if (Array.BinarySearch(_roles, searchrole ) > 0 )
       return true;
       }
       return false;
       }
    

Crear el objeto CustomPrincipal

En este procedimiento se implementa un controlador de eventos de autenticación de aplicación y se construye un objeto CustomPrincipal para representar al usuario autenticado en función de la información contenida en el vale de autenticación.

Para crear el objeto CustomPrincipal

  1. En el Explorador de soluciones, abra global.asax.

  2. Cambie a la vista de código y agregue las siguientes instrucciones using al principio del archivo.

    using System.Web.Security;
       using System.Security.Principal;
    
  3. Busque el controlador de eventos Application_AuthenticateRequest y agregue el siguiente código para obtener la cookie de autenticación mediante Formularios de la colección de cookies que se pasó con la solicitud.

    // Extract the forms authentication cookie
       string cookieName = FormsAuthentication.FormsCookieName;
       HttpCookie authCookie = Context.Request.Cookies[cookieName];
    
    if(null == authCookie)
       {
       // There is no authentication cookie.
       return;
       }
    
  4. Agregue el siguiente código para extraer el vale de autenticación de la cookie de autenticación mediante Formularios y descifrarlo.

    FormsAuthenticationTicket authTicket = null;
       try
       {
       authTicket = FormsAuthentication.Decrypt(authCookie.Value);
       }
       catch(Exception ex)
       {
       // Log exception details (omitted for simplicity)
       return;
       }
    
    if (null == authTicket)
       {
       // Cookie failed to decrypt.
       return;
       }
    
  5. Agregue el siguiente código para analizar la lista de nombres de funciones separados por el símbolo | que se adjuntó al vale cuando se autenticó al usuario originalmente.

    // When the ticket was created, the UserData property was assigned a
       // pipe delimited string of role names.
       string[] roles = authTicket.UserData.Split('|');
    
  6. Agregue el siguiente código para crear un objeto FormsIdentity con el nombre de usuario obtenido en el nombre del vale y un objeto CustomPrincipal que contiene esa identidad junto con la lista de funciones del usuario.

    // Create an Identity object
       FormsIdentity id = new FormsIdentity( authTicket );
    
    // This principal will flow throughout the request.
       CustomPrincipal principal = new CustomPrincipal(id, roles);
       // Attach the new principal object to the current HttpContext object
       Context.User = principal;
    

Probar la aplicación

En este procedimiento se agrega código a la página default.aspx para mostrar información del objeto CustomPrincipal adjunto al objeto HttpContext actual, para confirmar que se ha construido el objeto correctamente y que se ha asignado a la solicitud Web actual. También se prueba la funcionalidad basada en funciones que admite la nueva clase.

Para probar la aplicación

  1. En el Explorador de soluciones, haga doble clic en default.aspx.

  2. Haga doble clic en el formulario Web default.aspx para mostrar el controlador de eventos de carga de la página.

  3. Desplácese hasta el principio del archivo y agregue la siguiente instrucción using debajo de las instrucciones using existentes.

    using System.Security.Principal;
    
  4. Vuelva al controlador de eventos de carga de la página y agregue el siguiente código para mostrar el nombre de identidad adjunto al objeto CustomPrincipal asociado con la solicitud Web actual.

    CustomPrincipal cp = HttpContext.Current.User as CustomPrincipal;
       Response.Write( "Authenticated Identity is: " + 
       cp.Identity.Name );
       Response.Write( "<p>" );
    
  5. Agregue el siguiente código para probar la pertenencia a funciones de la identidad autenticada actual, con el método IsInRole estándar y los métodos IsInAnyRoles y IsInAllRoles adicionales admitidos por la clase CustomPrincipal.

    if ( cp.IsInRole("Senior Manager") )
       {
       Response.Write( cp.Identity.Name + " is in the " + "Senior Manager    Role" );
       Response.Write( "<p>" );
       }
    
    if ( cp.IsInAnyRoles("Senior Manager", "Manager", "Employee",    "Sales") )
       {
       Response.Write( cp.Identity.Name + " is in one of the specified roles");
       Response.Write( "<p>" );
       }
       if ( cp.IsInAllRoles("Senior Manager", "Manager", "Employee",    "Sales") )
       {
       Response.Write( cp.Identity.Name + " is in ALL of the specified roles"    );
       Response.Write( "<p>" );
       }
       else
       {
       Response.Write( cp.Identity.Name + 
       " is not in ALL of the specified roles" );
       Response.Write( "<p>" );
       }
    
    if ( cp.IsInRole("Sales") )
       Response.Write( "User is in Sales role<p>" );
       else
       Response.Write( "User is not in Sales role<p>" );
    
  6. En el Explorador de soluciones, haga clic con el botón secundario en default.aspx y, a continuación, haga clic en Establecer como página de inicio.

  7. En el menú Generar, haga clic en Generar solución.

  8. Presione CTRL+F5 para ejecutar la aplicación. Puesto que default.aspx está configurado como la página de inicio, ésta es la página que se solicita inicialmente.

  9. Cuando se haya realizado la redirección a la página de inicio de sesión (porque inicialmente no tiene un vale de autenticación), escriba un nombre de usuario en User Name y una contraseña (cualquiera) en Password y, después, haga clic en Logon (Iniciar sesión).

  10. Confirme que se lleva a cabo la redirección a la página default.aspx y que se muestran la identidad de usuario y los detalles de función correctos. El usuario es miembro de las funciones Senior Manager, Manager y Employee, pero no de la función Sales.

Recursos adicionales

Para obtener más información acerca de la autenticación basada en formularios, consulte los siguientes artículos en la sección Referencia de esta guía:

Mostrar:
© 2016 Microsoft