Autorización basada en roles (VB)

por Scott Mitchell

Nota:

Desde que se escribió este artículo, los proveedores de pertenencia de ASP.NET han sido reemplazados por ASP.NET Identity. Se recomienda encarecidamente actualizar las aplicaciones para usar la plataforma ASP.NET Identity en lugar de los proveedores de pertenencia destacados en el momento en el que se escribió este artículo. ASP.NET Identity ofrece una serie de ventajas frente al sistema de pertenencia de ASP.NET, incluidas las siguientes:

  • Mejor rendimiento
  • Extensibilidad y capacidad de prueba mejoradas
  • Compatibilidad con OAuth, OpenID Connect y autenticación en dos fases
  • Admite identidades basadas en notificaciones
  • Mejor interoperabilidad con ASP.Net Core

Descargar código o descargar PDF

Este tutorial comienza con un vistazo a cómo el marco roles asocia los roles de un usuario con su contexto de seguridad. A continuación, examina cómo aplicar reglas de autorización de direcciones URL basadas en roles. Después, veremos el uso de medios declarativos y mediante programación para modificar los datos mostrados y la funcionalidad que ofrece una página de ASP.NET.

Introducción

En el Tutorial autorización basada en usuarios hemos visto cómo usar la autorización de dirección URL para especificar qué usuarios podrían visitar un conjunto determinado de páginas. Con un poco de marcado en Web.config, podríamos indicar a ASP.NET permitir que solo los usuarios autenticados visiten una página. O podríamos dictar que solo se permitían los usuarios Tito y Bob, o indicar que todos los usuarios autenticados excepto Sam estaban permitidos.

Además de la autorización de direcciones URL, también hemos examinado técnicas declarativas y programáticas para controlar los datos mostrados y la funcionalidad que ofrece una página basada en la visita del usuario. En concreto, hemos creado una página que enumera el contenido del directorio actual. Cualquiera podría visitar esta página, pero solo los usuarios autenticados podían ver el contenido de los archivos y solo Tito podía eliminar los archivos.

La aplicación de reglas de autorización por usuario puede crecer en una pesadilla de contabilidad. Un enfoque más fácil de mantener es usar la autorización basada en roles. La buena noticia es que las herramientas a nuestra disposición para aplicar reglas de autorización funcionan igualmente bien con roles como lo hacen para las cuentas de usuario. Las reglas de autorización de direcciones URL pueden especificar roles en lugar de usuarios. El control LoginView, que representa una salida diferente para los usuarios autenticados y anónimos, se puede configurar para mostrar contenido diferente en función de los roles del usuario que ha iniciado sesión. Y la API de roles incluye métodos para determinar los roles del usuario que ha iniciado sesión.

Este tutorial comienza con un vistazo a cómo el marco roles asocia los roles de un usuario con su contexto de seguridad. A continuación, examina cómo aplicar reglas de autorización de direcciones URL basadas en roles. Después, veremos el uso de medios declarativos y mediante programación para modificar los datos mostrados y la funcionalidad que ofrece una página de ASP.NET. Comencemos.

Descripción de cómo están asociados los roles con el contexto de seguridad de un usuario

Cada vez que una solicitud entra en la canalización de ASP.NET está asociada a un contexto de seguridad, lo que incluye información que identifica al solicitante. Al usar la autenticación de formularios, se usa un vale de autenticación como token de identidad. Como se explicó en el tutorial Introducción a la autenticación de formularios, FormsAuthenticationModule es responsable de determinar la identidad del solicitante, que hace durante el AuthenticateRequest evento.

Si se encuentra un vale de autenticación no expirado válido, el FormsAuthenticationModule descodifica para determinar la identidad del solicitante. Crea un nuevo objeto GenericPrincipal y lo asigna al objeto HttpContext.User. El propósito de una entidad de seguridad, como GenericPrincipal, es identificar el nombre del usuario autenticado y los roles a los que pertenece. Este propósito es evidente por el hecho de que todos los objetos de entidad de seguridad tienen una propiedad Identity y un método IsInRole(roleName). FormsAuthenticationModuleSin embargo, el objeto que crea no está interesado en registrar la información del rol y el objeto GenericPrincipal que crea no especifica ningún rol.

Si el marco roles está habilitado, el módulo HTTP realiza los RoleManagerModule pasos después de FormsAuthenticationModule e identifica los roles del usuario autenticado durante el PostAuthenticateRequest evento, que se desencadena después del evento AuthenticateRequest. Si la solicitud procede de un usuario autenticado, RoleManagerModule sobrescribe el objeto creado GenericPrincipal por y lo reemplaza por FormsAuthenticationModule un RolePrincipal objeto. La RolePrincipal clase usa la API roles para determinar a qué roles pertenece el usuario.

En la figura 1 se muestra el flujo de trabajo de canalización de ASP.NET al usar la autenticación de formularios y el marco roles. El FormsAuthenticationModule se ejecuta primero, identifica al usuario a través de su vale de autenticación y crea un nuevo objeto GenericPrincipal. A continuación, el paso RoleManagerModule y sobrescribe el objeto GenericPrincipal con un objeto RolePrincipal.

Si un usuario anónimo visita el sitio, ni el FormsAuthenticationModule ni el RoleManagerModule crea un objeto principal.

The ASP.NET Pipeline Events for an Authenticated User When Using Forms Authentication and the Roles Framework

Figura 1: Los eventos de canalización de ASP.NET para un usuario autenticado al usar la autenticación de formularios y el marco de roles (haga clic para ver la imagen de tamaño completo)

El método RolePrincipal del objeto IsInRole(roleName) llama a Roles.GetRolesForUser para obtener los roles del usuario con el fin de determinar si el usuario es miembro de roleName. Cuando se usa SqlRoleProvider, se produce una consulta en la base de datos del almacén de roles. Al usar reglas de autorización de direcciones URL basadas en rol, se llamará a los métodos RolePrincipal y IsInRole de cada solicitud a una página protegida por las reglas de autorización de direcciones URL basadas en roles. En lugar de tener que buscar la información de rol en la base de datos en cada solicitud, el marco Roles incluye una opción para almacenar en caché los roles del usuario en una cookie.

Si el marco roles está configurado para almacenar en caché los roles del usuario en una cookie, RoleManagerModule crea la cookie durante el EndRequestevento de la canalización de ASP.NET. Esta cookie se usa en las solicitudes posteriores de PostAuthenticateRequest, que es cuando se crea el objeto RolePrincipal. Si la cookie es válida y no ha expirado, los datos de la cookie se analizan y se usan para rellenar los roles del usuario, lo que evita RolePrincipal tener que realizar una llamada a la clase Roles para determinar los roles del usuario. En la figura 2 se muestra este flujo de trabajo.

The User's Role Information Can Be Stored in a Cookie to Improve Performance

Figura 2: La información de rol del usuario se puede almacenar en una cookie para mejorar el rendimiento (Haga clic para ver la imagen de tamaño completo)

De manera predeterminada, el mecanismo de cookies de caché de roles está deshabilitado. Se puede habilitar mediante el marcado de configuración <roleManager> en Web.config. Hemos analizado el uso del <roleManager> elemento para especificar proveedores de roles en el tutorial Creación y administración de roles, por lo que ya debería tener este elemento en el archivo Web.config de la aplicación. La configuración de cookies de caché de roles se especifica como atributos del elemento <roleManager>, y son resumidas en la tabla 1.

Nota:

Las opciones de configuración enumeradas en la tabla 1 especifican las propiedades de la cookie de caché de roles resultante. Para obtener más información sobre las cookies, cómo funcionan y sus diversas propiedades, lea este tutorial sobre cookies.

Propiedad Descripción
cacheRolesInCookie Valor booleano que indica si se usa el almacenamiento en caché de cookies. Tiene como valor predeterminado false.
cookieName Nombre de la cookie de caché de roles. El valor predeterminado es ". ASPXROLES".
cookiePath Ruta de acceso de la cookie de nombre de roles. El atributo ruta permite a un desarrollador limitar el ámbito de una cookie a una jerarquía de directorios determinada. El valor predeterminado es "/", que informa al explorador para enviar la cookie de vale de autenticación a cualquier solicitud realizada al dominio.
cookieProtection Indica qué técnicas se usan para proteger la cookie de caché de roles. Los valores permitidos son: All (valor predeterminado); Encryption; None; y Validation.md)

| cookieRequireSSL | Valor booleano que indica si se requiere una conexión SSL para transmitir la cookie de autenticación. El valor predeterminado es false. | | cookieSlidingExpiration | A Boolean value that indicates whether the cookie's timeout is reset each time the user visits the site during a single session. The default value isfalse. This value is only pertinent when createPersistentCookieis set totrue. | | cookieTimeout | Specifies the time, in minutes, after which the authentication ticket cookie expires. The default value is30. This value is only pertinent when createPersistentCookieis set totrue. | | createPersistentCookie | A Boolean value that specifies whether the role cache cookie is a session cookie or persistent cookie. Iffalse(the default), a session cookie is used, which is deleted when the browser is closed. Iftrue, a persistent cookie is used; it expires cookieTimeoutnumber of minutes after it has been created or after the previous visit, depending on the value ofcookieSlidingExpiration. | | domain| Specifies the cookie's domain value. The default value is an empty string, which causes the browser to use the domain from which it was issued (such as www.yourdomain.com). In this case, the cookie will <strong>not</strong> be sent when making requests to subdomains, such as admin.yourdomain.com. If you want the cookie to be passed to all subdomains you need to customize thedomainattribute, setting it to "yourdomain.com". | | maxCachedResults | Specifies the maximum number of role names that are cached in the cookie. The default is 25. TheRoleManagerModuledoes not create a cookie for users that belong to more thanmaxCachedResultsroles. Consequently, theRolePrincipalobject'sIsInRolemethod will use theRolesclass to determine the user's roles. The reasonmaxCachedResultsexists is because many user agents do not permit cookies larger than 4,096 bytes. So this cap is meant to reduce the likelihood of exceeding this size limitation. If you have extremely long role names, you may want to consider specifying a smallermaxCachedResults` value; en caso contrario, si tiene nombres de roles extremadamente cortos, probablemente pueda aumentar este valor. |

Tabla 1: Opciones de configuración de cookies de caché de roles

Vamos a configurar nuestra aplicación para que use cookies de caché de roles no persistentes. Para ello, actualice el elemento <roleManager> en Web.config para incluir los siguientes atributos relacionados con cookies:

<roleManager enabled="true" 
          defaultProvider="SecurityTutorialsSqlRoleProvider"
          cacheRolesInCookie="true"
          createPersistentCookie="false"
          cookieProtection="All">

     <providers>
     ...
     </providers>
</roleManager>

He actualizado el elemento <roleManager> agregando tres atributos: cacheRolesInCookie, createPersistentCookie, y cookieProtection. Al establecer cacheRolesInCookie en true, el RoleManagerModule almacenará automáticamente en caché los roles del usuario en una cookie en lugar de tener que buscar la información de rol del usuario en cada solicitud. He establecido explícitamente los atributos createPersistentCookie y cookieProtection en false y All, respectivamente, Técnicamente, no necesito especificar valores para estos atributos, ya que acabo de asignarlos a sus valores predeterminados, pero los puse aquí para aclarar explícitamente que no estoy usando cookies persistentes y que la cookie está cifrada y validada.

Eso es todo. Por lo tanto, el marco roles almacenará en caché los roles de los usuarios en las cookies. Si el explorador del usuario no admite cookies, o si sus cookies se eliminan o pierden, de alguna manera, no es importante, el objeto RolePrincipal simplemente usará la clase Roles en caso de que ninguna cookie (o una no válida o expirada) esté disponible.

Nota:

El grupo Patrones y prácticas de Microsoft desaconseja el uso de cookies de caché de roles persistentes. Dado que la posesión de la cookie de caché de roles es suficiente para demostrar la pertenencia a roles, si un hacker puede obtener acceso a la cookie de un usuario válido, puede suplantar a ese usuario. La probabilidad de que esto suceda aumenta si la cookie se conserva en el explorador del usuario. Para obtener más información sobre esta recomendación de seguridad, así como otros problemas de seguridad, consulte la Lista de preguntas de seguridad para ASP.NET 2.0.

Paso 1: Definir reglas de autorización de direcciones URL basadas en roles

Como se describe en el tutorial Autorización basada en usuarios, la autorización de direcciones URL ofrece un medio para restringir el acceso a un conjunto de páginas por usuario o rol por rol. Las reglas de autorización de dirección URL se describen mediante Web.config el elemento <authorization> con elementos secundarios <allow> y <deny>. Además de las reglas de autorización relacionadas con el usuario descritas en los tutoriales anteriores, cada elemento secundario<allow> y <deny> también puede incluir:

  • Un rol determinado
  • Una lista delimitada por comas de roles

Por ejemplo, las reglas de autorización de direcciones URL conceden acceso a esos usuarios en los roles Administradores y Supervisores, pero deniegan el acceso a todos los demás:

<authorization>

     <allow roles="Administrators, Supervisors" />
     <deny users="*" />
</authorization>

El elemento <allow> del marcado anterior indica que se permiten los roles Administradores y Supervisores; el elemento <deny> indica a todos los usuarios que se deniegan.

Vamos a configurar nuestra aplicación para que las páginasManageRoles.aspx, UsersAndRoles.aspx, y CreateUserWizardWithRoles.aspx solo sean accesibles para los usuarios del rol Administradores, mientras que la página RoleBasedAuthorization.aspx sigue siendo accesible para todos los visitantes.

Para ello, empiece agregando un archivo Web.config a la carpeta Roles.

Add a Web.config File to the Roles directory

Figura 3: Agregar un archivo Web.config al directorioRoles (haga clic para ver la imagen de tamaño completo)

A continuación, agregue el siguiente marcado de configuración a Web.config:

<?xml version="1.0"?>

<configuration>
     <system.web>
          <authorization>
               <allow roles="Administrators" />
               <deny users="*"/>
          </authorization>

     </system.web>

     <!-- Allow all users to visit RoleBasedAuthorization.aspx -->
     <location path="RoleBasedAuthorization.aspx">
          <system.web>
               <authorization>
                    <allow users="*" />

               </authorization>
          </system.web>
     </location>
</configuration>

El elemento <authorization> de la sección <system.web> indica que solo los usuarios del rol Administradores pueden tener acceso a los recursos de ASP.NET en el directorio Roles. El elemento <location> define un conjunto alternativo de reglas de autorización de direcciones URL para la página RoleBasedAuthorization.aspx, lo que permite a todos los usuarios visitar la página.

Después de guardar los cambios en Web.config, registrarse como usuario que no esté en el rol Administradores y a continuación, intente visitar una de las páginas protegidas. UrlAuthorizationModule Detectará que no tiene permiso para visitar el recurso solicitado; por lo tanto, FormsAuthenticationModule le redirigirá a la página de inicio de sesión. A continuación, la página de registro le redirigirá a la página (consulte la UnauthorizedAccess.aspx figura 4). Esta redirección final desde la página de inicio de sesión para UnauthorizedAccess.aspx que se produzca debido al código que hemos agregado a la página de inicio de sesión en el paso 2 del tutorial de autorización basada en usuario. En concreto, la página de inicio de sesión redirige automáticamente a cualquier usuario autenticado a UnauthorizedAccess.aspx si la cadena de consultas contiene un parámetro ReturnUrl, ya que este parámetro indica que el usuario llegó a la página de inicio de sesión después de intentar ver una página que no estaba autorizada para ver.

Only Users in the Administrators Role Can View the Protected Pages

Figura 4: Solo los usuarios del rol Administradores pueden ver las páginas protegidas (Haga clic para ver la imagen de tamaño completo)

Cerrar sesión y a continuación, regístrese como usuario que esté en el rol Administradores. Ahora debería poder ver las tres páginas protegidas.

Tito Can Visit the UsersAndRoles.aspx Page Because He is in the Administrators Role

Figura 5: Tito puede visitar la página UsersAndRoles.aspxPorque está en el rol administradores (Haga clic para ver la imagen de tamaño completo)

Nota:

Al especificar reglas de autorización de direcciones URL (para roles o usuarios), es importante tener en cuenta que las reglas se analizan de una en una, desde la parte superior hacia abajo. Tan pronto como se encuentre una coincidencia, se concede o deniega el acceso al usuario, en función de si la coincidencia se encontró en un elemento <allow> o <deny>. Si no se encuentra ninguna coincidencia, se concede acceso al usuario. Por lo tanto, si desea restringir el acceso a una o varias cuentas de usuario, es imperativo usar un elemento <deny> como último elemento en la configuración de autorización de dirección URL. Si las reglas de autorización de direcciones URL no incluyen un elemento<deny>, se concederá acceso a todos los usuarios. Para un análisis más detallado de cómo se analizan las reglas de autorización de URL, consulte la sección "Cómo UrlAuthorizationModule utiliza las reglas de autorización para conceder o denegar el acceso" del tutorial Autorización basada en usuarios.

Paso 2: Limitar la funcionalidad en función de los roles del usuario que ha iniciado sesión actualmente

La autorización de direcciones URL facilita la especificación de reglas de autorización gruesas que indiquen qué identidades se permiten y cuáles se deniegan de ver una página determinada (o todas las páginas de una carpeta y sus subcarpetas). Sin embargo, en determinados casos es posible que deseemos permitir que todos los usuarios visiten una página, pero limite la funcionalidad de la página en función de los roles del usuario que visita. Esto puede implicar mostrar u ocultar datos en función del rol del usuario o ofrecer funcionalidad adicional a los usuarios que pertenecen a un rol determinado.

Estas reglas de autorización específicas basadas en roles se pueden implementar mediante declaración o mediante programación (o mediante alguna combinación de los dos). En la sección siguiente veremos cómo implementar la autorización detallada declarativa mediante el control LoginView. Después, exploraremos técnicas de programación. Sin embargo, para poder examinar la aplicación de reglas de autorización específicas, primero es necesario crear una página cuya funcionalidad depende del rol del usuario que lo visite.

Vamos a crear una página que muestre todas las cuentas de usuario del sistema en GridView. GridView incluirá el nombre de usuario, la dirección de correo electrónico de cada usuario, la fecha de último inicio de sesión y los comentarios sobre el usuario. Además de mostrar la información de cada usuario, GridView incluirá funcionalidades de edición y eliminación. Inicialmente, crearemos esta página con la funcionalidad de edición y eliminación disponible para todos los usuarios. En las secciones "Usar el control LoginView" y "Funcionalidad de limitación mediante programación", veremos cómo habilitar o deshabilitar estas características en función del rol del usuario que visita.

Nota:

La página de ASP.NET que estamos a punto de compilar usa un control GridView para mostrar las cuentas de usuario. Dado que esta serie de tutoriales se centra en la autenticación, autorización, cuentas de usuario y roles de formularios, no quiero dedicar demasiado tiempo a analizar los trabajos internos del control GridView. Aunque en este tutorial se proporcionan instrucciones paso a paso específicas para configurar esta página, no profundiza en los detalles de por qué se realizaron determinadas opciones o qué efecto tienen las propiedades concretas en la salida representada. Para obtener un examen exhaustivo del control GridView, consulte mi serie de tutoriales Trabajar con datos en ASP.NET 2.0.

Para empezar, abra la página RoleBasedAuthorization.aspx en la carpeta Roles. Arrastre un Control GridView desde la página hasta el Diseñador y establezca su ID en UserGrid. En un momento escribiremos código que llame al método Membership.GetAllUsers y enlazaremos el objeto MembershipUserCollection resultante a GridView. MembershipUserCollection contiene un objeto MembershipUser para cada cuenta de usuario del sistema; los objetos MembershipUser tienen propiedades como UserName, Email, LastLoginDate, etc.

Antes de escribir el código que enlaza las cuentas de usuario a la cuadrícula, primero definiremos los campos de GridView. En la etiqueta inteligente de GridView, haga clic en el vínculo "Editar columnas" para iniciar el cuadro de diálogo Campos (vea la figura 6). Desde aquí, desactive la casilla "Generar campos automáticamente" en la esquina inferior izquierda. Puesto que queremos que GridView incluya funcionalidades de edición y eliminación, agregue un CommandField y establezca sus propiedades ShowEditButton y ShowDeleteButton en True. A continuación, agregue cuatro campos para mostrar las propiedades UserName, Email, LastLoginDate, y Comment. Use un BoundField para las dos propiedades de solo lectura (UserName y LastLoginDate) y TemplateFields para los dos campos editables (Email y Comment).

Haga que el primer BoundField muestre la propiedadUserName; establezca sus propiedades HeaderText y DataField en "UserName". Este campo no se podrá editar, por lo que establezca su propiedad ReadOnly en True. Configure BoundField LastLoginDate estableciendo su HeaderText a "Último inicio de sesión" y su DataField a "LastLoginDate". Vamos a dar formato a la salida de este BoundField para que solo se muestre la fecha (en lugar de la fecha y hora). Para ello, establezca la propiedad de BoundField HtmlEncode en False y su propiedad DataFormatString en "{0:d}". Establezca también la propiedad ReadOnly en True.

Establezca las propiedades HeaderText de los dos TemplateFields en "Email" y "Comentario".

The GridView's Fields Can Be Configured Through the Fields Dialog Box

Figura 6: Los campos de GridView se pueden configurar a través del cuadro de diálogo Campos (haga clic para ver la imagen de tamaño completo)

Ahora es necesario definir ItemTemplate y EditItemTemplate para los TemplateFields "Email" y "Comentario". Añada un control Label Web a cada uno de los ItemTemplates y enlace sus propiedades Text a las propiedades Email y Comment, respectivamente.

Para TemplateField de "Correo electrónico", agregue un TextBox denominado Email a su EditItemTemplate y enlace su propiedad Text a la propiedad Email mediante el enlace de datos bidireccional. Agregue RequiredFieldValidator y RegularExpressionValidator a EditItemTemplate para asegurarse de que un visitante que edite la propiedad Email haya escrito una dirección de correo electrónico válida. Para TemplateField de "Comentario", agregue un TextBox de varias líneas denominado Comment a su EditItemTemplate. Establezca las propiedades Columns y Rows de TextBox en 40 y 4, respectivamente, y luego enlace su propiedad Text a la propiedad Comment mediante el enlace de datos bidireccional.

Después de configurar estos TemplateFields, su marcado declarativo debe ser similar al siguiente:

<asp:TemplateField HeaderText="Email">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label1" Text='<%# Eval("Email")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Email" Text='<%# Bind("Email")%>'></asp:TextBox>

          <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" 
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="You must provide an email address."
               SetFocusOnError="True">*</asp:RequiredFieldValidator>

          <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"
               ControlToValidate="Email" Display="Dynamic"
               ErrorMessage="The email address you have entered is not valid. Please fix 
               this and try again."
               SetFocusOnError="True"

               ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
          </asp:RegularExpressionValidator>
     </EditItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Comment">
     <ItemTemplate>
          <asp:Label runat="server" ID="Label2" Text='<%# Eval("Comment")%>'></asp:Label>

     </ItemTemplate>
     <EditItemTemplate>
          <asp:TextBox runat="server" ID="Comment" TextMode="MultiLine"
               Columns="40" Rows="4" Text='<%# Bind("Comment")%>'>

          </asp:TextBox>
     </EditItemTemplate>
</asp:TemplateField>

Al editar o eliminar una cuenta de usuario, es necesario saber el valor de propiedad UserName del usuario. Establezca la propiedad DataKeyNames de GridView en "UserName" para que esta información esté disponible a través de la colección DataKeys de GridView.

Por último, agregue un control ValidationSummary a la página y establezca su propiedad ShowMessageBox en True y su propiedad ShowSummary en False. Con esta configuración, ValidationSummary mostrará una alerta del lado cliente si el usuario intenta editar una cuenta de usuario con una dirección de correo electrónico que falta o no es válida.

<asp:ValidationSummary ID="ValidationSummary1"
               runat="server"
               ShowMessageBox="True"
               ShowSummary="False" />

Ya hemos completado el marcado declarativo de esta página. Nuestra siguiente tarea consiste en enlazar el conjunto de cuentas de usuario a GridView. Agregue un método denominado BindUserGrid a la clase de código subyacente de la página RoleBasedAuthorization.aspx que enlaza el MembershipUserCollection devuelto por Membership.GetAllUsers al GridView UserGrid. Llame a este método desde el controlador de eventos Page_Load en la primera visita de página.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     If Not Page.IsPostBack Then
          BindUserGrid()
     End If
End Sub

Private Sub BindUserGrid()
     Dim allUsers As MembershipUserCollection = Membership.GetAllUsers()
     UserGrid.DataSource = allUsers
     UserGrid.DataBind()
End Sub

Con este código en su lugar, visite la página a través de un explorador. Como se muestra en la figura 7, debería ver una información de descripción de GridView sobre cada cuenta de usuario del sistema.

The UserGrid GridView Lists Information About Each User in the System

Figura 7: El GridView UserGrid enumera información sobre cada usuario del sistema (Haga clic para ver la imagen de tamaño completo)

Nota:

El GridView UserGrid enumera todos los usuarios de una interfaz no paginada. Esta interfaz de cuadrícula simple no es adecuada para escenarios en los que hay varias docenas o más usuarios. Una opción es configurar GridView para habilitar la paginación. El método Membership.GetAllUsers tiene dos sobrecargas: una que no acepta parámetros de entrada y devuelve todos los usuarios y uno que toma valores enteros para el índice de página y el tamaño de página, y devuelve solo el subconjunto especificado de los usuarios. La segunda sobrecarga se puede usar para paginar de forma más eficaz a través de los usuarios, ya que devuelve solo el subconjunto preciso de cuentas de usuario en lugar todos ellos. Si tiene miles de cuentas de usuario, es posible que desee considerar una interfaz basada en filtros, una que solo muestre a los usuarios cuyo UserName comienza con un carácter seleccionado, por ejemplo. El método Membership.FindUsersByName es ideal para compilar una interfaz de usuario basada en filtros. Veremos la creación de una interfaz de este tipo en un tutorial futuro.

El control GridView ofrece compatibilidad integrada de edición y eliminación cuando el control está enlazado a un control de origen de datos configurado correctamente, como SqlDataSource o ObjectDataSource. El GridView UserGrid, sin embargo, tiene sus datos enlazados mediante programación; por lo tanto, debemos escribir código para realizar estas dos tareas. En particular, necesitaremos crear controladores de eventos para los eventos RowEditing, RowCancelingEdit, RowUpdating y RowDeleting del GridView, que se disparan cuando un visitante hace clic en los botones Editar, Cancelar, Actualizar o Eliminar del GridView.

Empiece por crear los controladores de eventos para los eventosRowEditing, RowCancelingEdit, y RowUpdating de GridView y agregue el código siguiente:

Protected Sub UserGrid_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles UserGrid.RowEditing
     ' Set the grid's EditIndex and rebind the data

     UserGrid.EditIndex = e.NewEditIndex
     BindUserGrid()
End Sub

Protected Sub UserGrid_RowCancelingEdit(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCancelEditEventArgs) Handles UserGrid.RowCancelingEdit
     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub
    
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ' Exit if the page is not valid
     If Not Page.IsValid Then
          Exit Sub
     End If

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Read in the entered information and update the user
     Dim EmailTextBox As TextBox = CType(UserGrid.Rows(e.RowIndex).FindControl("Email"),TextBox)
     Dim CommentTextBox As TextBox= CType(UserGrid.Rows(e.RowIndex).FindControl("Comment"),TextBox)

     ' Return information about the user
     Dim UserInfo As MembershipUser = Membership.GetUser(UserName)

     ' Update the User account information
     UserInfo.Email = EmailTextBox.Text.Trim()
     UserInfo.Comment = CommentTextBox.Text.Trim()

     Membership.UpdateUser(UserInfo)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

Los controladores de eventos RowEditing y RowCancelingEdit simplemente establecen la propiedad de GridView EditIndex y a continuación, vuelven a enlazar la lista de cuentas de usuario a la cuadrícula. Las cosas interesantes se producen en el controlador de eventos RowUpdating. Este controlador de eventos comienza asegurándose de que los datos son válidos y a continuación, toma el valor UserName de la cuenta de usuario editada de la colección DataKeys. Los TextBoxes Email y Comment de los dos TemplateFields EditItemTemplate se hacen referencia mediante programación. Sus propiedades Text contienen la dirección de correo electrónico y el comentario editados.

Para actualizar una cuenta de usuario a través de la API de pertenencia, primero necesitamos obtener la información del usuario, que hacemos a través de una llamada a Membership.GetUser(userName). El objeto devuelto MembershipUser y sus propiedades Email y Comment se actualizan con los valores introducidos en los dos TextBoxes de la interfaz de edición. Por último, estas modificaciones se guardan con una llamada a Membership.UpdateUser. El controlador de eventos RowUpdating finaliza revirtiendo GridView a su interfaz de edición previa.

A continuación, cree el controlador de eventos RowDeleting RowDeleting y agregue el código siguiente:

Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting

     ' Determine the username of the user we are editing
     Dim UserName As String = UserGrid.DataKeys(e.RowIndex).Value.ToString()

     ' Delete the user
     Membership.DeleteUser(UserName)

     ' Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1
     BindUserGrid()
End Sub

El controlador de eventos anterior comienza tomando el valor UserName de la colección DataKeys de GridView; este valor UserName se pasa al DeleteUsermétodo de la clase Membership. El método DeleteUser elimina la cuenta de usuario del sistema, incluidos los datos de pertenencia relacionados (como los roles a los que pertenece este usuario). Después de eliminar el usuario, el de la cuadrícula EditIndex se establece en -1 (en caso de que el usuario haga clic en Eliminar mientras otra fila estaba en modo de edición) y se llama al método BindUserGrid.

Nota:

El botón Eliminar no requiere ningún tipo de confirmación del usuario antes de eliminar la cuenta de usuario. Le recomendamos que agregue algún tipo de confirmación de usuario para reducir la posibilidad de que se elimine accidentalmente una cuenta. Una de las formas más fáciles de confirmar una acción es a través de un cuadro de diálogo confirmar del lado cliente. Para obtener más información sobre esta técnica, vea Agregar confirmación del lado cliente al eliminar.

Compruebe que esta página funciona según lo previsto. Debe poder editar la dirección de correo electrónico y el comentario de cualquier usuario, así como eliminar cualquier cuenta de usuario. Puesto que la página RoleBasedAuthorization.aspx es accesible para todos los usuarios, cualquier usuario, incluso visitantes anónimos, puede visitar esta página y editar y eliminar cuentas de usuario. Vamos a actualizar esta página para que solo los usuarios de los roles supervisores y administradores puedan editar la dirección de correo electrónico y el comentario de un usuario, y solo los administradores pueden eliminar una cuenta de usuario.

La sección "Usar el control LoginView" examina el uso del control LoginView para mostrar instrucciones específicas del rol del usuario. Si una persona del rol Administradores visita esta página, mostraremos instrucciones sobre cómo editar y eliminar usuarios. Si un usuario del rol Supervisores llega a esta página, mostraremos instrucciones sobre la edición de usuarios. Y si el visitante es anónimo o no está en el rol Supervisores o Administradores, mostraremos un mensaje que explica que no puede editar o eliminar información de la cuenta de usuario. En la sección "Funcionalidad de limitación mediante programación", escribiremos código que muestre u oculte mediante programación los botones Editar y Eliminar en función del rol del usuario.

Uso del control LoginView

Como hemos visto en los tutoriales anteriores, el control LoginView es útil para mostrar diferentes interfaces para usuarios autenticados y anónimos, pero el control LoginView también se puede usar para mostrar un marcado diferente en función de los roles del usuario. Vamos a usar un control LoginView para mostrar instrucciones diferentes en función del rol del usuario que visita.

Empiece agregando un elemento LoginView encima de GridView UserGrid. Como hemos explicado anteriormente, el control LoginView tiene dos plantillas integradas: AnonymousTemplate y LoggedInTemplate. Escriba un breve mensaje en ambas plantillas que informe al usuario de que no puede editar ni eliminar información de usuario.

<asp:LoginView ID="LoginView1" runat="server">
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. Therefore you
           cannot edit or delete any user information.
     </LoggedInTemplate>
     <AnonymousTemplate>

          You are not logged into the system. Therefore you cannot edit or delete any user
           information.
     </AnonymousTemplate>
</asp:LoginView>

Además de AnonymousTemplate y LoggedInTemplate, el control LoginView puede incluir RoleGroups, que son plantillas específicas de rol. Cada RoleGroup contiene una sola propiedad, Roles, que especifica a qué roles se aplica RoleGroup. La propiedad Roles se puede establecer en un solo rol (como "Administradores") o en una lista delimitada por comas de roles (como "Administradores, Supervisores").

Para administrar RoleGroups, haga clic en el vínculo "Editar grupos de roles" de la etiqueta inteligente del control para abrir el Editor de recopilación RoleGroup. Agregue dos nuevos RoleGroups. Establezca la primera propiedad Roles de RoleGroup en "Administradores" y la segunda en "Supervisores".

Manage the LoginView's Role-Specific Templates Through the RoleGroup Collection Editor

Figura 8: Administrar las plantillas específicas de rol de LoginView mediante el Editor de colecciones RoleGroup (haga clic para ver la imagennde tamaño completo)

Haga clic en Aceptar para cerrar el Editor de colección RoleGroup; esto actualiza el marcado declarativo de LoginView para incluir una sección <RoleGroups> con un elemento secundario <asp:RoleGroup> para cada RoleGroup definido en el Editor de colección RoleGroup. Además, en la lista desplegable "Vistas" de la etiqueta inteligente de LoginView, que inicialmente se listan solo AnonymousTemplate y LoggedInTemplate, ahora también se incluyen los RoleGroups agregados.

Edite RoleGroups para que los usuarios del rol Supervisores muestren instrucciones sobre cómo editar cuentas de usuario, mientras que los usuarios del rol Administradores se muestran instrucciones para editar y eliminar. Después de realizar estos cambios, el marcado declarativo de LoginView debe ser similar al siguiente.

<asp:LoginView ID="LoginView1" runat="server">
     <RoleGroups>
          <asp:RoleGroup Roles="Administrators">

               <ContentTemplate>
                    As an Administrator, you may edit and delete user accounts. 
                    Remember: With great power comes great responsibility!
               </ContentTemplate>
          </asp:RoleGroup>
          <asp:RoleGroup Roles="Supervisors">
               <ContentTemplate>
                    As a Supervisor, you may edit users&#39; Email and Comment information. 
                    Simply click the Edit button, make your changes, and then click Update.
               </ContentTemplate>

          </asp:RoleGroup>
     </RoleGroups>
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. 
          Therefore you cannot edit or delete any user information.
     </LoggedInTemplate>
     </AnonymousTemplate>
          You are not logged into the system. 
          Therefore you cannot edit or delete any user information.
     </AnonymousTemplate>
</asp:LoginView>

Después de realizar estos cambios, guarde la página y después la visite a través de un explorador. En primer lugar, visite la página como usuario anónimo. Debería mostrar el mensaje "No se ha registrado en el sistema. Por lo tanto, no puede editar ni eliminar ninguna información de usuario". A continuación, inicie sesión como usuario autenticado, pero uno que no esté en el rol Supervisores ni Administradores. Esta vez debería ver el mensaje "No es miembro de los roles supervisores o administradores. Por lo tanto, no puede editar ni eliminar ninguna información de usuario".

A continuación, inicie sesión como usuario que sea miembro del rol Supervisores. Esta vez debería ver el mensaje específico del rol supervisores (consulte la figura 9). Y si se registra como usuario en el rol Administradores, debería ver el mensaje específico del rol Administradores (vea la figura 10).

Bruce is Shown the Supervisors Role-Specific Message

Figura 9: Bruce se muestra el mensaje específico del rol supervisores (haga clic para ver la imagen de tamaño completo)

Tito is Shown the Administrators Role-Specific Message

Figura 10: Tito se muestra el mensaje específico del rol administradores (haga clic para ver la imagen de tamaño completo)

Como se muestran las capturas de pantalla de las figuras 9 y 10, LoginView solo representa una plantilla, incluso si se aplican varias plantillas. Bruce y Tito son usuarios que han iniciado sesión, pero LoginView representa solo el RoleGroup coincidente y no el LoggedInTemplate. Además, Tito pertenece a los roles Administradores y Supervisores, pero el control LoginView representa la plantilla específica del rol Administradores en lugar de supervisores.

En la figura 11 se muestra el flujo de trabajo usado por el control LoginView para determinar qué plantilla se va a representar. Tenga en cuenta que si hay más de un RoleGroup especificado, la plantilla LoginView representa el primer RoleGroup que coincide. En otras palabras, si hubiéramos colocado el RoleGroup supervisores como el primer RoleGroup y los Administradores como el segundo, entonces cuando Tito visitó esta página vería el mensaje supervisores.

The LoginView Control's Workflow for Determining What Template to Render

Figura 11: Flujo de trabajo del control LoginView para determinar qué plantilla se va a representar (haga clic para ver la imagen de tamaño completo)

Limitación de la funcionalidad mediante programación

Aunque el control LoginView muestra instrucciones diferentes en función del rol del usuario que visita la página, los botones Editar y Cancelar permanecen visibles para todos. Es necesario ocultar mediante programación los botones Editar y Eliminar para visitantes anónimos y usuarios que no están en el rol Supervisores ni Administradores. Es necesario ocultar el botón Eliminar para todos los usuarios que no son administradores. Para lograr esto, escribiremos un poco de código que haga referencia mediante programación a edit y delete LinkButtons de CommandField y establezca sus propiedades Visible a False, si es necesario.

La manera más sencilla de hacer referencia a los controles en un CommandField es convertirlo primero en una plantilla. Para ello, haga clic en el vínculo "Editar columnas" de la etiqueta inteligente de GridView, seleccione CommandField en la lista de campos actuales y haga clic en el vínculo "Convertir este campo en un TemplateField". Esto convierte CommandField en un TemplateField con ItemTemplate y EditItemTemplate. ItemTemplate contiene los botones Editar y Eliminar, mientras que EditItemTemplate alberga los LinkButtons Actualizar y Cancelar.

Convert the CommandField Into a TemplateField

Figura 12: Convertir CommandField en un TemplateField (haga clic para ver la imagen de tamaño completo)

Actualice los LinkButtons Editar y Eliminar en ItemTemplate, estableciendo sus propiedades ID a los valores EditButton y DeleteButton, respectivamente.

<asp:TemplateField ShowHeader="False">
     <EditItemTemplate>
          <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" 
               CommandName="Update" Text="Update"></asp:LinkButton>

           <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
               CommandName="Cancel" Text="Cancel"></asp:LinkButton>

     </EditItemTemplate>
     <ItemTemplate>
          <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" 
               CommandName="Edit" Text="Edit"></asp:LinkButton>

           <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
               CommandName="Delete" Text="Delete"></asp:LinkButton>

     </ItemTemplate>
</asp:TemplateField>

Cada vez que los datos se enlazan a GridView, GridView enumera los registros de su propiedad DataSource y genera un objeto correspondiente GridViewRow. A medida que se crea cada objeto GridViewRow, se desencadena el evento RowCreated. Para ocultar los botones Editar y Eliminar para usuarios no autorizados, es necesario crear un controlador de eventos para este evento y hacer referencia mediante programación a los botones Editar y Eliminar LinkButtons, estableciendo sus propiedades Visible en consecuencia.

Cree un controlador de eventos para el evento RowCreated y agregue el siguiente código:

Protected Sub UserGrid_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles UserGrid.RowCreated
     If e.Row.RowType = DataControlRowType.DataRow AndAlso e.Row.RowIndex <> UserGrid.EditIndex Then
          ' Programmatically reference the Edit and Delete LinkButtons
          Dim EditButton As LinkButton = CType(e.Row.FindControl("EditButton"), LinkButton)

          Dim DeleteButton As LinkButton = CType(e.Row.FindControl("DeleteButton"), LinkButton)

          EditButton.Visible = (User.IsInRole("Administrators") OrElse User.IsInRole("Supervisors"))
          DeleteButton.Visible = User.IsInRole("Administrators")
     End If
End Sub

Tenga en cuenta que el evento RowCreated se activa para todas las filas de GridView, incluido el encabezado, el pie de página, la interfaz del buscapersonas, etc. Solo queremos hacer referencia mediante programación a los botones Editar y Eliminar LinkButtons si estamos tratando con una fila de datos no en modo de edición (ya que la fila en modo de edición tiene botones Actualizar y Cancelar en lugar de Editar y Eliminar). Esta comprobación se controla mediante el extracto If.

Si estamos tratando con una fila de datos que no está en modo de edición, se hace referencia a los elementos Edit y Delete LinkButtons y sus propiedades Visible se establecen en función de los valores booleanos devueltos por el métodoUser del objetoIsInRole(roleName). El objeto User hace referencia a la entidad de seguridad creada por RoleManagerModule; en consecuencia, el método IsInRole(roleName) usa la API de roles para determinar si el visitante actual pertenece a roleName.

Nota:

Podríamos haber usado la clase Roles directamente, reemplazando la llamada a User.IsInRole(roleName) por una llamada al método Roles.IsUserInRole(roleName). Decidí usar el método IsInRole(roleName) del objeto de entidad de seguridad en este ejemplo porque es más eficaz que usar directamente la API de roles. Anteriormente en este tutorial se ha configurado el administrador de roles para almacenar en caché los roles del usuario en una cookie. Estos datos de cookies almacenados en caché solo se usan cuando se llama al método IsInRole(roleName)de la entidad de seguridad; las llamadas directas a la API de roles siempre implican un viaje al almacén de roles. Incluso si los roles no se almacenan en caché en una cookie, llamar al método IsInRole(roleName) del objeto de entidad de seguridad suele ser más eficaz porque cuando se llama por primera vez durante una solicitud almacena en caché los resultados. La API roles, por otro lado, no realiza ningún almacenamiento en caché. Dado que el evento RowCreated se desencadena una vez por cada fila de GridView, el uso de User.IsInRole(roleName) implica solo un viaje al almacén de roles, mientras que Roles.IsUserInRole(roleName) requiere N viajes, donde N es el número de cuentas de usuario mostradas en la cuadrícula.

La propiedad Visible del botón Editar se establece en True si el usuario que visita esta página está en el rol Administradores o Supervisores; de lo contrario, se establece en False. La propiedad Visible del botón Eliminar se establece en True solo si el usuario está en el rol Administradores.

Pruebe esta página a través de un explorador. Si visita la página como visitante anónimo o como usuario que no es supervisor ni administrador, CommandField está vacío; sigue existiendo, pero como una fina astilla sin los botones Editar o Eliminar.

Nota:

Es posible ocultar CommandField por completo cuando un no supervisor y no administrador está visitando la página. Lo dejo como ejercicio para el lector.

The Edit and Delete Buttons are Hidden for Non-Supervisors and Non-Administrators

Figura 13: Los botones Editar y Eliminar están ocultos para no supervisores y no administradores (Haga clic para ver la imagen de tamaño completo)

Si un usuario que pertenece al rol Supervisores (pero no al rol Administradores), ve solo el botón Editar.

While the Edit Button is Available for Supervisors, the Delete Button is Hidden

Figura 14: Mientras el botón Editar está disponible para supervisores, el botón Eliminar está oculto (Haga clic para ver la imagen de tamaño completo)

Y si un administrador visita, tiene acceso a los botones Editar y Eliminar.

The Edit and Delete Buttons are Available Only for Administrators

Figura 15: Los botones Editar y Eliminar solo están disponibles para los administradores (Haga clic para ver la imagen de tamaño completo)

Paso 3: Aplicar reglas de autorización basadas en roles a clases y métodos

En el paso 2, limitamos las funcionalidades de edición a los usuarios de los roles supervisores y administradores y eliminamos las funcionalidades solo a los administradores. Esto se ha logrado ocultando los elementos de la interfaz de usuario asociados para los usuarios no autorizados a través de técnicas de programación. Estas medidas no garantizan que un usuario no autorizado no pueda realizar una acción con privilegios. Puede haber elementos de interfaz de usuario que se agreguen más adelante o que olvidemos ocultar para usuarios no autorizados. O es posible que un hacker descubra alguna otra manera de obtener la página de ASP.NET para ejecutar el método deseado.

Una manera fácil de asegurarse de que un usuario no autorizado pueda tener acceso a una determinada funcionalidad es decorar esa clase o método con el atributoPrincipalPermission. Cuando el entorno de ejecución de .NET usa una clase o ejecuta uno de sus métodos, comprueba que el contexto de seguridad actual tiene permiso. El atributo PrincipalPermission proporciona un mecanismo a través del cual podemos definir estas reglas.

Hemos examinado el uso del atributo PrincipalPermission de nuevo en el tutorial autorización basada en el usuario. Específicamente, vimos cómo decorar el GridView's SelectedIndexChanged y el controlador de eventos RowDeleting para que solo pudieran ser ejecutados por usuarios autenticados y Tito, respectivamente. El atributo PrincipalPermission funciona igual que con roles.

Vamos a demostrar el uso del atributo PrincipalPermission en GridView's RowUpdating y los RowDeletingcontroladores de eventos para prohibir la ejecución de usuarios no autorizados. Todo lo que necesitamos hacer es agregar el atributo adecuado en cada definición de función:

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
<PrincipalPermission(SecurityAction.Demand, Role:="Supervisors")>_
Protected Sub UserGrid_RowUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdateEventArgs) Handles UserGrid.RowUpdating
     ...
End Sub

<PrincipalPermission(SecurityAction.Demand, Role:="Administrators")>_
Protected Sub UserGrid_RowDeleting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewDeleteEventArgs) Handles UserGrid.RowDeleting
     ...
End Sub

El atributo para el controlador de eventos RowUpdating determina que solo los usuarios de los roles Administradores o Supervisores pueden ejecutar el controlador de eventos, donde como atributo en el controlador de eventos RowDeleting limita la ejecución a los usuarios del rol Administradores.

Nota:

El atributo PrincipalPermission se representa como una clase en el espacio de nombres System.Security.Permissions. Asegúrese de agregar un extracto Imports System.Security.Permissions en la parte superior del archivo de clase de código subyacente para importar este espacio de nombres.

Si, de alguna manera, un no administrador intenta ejecutar el controlador de eventos RowDeleting o si un no supervisor o no administrador intenta ejecutar el controlador de eventos RowUpdating, el entorno de ejecución de .NET generará un SecurityException.

If the Security Context is not Authorized to Execute the Method, a SecurityException is Thrown

Figura 16: Si el contexto de seguridad no está autorizado para ejecutar el método, se produce una excepción SecurityException (haga clic para ver la imagen de tamaño completo)

Además de las páginas ASP.NET, muchas aplicaciones también tienen una arquitectura que incluye varias capas, como la lógica de negocios y las capas de acceso a datos. Estas capas normalmente se implementan como bibliotecas de clases y ofrecen clases y métodos para realizar la funcionalidad relacionada con la lógica de negocios y los datos. El atributo PrincipalPermission también es útil para aplicar reglas de autorización a estas capas.

Para obtener más información sobre el uso del atributo PrincipalPermission para definir reglas de autorización en clases y métodos, consulte la entrada de blog de Scott Guthrie sobre Cómo agregar reglas de autorización a capas de datos y empresariales mediante PrincipalPermissionAttributes.

Resumen

En este tutorial hemos visto cómo especificar reglas de autorización generales y específicas basadas en los roles del usuario. ASP. La característica de autorización de direcciones URL de NET permite al desarrollador de páginas especificar qué identidades se permiten o deniegan el acceso a las páginas. Como hemos visto en el Tutorial de Autorización basada en el usuario, las reglas de autorización de direcciones URL se pueden aplicar por usuario. También se pueden aplicar por rol, como vimos en el paso 1 de este tutorial.

Las reglas de autorización específicas se pueden aplicar mediante declaración o mediante programación. En el paso 2, hemos visto el uso de la característica RoleGroups del control LoginView para representar una salida diferente en función de los roles del usuario visitante. También hemos examinado formas de determinar mediante programación si un usuario pertenece a un rol específico y cómo ajustar la funcionalidad de la página en consecuencia.

¡Feliz programación!

Lecturas adicionales

Para obtener más información sobre los temas tratados en este tutorial, consulte los siguientes recursos:

Acerca del autor

Scott Mitchell, autor de varios libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha estado trabajando con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, formador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Se puede contactar con Scott en mitchell@4guysfromrolla.com o a través de su blog en http://ScottOnWriting.NET.

Agradecimientos especiales a...

Muchos revisores han evaluado esta serie de tutoriales. Los revisores principales de este tutorial incluyen Suchi Banerjee y Teresa Murphy. ¿Le interesaría revisar mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4GuysFromRolla.com