Migración de la autenticación de pertenencia de ASP.NET a ASP.NET Core 2.0 Identity
Por Isaac Levin
En este artículo se muestra cómo migrar el esquema de base de datos para ASP.NET aplicaciones mediante la autenticación de pertenencia a ASP.NET Core 2.0 Identity.
Nota
En este documento se proporcionan los pasos necesarios para migrar el esquema de base de datos para ASP.NET aplicaciones basadas en pertenencia al esquema de base de datos usado para ASP.NET Core Identity. Para obtener más información sobre la migración de la autenticación basada en membresía de ASP.NET a ASP.NET Identity, consulte Migración de una aplicación existente de Membresía de SQL a ASP.NET Identity. Para obtener más información sobre ASP.NET Core Identity, consulte Introducción a Identity en ASP.NET Core.
Antes de ASP.NET 2.0, a los desarrolladores se les encargaba crear todo el proceso de autenticación y autorización para sus aplicaciones. Con ASP.NET 2.0, se introdujo la pertenencia, proporcionando una solución reutilizable para controlar la seguridad dentro de las aplicaciones de ASP.NET. Los desarrolladores ahora podían iniciar un esquema en una base de datos de SQL Server con la herramienta de registro de ASP.NET SQL Server (Aspnet_regsql.exe
) (ya no se admite). Después de ejecutar este comando, se crearon las tablas siguientes en la base de datos.
Para migrar aplicaciones existentes a ASP.NET Core 2.0 Identity, los datos de estas tablas deben migrarse a las tablas que usa el nuevo esquema Identity.
ASP.NET Core 2.0 se rige por el Identity principio introducido en ASP.NET 4.5. Aunque el principio se comparte, la implementación entre los marcos es diferente, incluso entre las versiones de ASP.NET Core (consulte Migración de autenticación y de Identity a ASP.NET Core 2.0).
La forma más rápida de ver el esquema de ASP.NET Core 2.0 Identity es crear una nueva aplicación de ASP.NET Core 2.0. Siga estos pasos en Visual Studio 2017:
Seleccione Archivo>Nuevo>Proyecto.
Crea un nuevo proyecto de aplicación web de ASP.NET Core denominado CoreIdentitySample.
Seleccione ASP.NET Core 2.0 en la lista desplegable y, luego, Aplicación web. Esta plantilla genera una aplicación de Razor Pages. Antes de hacer clic en Aceptar, haga clic en Cambiar Autenticación.
Elija Cuentas de usuario individuales para las plantillas de Identity. Por último, haga clic en Aceptar y, a continuación, en Aceptar. Visual Studio crea un proyecto mediante la plantilla ASP.NET Core Identity .
Seleccione Herramientas>Administrador de paquetes NuGet>Consola del administrador de paquetes para abrir la ventana de la Consola del administrador de paquetes (PMC).
Vaya a la raíz del proyecto en la PMC y ejecute el comando
Update-Database
de Entity Framework (EF) Core.ASP.NET Core 2.0 Identity usa EF Core para interactuar con la base de datos que almacena los datos de autenticación. Para que la aplicación recién creada funcione, debe haber una base de datos para almacenar estos datos. Después de crear una nueva aplicación, la forma más rápida de inspeccionar el esquema en un entorno de base de datos es crear la base de datos mediante EF Core Migraciones. Este proceso crea una base de datos, ya sea localmente o en otro lugar, que imita ese esquema. Revise la documentación anterior para obtener más información.
Los comandos EF Core usan la cadena de conexión para la base de datos especificada en
appsettings.json
. La siguiente cadena de conexión tiene como destino una base de datos en localhost denominada asp-net-core-identity. En esta configuración, EF Core se establece para usar la cadena de conexiónDefaultConnection
.{ "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=aspnet-core-identity;Trusted_Connection=True;MultipleActiveResultSets=true" } }
Advertencia
En este artículo se muestra el uso de cadena de conexión. Con una base de datos local, el usuario no tiene que autenticarse, pero en producción, cadena de conexión a veces incluye una contraseña para autenticarse. Una credencial de contraseña de propietario de recursos (ROPC) es un riesgo de seguridad que se debe evitar en las bases de datos de producción. Las aplicaciones de producción deben usar el flujo de autenticación más seguro disponible. Para obtener más información sobre la autenticación de aplicaciones implementadas para probar o entornos de producción, consulte Flujos de autenticación seguros.
Seleccione Ver>Explorador de objetos de SQL Server. Expanda el nodo correspondiente al nombre de la base de datos especificado en la propiedad
ConnectionStrings:DefaultConnection
deappsettings.json
.El comando
Update-Database
creó la base de datos especificada con el esquema y los datos necesarios para la inicialización de la aplicación. En la imagen siguiente se muestra la estructura de tabla que se crea con los pasos anteriores.
Existen diferencias sutiles en las estructuras de tabla y los campos de pertenencia y ASP.NET Core Identity. El patrón ha cambiado sustancialmente para la autenticación y autorización con ASP.NET y ASP.NET Core aplicaciones. Los objetos clave que todavía se usan con Identity son Usuarios y Roles. Estas son las tablas de asignación para Usuarios, Roles y UserRoles.
Identity Columna ( dbo.AspNetUsers ) |
Tipo | Membership Columna ( dbo.aspnet_Users / dbo.aspnet_Membership ) |
Tipo |
---|---|---|---|
Id |
string |
aspnet_Users.UserId |
string |
UserName |
string |
aspnet_Users.UserName |
string |
Email |
string |
aspnet_Membership.Email |
string |
NormalizedUserName |
string |
aspnet_Users.LoweredUserName |
string |
NormalizedEmail |
string |
aspnet_Membership.LoweredEmail |
string |
PhoneNumber |
string |
aspnet_Users.MobileAlias |
string |
LockoutEnabled |
bit |
aspnet_Membership.IsLockedOut |
bit |
IsLockedOut
no se asigna a LockoutEnabled
. IsLockedOut
se establece si un usuario tuvo demasiados inicios de sesión fallidos y se bloquea durante un tiempo determinado. LockoutEnabled
permite bloquear a un usuario con demasiados intentos fallidos de inicio de sesión. Cuando el usuario tiene demasiados intentos de inicio de sesión erróneos, LockoutEnd
se establece en una fecha en el futuro y el usuario no puede iniciar sesión hasta esa fecha. Si LockoutEnabled
es FALSE, el usuario nunca se bloquea para demasiados intentos de inicio de sesión erróneos. Según OWASP, el bloqueo temporal de la cuenta después de varios intentos fallidos es un objetivo demasiado simple para los ataques DoS contra usuarios legítimos.
Para obtener más información sobre el bloqueo, consulte Pruebas OWASP para el mecanismo de bloqueo débil.
Las aplicaciones que migren a Identity que deseen habilitar el bloqueo de inicio de sesión fallido deben establecer LockoutEnabled
en TRUE como parte de la migración.
Nota
No todas las asignaciones de campos se asemejan a las relaciones uno a uno de pertenencia a ASP.NET Core Identity. La tabla anterior toma el esquema de usuario de pertenencia predeterminado y lo asigna al esquema de ASP.NET Core Identity . Cualquier otro campo personalizado que se usó para la pertenencia debe asignarse manualmente. En esta asignación, no hay ningún mapa para las contraseñas, ya que los criterios de contraseña y las sales de contraseña no se migran entre los dos. Se recomienda dejar la contraseña como null y pedir a los usuarios que restablezcan sus contraseñas. En ASP.NET Core Identity, LockoutEnd
debe establecerse en alguna fecha en el futuro si el usuario está bloqueado. Esto se muestra en el script de migración.
Identity Columna ( dbo.AspNetRoles ) |
Tipo | Membership Columna ( dbo.aspnet_Roles ) |
Tipo |
---|---|---|---|
Id |
string |
RoleId |
string |
Name |
string |
RoleName |
string |
NormalizedName |
string |
LoweredRoleName |
string |
Identity Columna ( dbo.AspNetUserRoles ) |
Tipo | Membership Columna ( dbo.aspnet_UsersInRoles ) |
Tipo |
---|---|---|---|
RoleId |
string |
RoleId |
string |
UserId |
string |
UserId |
string |
Haga referencia a las tablas de asignación anteriores al crear un script de migración para Usuarios y Roles. En el ejemplo siguiente se supone que tiene dos bases de datos en un servidor de bases de datos. Una base de datos contiene los datos y el esquema de pertenencia de ASP.NET existentes. La otra base de datos CoreIdentitySample se creó siguiendo los pasos descritos anteriormente. Los comentarios se incluyen en línea para obtener más detalles.
-- THIS SCRIPT NEEDS TO RUN FROM THE CONTEXT OF THE MEMBERSHIP DB
BEGIN TRANSACTION MigrateUsersAndRoles
USE aspnetdb
-- INSERT USERS
INSERT INTO CoreIdentitySample.dbo.AspNetUsers
(Id,
UserName,
NormalizedUserName,
PasswordHash,
SecurityStamp,
EmailConfirmed,
PhoneNumber,
PhoneNumberConfirmed,
TwoFactorEnabled,
LockoutEnd,
LockoutEnabled,
AccessFailedCount,
Email,
NormalizedEmail)
SELECT aspnet_Users.UserId,
aspnet_Users.UserName,
-- The NormalizedUserName value is upper case in ASP.NET Core Identity
UPPER(aspnet_Users.UserName),
-- Creates an empty password since passwords don't map between the 2 schemas
'',
/*
The SecurityStamp token is used to verify the state of an account and
is subject to change at any time. It should be initialized as a new ID.
*/
NewID(),
/*
EmailConfirmed is set when a new user is created and confirmed via email.
Users must have this set during migration to reset passwords.
*/
1,
aspnet_Users.MobileAlias,
CASE
WHEN aspnet_Users.MobileAlias IS NULL THEN 0
ELSE 1
END,
-- 2FA likely wasn't setup in Membership for users, so setting as false.
0,
CASE
-- Setting lockout date to time in the future (1,000 years)
WHEN aspnet_Membership.IsLockedOut = 1 THEN Dateadd(year, 1000,
Sysutcdatetime())
ELSE NULL
END,
aspnet_Membership.IsLockedOut,
/*
AccessFailedAccount is used to track failed logins. This is stored in
Membership in multiple columns. Setting to 0 arbitrarily.
*/
0,
aspnet_Membership.Email,
-- The NormalizedEmail value is upper case in ASP.NET Core Identity
UPPER(aspnet_Membership.Email)
FROM aspnet_Users
LEFT OUTER JOIN aspnet_Membership
ON aspnet_Membership.ApplicationId =
aspnet_Users.ApplicationId
AND aspnet_Users.UserId = aspnet_Membership.UserId
LEFT OUTER JOIN CoreIdentitySample.dbo.AspNetUsers
ON aspnet_Membership.UserId = AspNetUsers.Id
WHERE AspNetUsers.Id IS NULL
-- INSERT ROLES
INSERT INTO CoreIdentitySample.dbo.AspNetRoles(Id, Name)
SELECT RoleId, RoleName
FROM aspnet_Roles;
-- INSERT USER ROLES
INSERT INTO CoreIdentitySample.dbo.AspNetUserRoles(UserId, RoleId)
SELECT UserId, RoleId
FROM aspnet_UsersInRoles;
IF @@ERROR <> 0
BEGIN
ROLLBACK TRANSACTION MigrateUsersAndRoles
RETURN
END
COMMIT TRANSACTION MigrateUsersAndRoles
Después de completar el script anterior, la aplicación ASP.NET Core Identity creada anteriormente se rellena con usuarios de pertenencia. Los usuarios deben cambiar sus contraseñas antes de iniciar sesión.
Nota
Si el sistema de pertenencia tenía usuarios con nombres de usuario que no coincidieron con su dirección de correo electrónico, se requieren cambios en la aplicación creada anteriormente para dar cabida a esto. La plantilla predeterminada espera que UserName
y Email
sean los mismos. Para situaciones en las que son diferentes, el proceso de inicio de sesión debe modificarse para usar UserName
en lugar de Email
.
En PageModel
de la página de inicio de sesión, ubicado en, quite el atributo [EmailAddress]
de la propiedad Email. Cambie el nombre a UserName. Esto requiere un cambio dondequiera que se mencione EmailAddress
, en la Vista y en PageModel. El resultado será similar al siguiente:
En este tutorial, ha aprendido a migrar usuarios de la pertenencia de SQL a ASP.NET Core 2.0 Identity. Para obtener más información sobre ASP.NET Core Identity, consulte Introducción a Identity.
Comentarios de ASP.NET Core
ASP.NET Core es un proyecto de código abierto. Seleccione un vínculo para proporcionar comentarios: