Autor: Willmove && Heath Stewart
Página de inicio: http://www.amuhouse.com
Correo electrónico: [email protected]
Nota: Aprendí ASP.NET hace dos meses. Vi un artículo titulado Seguridad basada en roles con autenticación de formularios en codeproject.com y lo encontré muy útil. En ese momento quise traducirlo al chino. Sin embargo, la traducción directa es realmente aburrida. En los últimos dos días, me referí a este artículo de Heath Stewart y, según mi propio entendimiento, lo escribí al chino de acuerdo con mis propias ideas y expresiones. Adjunto se encuentra una aplicación web de demostración que hice para este artículo.
Si hay algún malentendido, por favor escríbanos para señalarlo o deje un comentario.
P.D. El spam es realmente molesto, muestren su respeto.
El artículo original está en http://www.codeproject.com/aspnet/formsroleauth.asp
Autor originalHeath Stewart
resumen:
ASP.NET proporciona un mecanismo de autenticación basado en roles, pero su soporte para roles es incompleto. Este artículo intenta ilustrar cómo implementar y utilizar este mecanismo de autenticación basado en roles a través de algunos ejemplos.
Introducción:
la autenticación de formularios en ASP.NET es una característica muy poderosa que requiere solo una pequeña cantidad de código para implementar un sistema de autenticación de seguridad simple e independiente de la plataforma.
Sin embargo, si necesita un mecanismo de autenticación más complejo y eficiente, deberá aprovechar su flexibilidad dividiendo muchos usuarios en grupos de usuarios. La autenticación integrada de Windows proporciona este mecanismo de autenticación, pero utiliza NTLM, el administrador LAN de Windows NT, por lo que no es multiplataforma. Ahora cada vez más personas utilizan sistemas Linux y cada vez hay más usuarios del navegador Mozilla Forefox. Ciertamente no podemos mantener a estas personas fuera, por lo que estamos buscando otro mecanismo de autenticación. Hay dos opciones: una es dividir el sitio web en múltiples áreas y proporcionar múltiples páginas de inicio de sesión, lo que obliga a los usuarios a registrarse e iniciar sesión uno por uno, la otra es agrupar a los usuarios y restringir los derechos de acceso de grupos de usuarios específicos a una determinada página; o zona. Esta última es sin duda la mejor opción. Podemos lograr esta funcionalidad asignando roles a usuarios individuales.
Microsoft dejó el mecanismo de autenticación basado en roles en la autenticación de formularios para la plataforma .NET, pero tenemos que implementarlo nosotros mismos. Este artículo se esfuerza por cubrir algunos aspectos básicos sobre el mecanismo de autenticación basado en roles en la autenticación de formularios, como su concepto, su implementación, cómo aplicarlo en aplicaciones web, etc.
Preparación necesaria:
Primero necesitamos crear una base de datos, un proyecto de aplicación web, varios directorios confidenciales con diferentes niveles de seguridad y varias páginas ASP.NET. Por supuesto, también puede agregarlos a su proyecto de aplicación web existente.
1. Para crear una base de datos,
primero debe elegir el sistema de gestión de bases de datos DBMS que desea utilizar. Este artículo utiliza SQL Server 2000.
En la base de datos de proyectos de aplicaciones reales, generalmente hay una tabla de datos de usuario Usuarios, que puede incluir la etiqueta única del usuario: ID de usuario, nombre de usuario: Nombre de usuario, contraseña: Contraseña, dirección de correo electrónico del usuario: Correo electrónico, ciudad del usuario: Ciudad y el número de inicios de sesión de usuarios LoginCount, etc. Puede asignar roles a los usuarios creando una tabla de datos UserInRoles (que generalmente incluye dos campos, nombre de usuario: UserName, rol de usuario: UserRoles).
En aras de la simplicidad, solo creo una tabla de datos de Usuarios, que tiene 3 campos, nombre de usuario Nombre de usuario, contraseña Contraseña y roles de usuario UserRoles. Antes de crear una tabla, debe seleccionar una base de datos o crear una nueva base de datos. Para crear una nueva base de datos denominada WebSolution, sólo se requiere una simple declaración SQL:
código de programa
Crear solución web de BASE DE DATOS
Para seleccionar una base de datos llamada msdb
en GO
, puede usar la declaración SQL:
código de programa
USAR msdb
IR
A continuación, creamos la tabla de datos de Usuarios que acabamos de mencionar. El script SQL es el siguiente:
Código del programa
Crear TABLA de Usuarios.
(
Nombre de usuario nvarchar(100) RESTRICCIÓN PK_Nombre de usuario CLAVE PRIMARIA,
Contraseña nvarchar(150),
Roles de usuario nvarchar(100)
)
puede crear credenciales de índice para esta tabla. La declaración SQL es la siguiente:
Código de programa
Crear credenciales de ÍNDICE para los usuarios.
(
Nombre de usuario,
Contraseña
)
Crear un índice es opcional y depende de usted. Consulte la información relevante para conocer los beneficios y desventajas de la indexación.
Luego agregamos datos a esta base de datos de Usuarios. El nombre del personaje es de tu elección, pero es mejor usar un nombre significativo, como
"Administrador" (administrador de nivel superior), "Administrador" (administrador), "Miembro" (miembro unido), "Usuario" (usuario normal), etc. Por ejemplo:
Nombre de usuario|Contraseña|Roles
"willmove"|"pwd123"|"Administrador,Usuario"
"amuhouse"|"pwd123"|"Usuario"
es:
código de programa
.Tenga en cuenta que '45CB41B32DCFB917CCD8614F1536D6DA' es una cadena cifrada por md5 usando 'pwd123'
Insertar EN Usuarios (Nombre de usuario, Contraseña, Funciones de usuario) VALORES ('willmove','45CB41B32DCFB917CCD8614F1536D6DA','Administrador,Usuario')
IR
Insertar EN Usuarios (Nombre de usuario, Contraseña, Funciones de usuario) VALORES ('amuhouse','45CB41B32DCFB917CCD8614F1536D6DA','Usuario')
IR
Tenga en cuenta que los roles distinguen entre mayúsculas y minúsculas porque lo hacen en el archivo Web.config. Ahora creamos varias páginas necesarias para implementar este mecanismo de autenticación de seguridad.
La primera es la página de inicio de sesión del usuario Login.aspx.
Si aún no ha creado una aplicación web, cree una ahora. Por supuesto, también puede crear esta página en una aplicación web existente. Aquí asumo que se ha creado una aplicación web llamada RolebasedAuth (es decir, Proyecto en Visual Studio .Net). Puse este Login.aspx en su directorio raíz, al que se puede acceder a través de http://localhost/RolebasedAuth/Login.aspx .
No importa dónde se coloque este Login.aspx, pero debe ser accesible al público.
En la ruta raíz de la aplicación, creamos dos subdirectorios secretos, a saber, Administrador y Usuario.
A continuación, creamos un sistema de inicio de sesión de autenticación de formularios que admita la autenticación de roles. Debido a que Microsoft no proporciona un mecanismo de implementación simple, debemos dedicar algún tiempo a crear el ticket de autenticación nosotros mismos. Necesita almacenar una pequeña cantidad de información. Por supuesto, algunos nombres deben ser los mismos que los configurados en Web.config; de lo contrario, ASP.NET pensará que su ticket de autenticación no es válido y lo obligará a redirigir a la página de inicio de sesión. Agregamos dos controles TextBox a Login.aspx en VS.NET y los llamamos UserNameTextBox y PasswordTextBox. También agregamos un botón y lo llamamos LoginButton. Haga clic en él para ingresar el código de fondo. Agregue el código requerido en el método LoginButton_Click. como sigue:
código de programa
privado vacío LoginButton_Click (remitente del objeto, System.EventArgs e)
{
//Inicializar autenticación de formularios
// Tenga en cuenta que está en el espacio de nombres System.Web.Security
// Entonces agrega usando System.Web.Security al principio del código.
FormsAuthentication.Initialize ();
// Crear conexión de base de datos y objetos de comando de operación de base de datos
// Tenga en cuenta que está en el espacio de nombres System.Data.SqlClient
// Entonces agrega usando System.Data.SqlClient;
Conexión SqlConnection =
new SqlConnection("Fuente de datos=sun-willmove;seguridad integrada=SSPI;Catálogo inicial=Solución web;");
SqlCommand cmd = conexión.CreateCommand();
cmd.CommandText = "Seleccione UserRoles DE Usuarios donde Nombre de usuario = @ nombre de usuario " +
"Y Contraseña=@contraseña ";
//Completa cada parámetro
cmd.Parameters.Add("@nombredeusuario", SqlDbType.NVarChar, 100).Value =
NombreDeUsuarioTextBox.Texto;
cmd.Parameters.Add("@contraseña", SqlDbType.NVarChar, 150).Value =
FormsAuthentication.HashPasswordForStoringInConfigFile(
PasswordTextBox.Text, "md5"); // o "sha1"
// Ejecutar el comando de operación de la base de datos
conexión.Open();
Lector SqlDataReader = cmd.ExecuteReader();
si (lector.Read())
{
// Para implementar la autenticación, crea un nuevo ticket
Boleto FormsAuthenticationTicket = nuevo FormsAuthenticationTicket(
1, // Número de versión del ticket
UserNameTextBox.Text, // Titular del billete
DateTime.Now, //Hora de asignar tickets
DateTime.Now.AddMinutes(30), //Hora de caducidad
verdadero, //requiere la cookie del usuario
lector.GetString(0), // Datos del usuario, aquí está en realidad el rol del usuario
FormsAuthentication.FormsCookiePath);//Ruta de cookie válida
//Utilice la clave de máquina del código de máquina para cifrar las cookies para una transmisión segura
hash de cadena = FormsAuthentication.Encrypt(boleto);
Cookie HttpCookie = nueva HttpCookie(
FormsAuthentication.FormsCookieName, // El nombre de la cookie de autenticación
hash); //Cookie cifrada
//Establece el tiempo de vencimiento de la cookie para que sea consistente con el tiempo de vencimiento de los tickets
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration
//Agregar cookies a la respuesta de la solicitud de página
;
Response.Cookies.Add(cookie);
//Redirecciona al usuario a la página solicitada anteriormente,
// Si no se ha solicitado ninguna página antes, redirige a la página de inicio
cadena returnUrl = Request.QueryString["ReturnUrl"];
if (returnUrl == null) returnUrl = "./";
// No llame al método FormsAuthentication.RedirectFromLoginPage.
// Porque reemplazará el ticket (cookie) recién agregado
Respuesta.Redirect(returnUrl);
}
demás
{
// No le digas al usuario "La contraseña es incorrecta", esto equivale a darle una oportunidad al intruso.
// Porque saben que el nombre de usuario que ingresaron existe
//
ErrorLabel.Text = "El nombre de usuario o la contraseña son incorrectos, ¡inténtelo de nuevo!";
ErrorLabel.Visible = verdadero;
}
lector.Cerrar();
conexión.Cerrar();
}
El código de la página aspx del front-end es el siguiente:
código de programa
<%@ Idioma de página="c#" Codebehind="Login.aspx.cs" AutoEventWireup="false" Inherits="RolebasedAuth.Login" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transicional//ES" >
<HTML>
<CABEZA>
<título>Iniciar sesión</título>
<meta nombre="GENERADOR" Contenido="Microsoft Visual Studio .NET 7.1">
<meta nombre="CODE_LANGUAGE" Contenido="C#">
<meta nombre="vs_defaultClientScript" contenido="JavaScript">
<meta nombre="vs_targetSchema" content=" http://schemas.microsoft.com/intellisense/ie5 ">
</CABEZA>
<cuerpo>
<id de formulario="Form1" método="publicación" runat="servidor">
<P>
<asp:Label id="Label1" runat="servidor">Nombre de usuario:</asp:Label>
<asp:TextBox id="UserNameTextBox" runat="servidor"></asp:TextBox></P>
<P><FONT face="宋体"> </FONT>
<asp:Label id="Label2" runat="servidor">Contraseña:</asp:Label>
<asp:TextBox id="ContraseñaTextBox" runat="servidor" TextMode="Contraseña"></asp:TextBox></P>
<P>
<asp:Label id="ErrorLabel" runat="servidor" Visible="False"></asp:Label></P>
<P>
<asp:Button id="LoginButton" runat="servidor" Text="Iniciar sesión"></asp:Button></P>
</formulario>
</cuerpo>
</HTML>
Notarás lo que hicimos con la contraseña anterior: aplicar hash. El cifrado hash es un algoritmo unidireccional (irreversible) que genera una matriz única de caracteres. Por lo tanto, cambiar el caso de incluso una letra en la contraseña producirá una columna hash completamente diferente. Almacenamos estas contraseñas cifradas en la base de datos, que es más segura. En una aplicación práctica, es posible que desee recuperar la contraseña olvidada de un usuario. Pero el hash es irreversible, por lo que no podrás recuperar la contraseña original. Pero puede cambiar la contraseña del usuario y decirle la contraseña modificada. Si un sitio web puede proporcionarle contraseñas antiguas, entonces debe pensar con claridad: ¡sus datos de usuario no están seguros! De hecho, la mayoría de los sitios web nacionales almacenan directamente las contraseñas de los usuarios en la base de datos sin cifrarlas. Si un hacker tiene éxito, ¡estas cuentas de usuario estarán en peligro!
Sin SSL, su contraseña se transmite en texto claro a través de la red. Puede ser robado durante la transmisión. Cifrar contraseñas en el lado del servidor solo garantiza la seguridad del almacenamiento de contraseñas. Puede encontrar información relacionada con SSL en http://www.versign.com o http://www.thewte.com .
Si no desea almacenar la contraseña encriptada en la base de datos, puede cambiar el código anterior a
FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordTextBox.Text, "md5") se puede cambiar a PasswordTextBox.Text.
A continuación, necesitamos modificar el archivo Global.asax. Si su aplicación web no tiene este archivo, haga clic derecho en el proyecto de la aplicación web y seleccione "Agregar->Agregar nuevo elemento...->Clase de aplicación global". En Global.asax o Global.asax.cs, busque el método (función) llamado Application_AuthenticationRequest. Primero confirme que los espacios de nombres System.Security.Principal y System.Web.Security se hayan incluido o utilizado, y luego modifíquelo El código modificado:
código de programa
void protegido Application_AuthenticateRequest (remitente del objeto, EventArgs e)
{
si (HttpContext.Current.User! = nulo)
{
si (HttpContext.Current.User.Identity.IsAuthenticated)
{
si (HttpContext.Current.User.Identity es FormsIdentity)
{
ID de identidad de formularios =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
// Obtiene los datos del usuario almacenados en el ticket, que en realidad es la función del usuario aquí.
cadena userData = ticket.UserData;
cadena[] roles = userData.Split(',');
HttpContext.Current.User = nuevo GenericPrincipal(id, roles);
}
}
}
}
El ticket de autenticación (nombre de usuario y contraseña) no se almacena como parte de la cookie y no puede serlo ya que los usuarios pueden modificar sus cookies.
De hecho, FormsAuthentication utiliza la clave de su máquina (generalmente en machine.config) para cifrar el ticket (FormsAuthenticationTicket). Usamos UserData para almacenar roles de usuario y generar nuevas credenciales. Una vez que se ha creado la credencial, se agrega al contexto actual (es decir, HttpContext) para que pueda usarse para recuperar la función del usuario.
A continuación, configuramos el directorio secreto (es decir, el "directorio de seguridad", un directorio al que solo usuarios específicos, como los administradores, tienen permiso para acceder). Primero verifique si hay un archivo Web.config en el directorio raíz de su aplicación web. Si no, cree uno. También puede crear un archivo Web.config en su subdirectorio. Por supuesto, este archivo Web.config está restringido (algunos parámetros no se pueden configurar).
Para implementar la autenticación de seguridad, busqueel código del programa
en el nodo <system.web> en el archivo Web.config en el directorio raíz de la aplicación web.
<modo de autenticación="Windows" />, cámbielo a
<modo de autenticación="Formularios">
<nombre de formularios="AMUHOUSE.ASPXAUTH"
loginUrl="Iniciar sesión.aspx"
proteccion="Todos"
ruta="./" />
</autenticación>
<autorización>
<permitir usuarios="*"/>
</authorization>
En el nombre="AMUHOUSE.ASPXAUTH" anterior, el nombre AMUHOUSE.ASPXAUTH es arbitrario. Para controlar los permisos de usuarios o grupos de usuarios, podemos tener dos métodos. Uno es configurar el archivo Web.config en el directorio raíz de la aplicación y el otro es crear un archivo Web.config independiente en el directorio secreto. (Esto último puede ser mejor). Si es lo primero, Web.config debe contener el siguiente contenido (o contenido similar):
código de programa
<configuración>
<sistema.web>
<modo de autenticación="Formularios">
<nombre de formularios="AMUHOUSE.ASPXAUTH"
loginUrl="iniciar sesión.aspx"
proteccion="Todos"
ruta="/"/>
</autenticación>
<autorización>
<permitir usuarios="*"/>
</autorización>
</sistema.web>
<ruta de ubicación="./Admin">
<sistema.web>
<autorización>
<!-- ¡Atención! ¡El orden y caso de las siguientes líneas son muy importantes! -->
<allow roles="Administrador"/>
<denegar usuarios="*"/>
</autorización>
</sistema.web>
</ubicación>
<ruta de ubicación="./Usuario">
<sistema.web>
<autorización>
<!-- ¡Atención! ¡El orden y caso de las siguientes líneas son muy importantes! -->
<permitir roles="Usuario"/>
<denegar usuarios="*"/>
</autorización>
</sistema.web>
</ubicación>
</configuración>
Para que los directorios de las aplicaciones web no dependan entre sí antes y facilitarles cambiarles el nombre o moverlos, puede optar por configurar un archivo Web.config separado en cada subdirectorio de seguridad. Solo necesita configurar el nodo <autorización/>, de la siguiente manera:
código de programa
<configuración>
<sistema.web>
<autorización>
<!-- ¡Atención! ¡El orden y caso de las siguientes líneas son muy importantes! -->
<allow roles="Administrador"/>
<denegar usuarios="*"/>
</autorización>
</sistema.web>
</configuración>
Debe recordarse nuevamente que los roles anteriores distinguen entre mayúsculas y minúsculas. Por conveniencia, también puede modificar lo anterior para:
<allow roles="Administrador,administrador" />
Si desea permitir o denegar el acceso de varios roles a este directorio, puede separarlos con comas, como por ejemplo:
<allow roles="Administrador,Miembro,Usuario" />
<deny users="*" />
En este punto, hemos configurado un mecanismo de autenticación de seguridad basado en roles para el sitio web. Puede compilar su programa primero y luego intentar acceder a un directorio secreto, como http://localhost/RolebasedAuth/Admin , momento en el cual será redirigido a la página de inicio de sesión del usuario. Si inicia sesión correctamente y su rol tiene derechos de acceso a este directorio, regresará a este directorio. Puede haber usuarios (o intrusos) intentando ingresar al directorio confidencial. Podemos usar una sesión para almacenar la cantidad de veces que el usuario ha iniciado sesión. Si el número excede un cierto número, el usuario no podrá iniciar sesión. y se mostrará "¡El sistema ha rechazado su solicitud de inicio de sesión!".
A continuación, analizamos cómo hacer que los controles web muestren contenido diferente según los roles de los usuarios.
A veces es mejor mostrar contenido según la función del usuario, porque probablemente no quieras crear un montón de páginas con mucho contenido duplicado para tantas funciones diferentes (grupos de usuarios). En un sitio de este tipo, pueden coexistir varias cuentas de usuario y las cuentas de usuario pagas pueden acceder a contenido pago adicional. Otro ejemplo es una página que mostrará un botón "Ingresar administrador" que vincula a la página Administrador si el usuario actual tiene la función "Administrador". Implementaremos esta página ahora.
La clase GenericPrincipal que utilizamos anteriormente implementa la interfaz IPincipal. Esta interfaz tiene un método llamado IsInRole() y su parámetro es una cadena. Esta cadena es el rol del usuario que se verificará. Si queremos mostrar contenido a los usuarios registrados cuyo rol es "Administrador", podemos agregar el siguiente código en Page_Load:
Código de programa
si (Usuario.IsInRole("Administrador"))
AdminLink.Visible = true;
El código completo de la página es el siguiente (para simplificar, el código de fondo también está escrito en la página aspx):
código de programa
<html>
<cabeza>
<título>¡Bienvenido! </título>
<script runat="servidor">
Page_Load vacío protegido (remitente del objeto, EventArgs e)
{
si (Usuario.IsInRole("Administrador"))
AdminLink.Visible = verdadero;
demás
AdminLink.Visible = falso;
}
</script>
</cabeza>
<cuerpo>
<h2>¡Bienvenido! </h2>
<p>Bienvenido a Amu House http://amuhouse.com/ ^_^</p>
<asp:HyperLink id="AdminLink" runat="servidor"
Text="Página de inicio del administrador" NavigateUrl="./Admin"/>
</cuerpo>
</html>
De esta manera, el control HyperLink vinculado al directorio de administración solo se mostrará a los usuarios cuyo rol sea Administrador. También puede proporcionar a los usuarios que no han iniciado sesión un enlace a la página de inicio de sesión, como por ejemplo:
código de programa
Page_Load vacío protegido (remitente del objeto, System.EventArgs e)
{
si (Usuario.IsInRole("Administrador"))
{
AdminLink.Text = "Administrador, por favor entre";
AdminLink.NavigateUrl="./Admin";
}
de lo contrario si (Usuario.IsInRole ("Usuario"))
{
AdminLink.Text = "Usuarios registrados por favor ingrese";
AdminLink.NavigateUrl="./Usuario"
;
demás
{
AdminLink.Text = "Inicie sesión";
AdminLink.NavigateUrl="Login.aspx?ReturnUrl=" + Solicitud.Path;
}
}
Aquí, al configurar la variable QueryString llamada ReturnUrl, podemos devolver al usuario a la página actual después de iniciar sesión correctamente.
resumen:
Este artículo se utiliza para ayudarlo a comprender la importancia y la practicidad de los mecanismos de seguridad basados en roles y también utiliza ASP.NET para implementar mecanismos de seguridad basados en roles. No es un mecanismo difícil de implementar, pero puede requerir cierto conocimiento de qué son las credenciales de usuario, cómo autenticar a los usuarios y cómo autenticar a los usuarios autorizados. Estaría muy feliz si lo encontraras útil. Espero que pueda guiarlo en la implementación de la autenticación de seguridad de formularios basada en roles en su sitio web.
Adjunto:
Código fuente del proyecto de muestra para este artículo: