Intercambio de passwords en ASP.NET

A veces para depurar nuestra aplicación necesitamos entrar «como si fuésemos» otro usuario. Si utilizamos la seguridad de formularios de ASP.NET la información de usuarios se guardará normalmente en una base de datos de SQLServer. Por seguridad la contraseña de los usuarios no se guarda en la BBDD, sino que se guarda un hash que nos sirve para saber si el usuario ha metido la contraseña correcta.

La forma menos intrusiva y más sencilla que tenemos de autenticarnos como otro usuario, es copiar nuestro password en el suyo. Para ello debemos de copiar dos campos de la tabla aspnet_Membership: Password y PasswordSalt. Para encontrar cuál es el usuario tenemos también que acceder a la tabla aspnet_Users, en donde podemos buscarlo por UserName. Y al acabar de hacer las pruebas estaría bien dejar todo como estaba, así que lo ideal sería haber guardado la información original en algún sitio.

El siguiente script hace todo esto por nosotros: intercambia la contraseña de dos usuarios, definidos por sendos parámetros al principio. De esta forma si quiero hacer una prueba en mi aplicación con el usuario ‘admin’, basta con que ejecute el script, entre con mi contraseña y el usuario ‘admin’ y finalmente vuelva a ejecutar el script para intercambiar de nuevo las contraseñas y dejar todo como estaba.

declare @Usuario1 varchar(250),@Usuario2 varchar(250);
--Datos de prueba
select @Usuario1='miUsuario',@Usuario2='admin';

begin
tran
    --Guardo la informacin del usuario1 y 2
   
select U.UserName,M.UserId,M.ApplicationId,M.Password,M.PasswordSalt
   
into #infoUsuario
   
from aspnet_Users U
   
inner join aspnet_Membership M
   
on U.UserId=M.UserId and U.ApplicationId=M.ApplicationId
   
where U.UserName=@Usuario1 or U.UserName=@Usuario2;

    --Intercambio las informaciones
   
update aspnet_Membership
   
set [Password]=n.[Password], PasswordSalt=n.PasswordSalt
   
from
   
(--Consulta que hace el verdadero swap
       
select A.UserName, A.UserId,A.ApplicationId,B.Password,B.PasswordSalt
        from
#infoUsuario A,#infoUsuario B
       
where A.UserId<>B.UserId
   
) n
   
where
    aspnet_Membership
.ApplicationId=n.ApplicationId
   
and aspnet_Membership.UserId=N.UserId;

    --Borrado de la tabla temporal
    if(OBJECT_ID('tempdb..#infoUsuario') is not null)
   
    drop table #infoUsuario;
commit tran

 

Fíjate que la base de datos de membership puede ser compartida por varias aplicaciones de asp.net, de ahí que introduzca en la consulta el campo ApplicationId. Si tienes esta información en tu base de datos exclusiva para la aplicación puedes obviar esta condición.

¿Sencillo, no?

3 comentarios sobre “Intercambio de passwords en ASP.NET”

  1. Francisco, otra forma es la propuesta por José Alarcon: http://geeks.ms/blogs/jalarcon/archive/2010/07/11/c-243-mo-suplantar-usuarios-de-tu-aplicaci-243-n-para-soporte.aspx

    Por otro lado, si quieres entrar como un usuario en especial, quiere decir que tu aplicación esta hardCode por usuario? La pregunta va, porque si manejas Roles en tu aplicación, bastaría que cambies de rol a tu usuario y tienes toda la vista del usuario común.

    Saludos,

  2. Es cierto Sergio, esa forma está bien (por definición viniendo de quien viene ;-)), sólo quería aportar otra forma sencilla. Aunque si manejas roles lo normal es que no tengas problemas, siempre te encuentras con el típico usuario que te dice «es que a mi me sale esto» y la única forma de verlo es entrar con su usuario. No es por ser ese usuario, ni por el role, es por ejemplo porque tiene un carrito de la compra asociado y quieres verlo «tal cual».

    Carles, yo diría que eso no es una opción. Piensa que mucha gente usa la misma contraseña para todo, con lo cual cómo mímino es inmoral que tú la puedas ver. Además es inseguro, la forma de asegurarse de que nadie te puede robar esas contraseñas es tan sencillo cómo no guardarlas, ¿no?

    ¡Gracias a los dos por los comentarios!

Responder a franotero Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *