Crear y administrar roles (C#)

por Scott Mitchell

Nota:

Desde que se escribió este artículo, los proveedores de pertenencia a 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 que se escribió este artículo. ASP.NET Identity tiene una serie de ventajas sobre el sistema de pertenencia ASP.NET, incluidas las siguientes:

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

Descargar código o Descargar PDF

En este tutorial se examinan los pasos necesarios para configurar el marco de roles. Después, crearemos páginas web para crear y eliminar roles.

Introducción

En el tutorial Autorización basada en usuarios vimos cómo utilizar la autorización de URL para restringir el acceso de determinados usuarios a un conjunto de páginas y exploramos técnicas declarativas y programáticas para ajustar la funcionalidad de una página ASP.NET en función del usuario visitante. Sin embargo, conceder permisos de acceso a páginas o funcionalidades usuario por usuario puede convertirse en una pesadilla de mantenimiento en escenarios en los que hay muchas cuentas de usuario o cuando los privilegios de los usuarios cambian a menudo. Cada vez que un usuario obtiene o pierde la autorización para realizar una tarea determinada, el administrador debe actualizar las reglas de autorización de dirección URL adecuadas, el marcado declarativo y el código.

Normalmente ayuda a clasificar a los usuarios en grupos o roles y, a continuación, aplicar permisos por rol. Por ejemplo, la mayoría de las aplicaciones web tienen un determinado conjunto de páginas o tareas que están reservados solo para los usuarios administrativos. Con las técnicas aprendidas en tutorial Autorización basada en usuarios, agregaríamos las reglas de autorización de direcciones URL adecuadas, el marcado declarativo y el código para permitir que las cuentas de usuario especificadas realicen tareas administrativas. Pero si se agregó un nuevo administrador o si un administrador existente necesitaba revocar sus derechos de administración, tendríamos que devolver y actualizar los archivos de configuración y las páginas web. Sin embargo, con los roles, podríamos crear un rol denominado Administradores y asignar esos usuarios de confianza al rol Administradores. A continuación, agregaríamos las reglas de autorización de direcciones URL adecuadas, el marcado declarativo y el código para permitir que el rol Administradores realice las diversas tareas administrativas. Con esta infraestructura en su lugar, agregar nuevos administradores al sitio o quitar los existentes es tan sencillo como incluir o quitar el usuario del rol Administradores. No hace falta ninguna configuración, marcado declarativo o cambios de código.

ASP.NET ofrece un marco de roles para definir roles y asociarlos con cuentas de usuario. Con el marco de roles podemos crear y eliminar roles, agregar o quitar usuarios de un rol, determinar el conjunto de usuarios que pertenecen a un rol determinado e indicar si un usuario pertenece a un rol determinado. Una vez configurado el marco de roles, podemos limitar el acceso a las páginas en función del rol mediante reglas de autorización de URL y mostrar u ocultar información o funciones adicionales en una página en función de los roles del usuario conectado en ese momento.

En este tutorial se examinan los pasos necesarios para configurar el marco de roles. Después, crearemos páginas web para crear y eliminar roles. En el tutorial Asignación de roles a usuarios veremos cómo agregar y quitar usuarios de roles. Y en el tutorial Autorización basada en roles veremos cómo limitar el acceso a las páginas en función del rol junto con cómo ajustar la funcionalidad de la página en función del rol del usuario que la visite. Comencemos.

Paso 1: agregar nuevas páginas ASP.NET

En este tutorial y en los dos siguientes examinaremos varias funciones y funcionalidades relacionadas con los roles. Necesitaremos una serie de páginas ASP.NET para implementar los temas examinados en estos tutoriales. Vamos a crear estas páginas y actualizar el mapa del sitio.

Empiece por crear una nueva carpeta en el proyecto denominado Roles. A continuación, agregue cuatro páginas ASP.NET nuevas a la carpeta Roles, vinculando cada página con la página maestra Site.master. Asigne un nombre a las páginas:

  • ManageRoles.aspx
  • UsersAndRoles.aspx
  • CreateUserWizardWithRoles.aspx
  • RoleBasedAuthorization.aspx

En este momento, el Explorador de soluciones del proyecto debe ser similar a la captura de pantalla que se muestra en la ilustración 1.

Four New Pages Have Been Added to the Roles Folder

Ilustración 1: se han agregado cinco páginas nuevas a la carpeta Roles (haga clic para ver la imagen a tamaño completo)

Cada página debe, en este momento, tener los dos controles de contenido, uno para cada uno de los ContentPlaceHolders de la página maestra: MainContent y LoginContent.

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent"Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="LoginContent"Runat="Server">
</asp:Content>

Recuerde que el marcado predeterminado de ContentPlaceHolder LoginContent muestra un vínculo para iniciar sesión o cerrar sesión en el sitio, en función de si el usuario está autenticado. Sin embargo, la presencia del control Content Content2 en la página ASP.NET invalida el marcado predeterminado de la página maestra. Como se ha explicado en el tutorial Introducción a la autenticación de formularios, la invalidación del marcado predeterminado es útil en las páginas en las que no queremos mostrar opciones relacionadas con el inicio de sesión en la columna izquierda.

Sin embargo, para estas cuatro páginas queremos mostrar el marcado predeterminado de la página maestra para ContentPlaceHolder LoginContent. Por lo tanto, quite el marcado declarativo del control de contenido Content2. Después de hacerlo, cada uno de los cuatro marcados de la página debe contener solo un control de contenido.

Por último, vamos a actualizar el mapa del sitio (Web.sitemap) para incluir estas nuevas páginas web. Agregue el siguiente XML después del <siteMapNode> que hemos agregado para los tutoriales de pertenencia.

<siteMapNode title="Roles">
 <siteMapNode url="~/Roles/ManageRoles.aspx" title="Manage Roles"/>
 <siteMapNode url="~/Roles/UsersAndRoles.aspx" title="Users and Roles" />
 <siteMapNode url="~/Roles/CreateUserWizardWithRoles.aspx" title="Create Account (with Roles)" />
 <siteMapNode url="~/Roles/RoleBasedAuthorization.aspx" title="Role-Based Authorization" />
</siteMapNode>

Con el mapa del sitio actualizado, visite el sitio a través de un explorador. Como se muestra en la ilustración 2, la navegación de la izquierda ahora incluye elementos para los tutoriales sobre roles.

The navigation on the left now includes items for the Roles tutorials.

Ilustración 2: se han agregado cuatro páginas nuevas a la carpeta Roles (haga clic para ver la imagen a tamaño completo)

Paso 2: especificar y configurar el proveedor del marco de roles

Al igual que el marco de pertenencia, el marco de roles se compila sobre el modelo de proveedor. Como se describe en el tutorial Aspectos básicos de seguridad y soporte técnico de ASP.NET, .NET Framework se incluye con tres proveedores de roles integrados: AuthorizationStoreRoleProvider, WindowsTokenRoleProvider y SqlRoleProvider. Esta serie de tutoriales se centra en el SqlRoleProvider, que usa una base de datos de Microsoft SQL Server como almacén de roles.

En el marco de roles y SqlRoleProvider funcionan igual que el marco de pertenencia y SqlMembershipProvider. .NET Framework contiene una clase Roles que actúa como API para el marco de roles. La clase Roles tiene métodos estáticos como CreateRole, DeleteRole, GetAllRoles, AddUserToRole, IsUserInRole, etc. Cuando se invoca uno de estos métodos, la clase Roles delega la llamada al proveedor configurado. El SqlRoleProvider funciona con las tablas específicas del rol (aspnet_Roles y aspnet_UsersInRoles) en respuesta.

Para usar el proveedor SqlRoleProvider en nuestra aplicación, es necesario especificar qué base de datos se va a usar como almacén. El SqlRoleProvider espera que el almacén de roles especificado tenga determinadas tablas de base de datos, vistas y procedimientos almacenados. Estos objetos de base de datos necesarios se pueden agregar mediante la herramienta aspnet_regsql.exe. En este momento ya tenemos una base de datos con el esquema necesario para el SqlRoleProvider. De nuevo en el tutorial Creación del esquema de pertenencia en SQL Server creamos una base de datos denominada SecurityTutorials.mdf y usamos aspnet_regsql.exe para agregar los servicios de aplicación, que incluían los objetos de base de datos necesarios para el SqlRoleProvider. Por lo tanto, solo es necesario indicar al marco de roles que habilite la compatibilidad con roles y que use el SqlRoleProvider con la base de datos SecurityTutorials.mdf como almacén de roles.

El marco de roles se configura a través del elemento <roleManager> del archivo Web.config de la aplicación. De forma predeterminada, la compatibilidad con roles está deshabilitada. Para habilitarla, debe establecer el atributo enabled del elemento <roleManager> en true de este modo:

<?xml version="1.0"?>
<configuration>
 <system.web>
 ... Additional configuration markup removed for brevity ...

 <roleManager enabled="true" />
 <system.web>
</configuration>

De forma predeterminada, todas las aplicaciones web tienen un proveedor de roles denominado AspNetSqlRoleProvider de tipo SqlRoleProvider. Este proveedor predeterminado se registra en machine.config (ubicado en %WINDIR%\Microsoft.Net\Framework\v2.0.50727\CONFIG):

<roleManager>
 <providers>
 <add name="AspNetSqlRoleProvider"
 connectionStringName="LocalSqlServer"
 applicationName="/"
 type="System.Web.Security.SqlRoleProvider, 
 System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
 </providers>
</roleManager>

El atributo connectionStringName del proveedor especifica el almacén de roles que se usa. El proveedor AspNetSqlRoleProvider establece este atributo en LocalSqlServer, que también se define en machine.config y puntos, de forma predeterminada, en una base de datos de SQL Server 2005 Express Edition en la carpeta App_Data denominada aspnet.mdf.

Por lo tanto, si simplemente habilitamos el marco de roles sin especificar información de proveedor en el archivo Web.config de la aplicación, la aplicación usa el proveedor de roles registrado predeterminado, AspNetSqlRoleProvider. Si la base de datos ~/App_Data/aspnet.mdf no existe, el runtime de ASP.NET la creará automáticamente y agregará el esquema de servicios de aplicación. Sin embargo, no queremos usar la base de datos aspnet.mdf; en su lugar, queremos usar la base de datos SecurityTutorials.mdf a la que ya hemos creado y agregado el esquema de servicios de aplicación. Esta modificación se puede realizar de una de estas dos maneras:

  • Especifique un valor para el LocalSqlServernombre de la cadena de conexión enWeb.config. Al sobrescribir el valor de nombre de la cadena de conexión LocalSqlServer en Web.config, podemos usar el proveedor de roles registrado predeterminado (AspNetSqlRoleProvider) y hacer que funcione correctamente con la base de datos SecurityTutorials.mdf. Para obtener más información sobre esta técnica, consulte la entrada de blog de Scott Guthrie: Configuración de los servicios de aplicaciones ASP.NET 2.0 para utilizar SQL Server 2000 o SQL Server 2005 .
  • Agregue un nuevo proveedor registrado de tipoSqlRoleProvidery configure su valorconnectionStringNamepara que apunte a la base de datosSecurityTutorials.mdf. Este es el enfoque que he recomendado y usado en el tutorial Creación del esquema de pertenencia en SQL Server, y es el enfoque que usaré también en este tutorial.

Agregue el siguiente marcado de configuración roles al archivo Web.config. Este marcado registra un nuevo proveedor denominado SecurityTutorialsSqlRoleProvider.

<?xml version="1.0"?>    
<configuration>    
 <connectionStrings>    
 <add name="SecurityTutorialsConnectionString"    
 connectionString="..."/>    
 </connectionStrings>

 <system.web>    
 ... Additional configuration markup removed for brevity ...

 <roleManager enabled="true" defaultProvider="SecurityTutorialsSqlRoleProvider">    
 <providers>    
 <add name="SecurityTutorialsSqlRoleProvider"    
 type="System.Web.Security.SqlRoleProvider"    
 applicationName="SecurityTutorials"    
 connectionStringName="SecurityTutorialsConnectionString" />    
 </providers>    
 </roleManager>    
 <system.web>    
</configuration>

El marcado anterior define el SecurityTutorialsSqlRoleProvider como proveedor predeterminado (a través del atributo defaultProvider del elemento <roleManager>). También establece la configuración applicationName de SecurityTutorialsSqlRoleProvider en SecurityTutorials, que es la misma configuración de applicationName usada por el proveedor de pertenencia (SecurityTutorialsSqlMembershipProvider). Aunque no se muestra aquí, el elemento <add> para el SqlRoleProvider también puede contener un atributo commandTimeout para especificar la duración del tiempo de espera de la base de datos, en segundos. El valor predeterminado es 30.

Con este marcado de configuración en su lugar, podemos empezar a usar la funcionalidad de rol dentro de nuestra aplicación.

Nota:

El marcado de configuración anterior muestra el uso de los atributos enabled ydefaultProvider del elemento<roleManager>. Hay una serie de otros atributos que afectan a la forma en que el marco de roles asocia información de roles por usuario. Examinaremos esta configuración en el tutorial Autorización basada en roles.

Paso 3: examen de la API de roles

La funcionalidad del marco de roles se expone a través de la clase Roles, que contiene trece métodos estáticos para realizar operaciones basadas en roles. Al examinar la creación y eliminación de roles en los pasos 4 y 6, usaremos los métodos CreateRole y DeleteRole, que agregan o quitan un rol del sistema.

Para obtener una lista de todos los roles del sistema, use el método GetAllRoles (consulte el paso 5). El método RoleExists devuelve un valor booleano que indica si existe un rol especificado.

En el siguiente tutorial examinaremos cómo asociar usuarios a roles. Los métodos AddUserToRole, AddUserToRoles, AddUsersToRole y AddUsersToRoles de la clase Roles agregan uno o varios usuarios a uno o varios roles. Para quitar usuarios de roles, use los métodos RemoveUserFromRole, RemoveUserFromRoles, RemoveUsersFromRoleo RemoveUsersFromRoles.

En el tutorial Autorización basada en roles veremos formas de mostrar u ocultar la funcionalidad mediante programación en función del rol del usuario que ha iniciado sesión actualmente. Para ello, podemos usar los métodos FindUsersInRole, GetRolesForUser, GetUsersInRole o IsUserInRole de la clase Role.

Nota:

Tenga en cuenta que en cualquier momento se invoca uno de estos métodos, la clase Roles delega la llamada al proveedor configurado. En nuestro caso, esto significa que la llamada se envía al SqlRoleProvider. A continuación, el SqlRoleProvider realiza la operación de base de datos adecuada en función del método invocado. Por ejemplo, el código Roles.CreateRole("Administrators") da como resultado en el SqlRoleProvider ejecutando el procedimiento almacenado aspnet_Roles_CreateRole, que inserta un nuevo registro en la tabla aspnet_Roles denominada Administradores .

En el resto de este tutorial se examina el uso de los métodos CreateRole, GetAllRoles y DeleteRolede la clase Roles para administrar los roles del sistema.

Paso 4: crear nuevos roles

Los roles ofrecen una manera de agrupar arbitrariamente a los usuarios y, normalmente, esta agrupación se usa para una manera más cómoda de aplicar reglas de autorización. Pero para usar roles como mecanismo de autorización, primero es necesario definir qué roles existen en la aplicación. Desafortunadamente, ASP.NET no incluye un control CreateRoleWizard. Para agregar nuevos roles, es necesario crear una interfaz de usuario adecuada e invocar la API de roles nosotros mismos. La buena noticia es que esto es muy fácil de lograr.

Nota:

Aunque no hay ningún control web CreateRoleWizard, tenemos la Herramienta de administración de sitios web de ASP.NET, que es una aplicación local de ASP.NET diseñada para ayudar a ver y administrar la configuración de la aplicación web. Sin embargo, no soy un gran fan de la herramienta de administración de sitios web de ASP.NET por dos razones. En primer lugar, tiene algunos fallos y la experiencia de usuario deja mucho que desear. En segundo lugar, la herramienta de administración de sitios web de ASP.NET está diseñada para funcionar solo localmente, lo que significa que tendrá que crear sus propias páginas web de administración de roles si necesita administrar roles en un sitio activo de forma remota. Por estos dos motivos, este tutorial y el siguiente se centrarán en la creación de las herramientas de administración de roles necesarias en una página web en lugar de confiar en la herramienta de administración de sitios web de ASP.NET.

Abra la página ManageRoles.aspx en la carpeta Roles y agregue un control TextBox y un control Web Button a la página. Establezca la propiedad ID del control TextBox en RoleName y las propiedades ID y Text del botón en CreateRoleButton y Crear rol, respectivamente. En este momento, el marcado declarativo de la página debe tener un aspecto similar al siguiente:

<b>Create a New Role: </b>
<asp:TextBox ID="RoleName" runat="server"></asp:TextBox>
<br />
<asp:Button ID="CreateRoleButton" runat="server" Text="Create Role" />

A continuación, haga doble clic en el control de botón CreateRoleButton en el Diseñador para crear un controlador de eventos Click y agregue el código siguiente:

protected void CreateRoleButton_Click(object sender, EventArgs e)
{
    string newRoleName = RoleName.Text.Trim();

    if (!Roles.RoleExists(newRoleName))
        // Create the role
        Roles.CreateRole(newRoleName);

    RoleName.Text = string.Empty;
}

El código anterior comienza asignando el nombre de rol recortado especificado en el TextBox RoleName a la variable newRoleName. A continuación, se llama al método RoleExists de la clase Roles para determinar si el rol newRoleName ya existe en el sistema. Si el rol no existe, se crea a través de una llamada al método CreateRole. Si el método CreateRole se pasa un nombre de rol que ya existe en el sistema, se produce una excepción ProviderException. Este es el motivo por el que el código comprueba primero para asegurarse de que el rol aún no existe en el sistema antes de llamar a CreateRole. El controlador de eventos Click concluye borrando la propiedad Text de TextBox RoleName.

Nota:

Es posible que se pregunte qué ocurrirá si el usuario no escribe ningún valor en el TextBox RoleName. Si el valor pasado al método CreateRole es null o una cadena vacía, se genera una excepción. Del mismo modo, si el nombre del rol contiene una coma, se genera una excepción. Por lo tanto, la página debe contener controles de validación para asegurarse de que el usuario entra en un rol y que no contiene ninguna coma. Lo dejo como ejercicio para el lector.

Vamos a crear un rol denominado Administradores. Visite la página ManageRoles.aspx a través de un explorador, escriba Administradores en el cuadro de texto (véase la ilustración 3) y, a continuación, haga clic en el botón Crear rol.

Create an Administrators Role

Ilustración 3: crear un rol Administradores (haga clic para ver la imagen a tamaño completo)

¿Qué sucede? Se produce un postback, pero no hay ninguna indicación visual de que el rol se ha agregado realmente al sistema. Actualizaremos esta página en el paso 5 para incluir comentarios visuales. Por ahora, sin embargo, puede comprobar que el rol se ha creado si va a la base de datos SecurityTutorials.mdf y muestra los datos de la tabla aspnet_Roles. Como se muestra en la ilustración 4, la tabla aspnet_Roles contiene un registro para los roles Administradores recién agregados.

The aspnet_Roles Table has a Row for the Administrators

Ilustración 4: la tabla aspnet_Roles tiene una fila para los Administradores (haga clic para ver la imagen a tamaño completo)

Paso 5: mostrar los roles en el sistema

Vamos a aumentar la página ManageRoles.aspx para incluir una lista de los roles actuales en el sistema. Para ello, agregue un control GridView a la página y establezca su propiedad ID en RoleList. A continuación, agregue un método a la clase de código subyacente de la página denominada DisplayRolesInGrid con el código siguiente:

private void DisplayRolesInGrid()
{
    RoleList.DataSource = Roles.GetAllRoles();
    RoleList.DataBind();
}

El método GetAllRoles de la clase Roles devuelve todos los roles del sistema como una matriz de cadenas. Esta matriz de cadenas se enlaza a GridView. Para enlazar la lista de roles a GridView cuando la página se carga por primera vez, es necesario llamar al método DisplayRolesInGrid desde el controlador de eventos Page_Load de la página. El siguiente código llama a este método cuando se visita la página por primera vez, pero no en postbacks posteriores.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    DisplayRolesInGrid();
}

Con este código en su lugar, visite la página a través de un explorador. Como se muestra en la ilustración 5, debería ver una cuadrícula con una sola columna con la etiqueta Item. La cuadrícula incluye una fila para el rol Administradores que hemos agregado en el paso 4.

The GridView Displays the Roles in a Single Column

Ilustración 5: GridView muestra los roles en una sola columna (haga clic para ver la imagen a tamaño completo)

GridView muestra una columna de carril etiquetada Item porque la propiedad AutoGenerateColumns de GridView está establecida en True (valor predeterminado), lo que hace que GridView cree automáticamente una columna para cada propiedad en su DataSource. Un array tiene una única propiedad que representa los elementos del array, de ahí la única columna del GridView.

Al mostrar datos con GridView, prefiero definir explícitamente mis columnas en lugar de generarlas implícitamente mediante GridView. Al definir explícitamente las columnas, es mucho más fácil dar formato a los datos, reorganizar las columnas y realizar otras tareas comunes. Por lo tanto, vamos a actualizar el marcado declarativo de GridView para que sus columnas se definan explícitamente.

Comience estableciendo la propiedad AutoGenerateColumns de GridView en False. A continuación, agregue un TemplateField a la cuadrícula, establezca su propiedad HeaderText en roles y configure su ItemTemplate para que muestre el contenido de la matriz. Para ello, agregue un control web Label denominado RoleNameLabel al ItemTemplate y enlace su propiedad Text a Container.DataItem.

Estas propiedades y el contenido de ItemTemplate se pueden establecer declarativamente o a través del cuadro de diálogo Campos de GridView y la interfaz Editar plantillas. Para llegar al cuadro de diálogo Campos, haga clic en el vínculo Editar columnas de la etiqueta inteligente de GridView. A continuación, desactive la casilla Generar campos automáticamente para establecer la propiedad AutoGenerateColumns en False y agregar un TemplateField a GridView, estableciendo su propiedad HeaderText en Rol. Para definir el contenido de ItemTemplate, elija la opción Editar plantillas de la etiqueta inteligente de GridView. Arrastre un control web Label al ItemTemplate, establezca su propiedad ID en RoleNameLabel y configure sus valores de enlace de datos para que su propiedad Text esté enlazada a Container.DataItem.

Independientemente del enfoque que use, el marcado declarativo resultante de GridView debe ser similar al siguiente cuando haya terminado.

<asp:GridView ID="RoleList" runat="server" AutoGenerateColumns="false">    
 <Columns>    
 <asp:TemplateField HeaderText="Role">    
 <ItemTemplate>    
 <asp:Label runat="server" ID="RoleNameLabel" Text='<%# Container.DataItem %>' />    
 </ItemTemplate>    
 </asp:TemplateField>    
 </Columns>    
</asp:GridView>

Nota:

El contenido de la matriz se muestra mediante la sintaxis de enlace de datos <%# Container.DataItem %>. Una descripción exhaustiva de por qué se usa esta sintaxis al mostrar el contenido de una matriz enlazada a GridView está fuera del ámbito de este tutorial. Para obtener más información sobre este asunto, consulte Enlace de una matriz escalar a un control web de datos.

Actualmente, el GridView RoleList solo está enlazado a la lista de roles cuando se visita la página por primera vez. Es necesario actualizar la cuadrícula cada vez que se agrega un nuevo rol. Para ello, actualice el controlador de eventos Click del botón CreateRoleButton para que llame al método DisplayRolesInGrid si se crea un nuevo rol.

protected void CreateRoleButton_Click(object sender, EventArgs e)    
{    
    string newRoleName = RoleName.Text.Trim();

    if (!Roles.RoleExists(newRoleName))    
    {    
        // Create the role    
        Roles.CreateRole(newRoleName);

        // Refresh the RoleList Grid    
        DisplayRolesInGrid();    
    }

    RoleName.Text = string.Empty;    
}

Ahora, cuando el usuario agrega un nuevo rol, el RoleList GridView muestra el rol recién agregado en postback, proporcionando comentarios visuales de que el rol se creó correctamente. Para ilustrar esto, visite la página ManageRoles.aspx a través de un explorador y agregue un rol denominado Supervisores. Al hacer clic en el botón Crear rol, se producirá una devolución de entrada y la cuadrícula se actualizará para incluir Administradores, así como el nuevo rol, Supervisores.

The Supervisors Role has Been Added

Ilustración 6: se ha agregado el rol Supervisores (Haga clic para ver la imagen a tamaño completo)

Paso 6: eliminación de roles

En este momento, un usuario puede crear un nuevo rol y ver todos los roles existentes desde la página ManageRoles.aspx. Vamos a permitir que los usuarios también eliminen roles. El método Roles.DeleteRole tiene dos sobrecargas:

  • DeleteRole(roleName): elimina el rol roleName. Se produce una excepción si el rol contiene uno o varios miembros.
  • DeleteRole(roleName, throwOnPopulatedRole): elimina el rol roleName. Si throwOnPopulateRole es true, se produce una excepción si el rol contiene uno o varios miembros. Si throwOnPopulateRole es false, el rol se elimina tanto si contiene miembros como si no. Internamente, el método DeleteRole(roleName) llama a DeleteRole(roleName, true).

El método DeleteRole también producirá una excepción si roleName es null o una cadena vacía o si roleName contiene una coma. Si roleName no existe en el sistema, DeleteRole produce un error en modo silencioso, sin generar una excepción.

Vamos a aumentar GridView en ManageRoles.aspx para incluir un botón Eliminar que, al hacer clic en ellos, elimina el rol seleccionado. Para empezar, agregue un botón Eliminar a GridView; para ello, vaya al cuadro de diálogo Campos y agregue un botón Eliminar, que se encuentra en la opción CommandField. Convierta el botón Eliminar en la columna izquierda y establezca su propiedad DeleteText en Eliminar rol .

Add a Delete Button to the RoleList GridView

Ilustración 7: agregar un botón Eliminar al GridView RoleList(Haga clic para ver la imagen a tamaño completo)

Después de agregar el botón Eliminar, el marcado declarativo de GridView debe ser similar al siguiente:

<asp:GridView ID="RoleList" runat="server" AutoGenerateColumns="False">
 <Columns>
 <asp:CommandField DeleteText="Delete Role" ShowDeleteButton="True"/>
 <asp:TemplateField HeaderText="Role">
 <ItemTemplate>
 <asp:Label runat="server" ID="RoleNameLabel" Text='<%# Container.DataItem %>' />
 </ItemTemplate>
 </asp:TemplateField>
 </Columns>
</asp:GridView>

A continuación, cree un controlador de eventos para el evento RowDeleting de GridView. Este es el evento que se genera en postback cuando se hace clic en el botón Eliminar rol. Agregue el código siguiente al controlador de eventos .

protected void RoleList_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
    // Get the RoleNameLabel
    Label RoleNameLabel = RoleList.Rows[e.RowIndex].FindControl("RoleNameLabel") as Label;

    // Delete the role
    Roles.DeleteRole(RoleNameLabel.Text, false);

    // Rebind the data to the RoleList grid
    DisplayRolesInGrid();
}

El código comienza haciendo referencia mediante programación al control web RoleNameLabel de la fila en la que se ha hecho clic en el botón Eliminar función. A continuación, se invoca el método Roles.DeleteRole, pasando el Text del RoleNameLabel y false, eliminando así el rol independientemente de si hay usuarios asociados al rol. Por último, el GridView RoleList se actualiza para que el rol recién eliminado ya no aparezca en la cuadrícula.

Nota:

El botón Eliminar rol no requiere ninguna confirmación del usuario antes de eliminar el rol. 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.

Resumen

Muchas aplicaciones web tienen ciertas reglas de autorización o funcionalidad de nivel de página que solo está disponible para determinadas clases de usuarios. Por ejemplo, puede haber un conjunto de páginas web a las que solo pueden acceder los administradores. En lugar de definir estas reglas de autorización por usuario, a menudo resulta más útil definir las reglas basadas en un rol. Es decir, en lugar de permitir explícitamente que los usuarios Scott y Jisun accedan a las páginas web administrativas, un enfoque más fácil de mantener es permitir que los miembros del rol Administradores accedan a estas páginas y, a continuación, denotan a Scott y Jisun como usuarios que pertenecen al rol Administradores.

El marco roles facilita la creación y administración de roles. En este tutorial se ha examinado cómo configurar el marco roles para usar el SqlRoleProvider, que usa una base de datos de Microsoft SQL Server como almacén de roles. También hemos creado una página web que enumera los roles existentes en el sistema y permite que se creen nuevos roles y se eliminen los existentes. En los tutoriales posteriores veremos cómo asignar usuarios a roles y cómo aplicar la autorización basada en roles.

¡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, entrenador 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

Esta serie de tutoriales fue revisada por muchos revisores que fueron de gran ayuda. Los revisores principales de este tutorial son Alicja Maziarz, 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