impersonation

21/10/2009 - 09:46 por josetellan | Informe spam
Hola a todos, les cuento el problema.
tengo una feature que sube en cada sitio creado una serie de masterpages y
aplica un tema determinado en funcion de la aplicacion en la que se crea
dicho sitio. las masterpages son para las paginas de contenido y tambien para
las paginas de administracion (/layouts). el cambio de masterpage lo hago a
traves de un httpmodule que segun que pagina se pida al servidor me pone una
master u otra. esa es la funcionalidad de mi codigo y todo lo hace genial
pero le falta lo mas importante. como la creacion de sitios debe ser con un
usuario con los permisos adecuados, adjunte un archivo de configuracion a la
feature llamado "siteConfigurator.config", desde el que leo un tag
<impersonate> con el user y pass del admin de la granja sin encriptar ni
nadapero como estaba en desarrollo pues me valia hasta lograr la
funcionalidad.
esos 3 valores (domain, user y pass) se le pasan a un metodo de una clase
llamada "impersonation.cs" que tiene este codigo:

public class Impersonation
{
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
private WindowsIdentity tempWindowsIdentity;


WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

internal bool ImpersonateValidUser(String userName, String domain,
String password)
{
//WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;

if (RevertToSelf())
{
if (LogonUserA(userName, domain, password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new
WindowsIdentity(tokenDuplicate);
impersonationContext =
tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}


if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}

internal void UndoImpersonation()
{
impersonationContext.Undo();
}
}

la funcion nos devuelve true si el token es valido. mi pregunta escual
es la mejor manera ( donde colocarlos, como recogerlos y como pasarlos) de
recoger los valores de domain , user y pass para pasarselos a esta clase



les cuento lo que he probado hasta ahora:

en primer lugar lei el tema de "aspnet_regiis -pe ." para encriptar
secciones de web.config ´s...y lo hacia genial pero no se por qué las
busquedas dejaban de funcionar y como las busquedas son tan importantes en la
intranet de mi empresa pues se ha decidio combiar de estrategia. y en segundo
lugar probe a insertar el codigo referente a runwithelevatedprivileges pero
me da algunos errores que me hacen preguntarme si voy por el buen camino.

muchas gracias de antemano y un saludo.

Preguntas similare

Leer las respuestas

#1 Hans Baumann
22/10/2009 - 10:46 | Informe spam
En principio como yo lo hacía para evitar cualquier problema era encriptar
el usuario y la contraseña en el web.config, pero sólo esos dos datos.

Es lo mas sencillo y directo que se me ocurre.

Un saludo,


"josetellan" escribió en el mensaje
de noticias news:
Hola a todos, les cuento el problema.
tengo una feature que sube en cada sitio creado una serie de masterpages y
aplica un tema determinado en funcion de la aplicacion en la que se crea
dicho sitio. las masterpages son para las paginas de contenido y tambien
para
las paginas de administracion (/layouts). el cambio de masterpage lo hago
a
traves de un httpmodule que segun que pagina se pida al servidor me pone
una
master u otra. esa es la funcionalidad de mi codigo y todo lo hace genial
pero le falta lo mas importante. como la creacion de sitios debe ser con
un
usuario con los permisos adecuados, adjunte un archivo de configuracion a
la
feature llamado "siteConfigurator.config", desde el que leo un tag
<impersonate> con el user y pass del admin de la granja sin encriptar ni
nadapero como estaba en desarrollo pues me valia hasta lograr la
funcionalidad.
esos 3 valores (domain, user y pass) se le pasan a un metodo de una clase
llamada "impersonation.cs" que tiene este codigo:

public class Impersonation
{
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
private WindowsIdentity tempWindowsIdentity;


WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError > true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError > true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

internal bool ImpersonateValidUser(String userName, String domain,
String password)
{
//WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;

if (RevertToSelf())
{
if (LogonUserA(userName, domain, password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new
WindowsIdentity(tokenDuplicate);
impersonationContext > tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}


if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}

internal void UndoImpersonation()
{
impersonationContext.Undo();
}
}

la funcion nos devuelve true si el token es valido. mi pregunta escual
es la mejor manera ( donde colocarlos, como recogerlos y como pasarlos) de
recoger los valores de domain , user y pass para pasarselos a esta clase



les cuento lo que he probado hasta ahora:

en primer lugar lei el tema de "aspnet_regiis -pe ." para encriptar
secciones de web.config ´s...y lo hacia genial pero no se por qué las
busquedas dejaban de funcionar y como las busquedas son tan importantes en
la
intranet de mi empresa pues se ha decidio combiar de estrategia. y en
segundo
lugar probe a insertar el codigo referente a runwithelevatedprivileges
pero
me da algunos errores que me hacen preguntarme si voy por el buen camino.

muchas gracias de antemano y un saludo.
Respuesta Responder a este mensaje
#2 josetellan
23/10/2009 - 13:05 | Informe spam
Hola Hans, gracias por contestar. En cual de todos los web.config encriptabas
el user y pass.y con que metodo???

donde yo encripte la seccion identity del web.config fue en el que esta
guardado en la ruta
c:\win\microsoft.net\framework64\v2.5027\config\web.config y lo hice con la
orden "aspnet_regiis -pe .."
lo hiciste tu asi???

saludossssssss
Respuesta Responder a este mensaje
#3 Hans Baumann
23/10/2009 - 13:33 | Informe spam
No, lo encripté directamente sobre el web.config que está en

c:\inetpub\wwwroot\wss\virtualdirectories\[puerto de tu aplicación web]

Este web.config sólo afecta a la aplicación y no a todo el servidor.

"josetellan" escribió en el mensaje
de noticias news:
Hola Hans, gracias por contestar. En cual de todos los web.config
encriptabas
el user y pass.y con que metodo???

donde yo encripte la seccion identity del web.config fue en el que esta
guardado en la ruta
c:\win\microsoft.net\framework64\v2.5027\config\web.config y lo hice con
la
orden "aspnet_regiis -pe .."
lo hiciste tu asi???

saludossssssss
Respuesta Responder a este mensaje
#4 David Martos
24/10/2009 - 20:49 | Informe spam
Hola José,

Otra opción que tienes es poner tu código dentro de un bloque privilegiado:

http://msdn.microsoft.com/en-us/lib...leges.aspx

esto te permitirá crear los sitios con las credenciales del administrador de
la colección de sitios sin tener que guardarlas en ningún sitio.

Por otro lado, comentas que usas un httpmodule para cambiar la masterpage en
cada petición. ¿Esto te funciona bien con usuarios concurrentes? ¿Y en
cuanto al rendimiento? Yo no lo veo muy claro, porque estás haciendo una
modificación que afecta a todos los usuarios en cada una de las peticiones.
Si necesitase mostrar algo diferente en base al usuario, haría uso de
audiencias, de controles web (o de webparts) y, en última instancia, de
variaciones de sitio.

Saludos,
David Martos
http://david-martos.blogspot.com


"josetellan" wrote in message
news:
Hola a todos, les cuento el problema.
tengo una feature que sube en cada sitio creado una serie de masterpages y
aplica un tema determinado en funcion de la aplicacion en la que se crea
dicho sitio. las masterpages son para las paginas de contenido y tambien
para
las paginas de administracion (/layouts). el cambio de masterpage lo hago
a
traves de un httpmodule que segun que pagina se pida al servidor me pone
una
master u otra. esa es la funcionalidad de mi codigo y todo lo hace genial
pero le falta lo mas importante. como la creacion de sitios debe ser con
un
usuario con los permisos adecuados, adjunte un archivo de configuracion a
la
feature llamado "siteConfigurator.config", desde el que leo un tag
<impersonate> con el user y pass del admin de la granja sin encriptar ni
nadapero como estaba en desarrollo pues me valia hasta lograr la
funcionalidad.
esos 3 valores (domain, user y pass) se le pasan a un metodo de una clase
llamada "impersonation.cs" que tiene este codigo:

public class Impersonation
{
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
private WindowsIdentity tempWindowsIdentity;


WindowsImpersonationContext impersonationContext;

[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError > true)]
public static extern int DuplicateToken(IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError > true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);

internal bool ImpersonateValidUser(String userName, String domain,
String password)
{
//WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;

if (RevertToSelf())
{
if (LogonUserA(userName, domain, password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new
WindowsIdentity(tokenDuplicate);
impersonationContext > tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
{
CloseHandle(token);
CloseHandle(tokenDuplicate);
return true;
}
}
}
}


if (token != IntPtr.Zero)
CloseHandle(token);
if (tokenDuplicate != IntPtr.Zero)
CloseHandle(tokenDuplicate);
return false;
}

internal void UndoImpersonation()
{
impersonationContext.Undo();
}
}

la funcion nos devuelve true si el token es valido. mi pregunta escual
es la mejor manera ( donde colocarlos, como recogerlos y como pasarlos) de
recoger los valores de domain , user y pass para pasarselos a esta clase



les cuento lo que he probado hasta ahora:

en primer lugar lei el tema de "aspnet_regiis -pe ." para encriptar
secciones de web.config ´s...y lo hacia genial pero no se por qué las
busquedas dejaban de funcionar y como las busquedas son tan importantes en
la
intranet de mi empresa pues se ha decidio combiar de estrategia. y en
segundo
lugar probe a insertar el codigo referente a runwithelevatedprivileges
pero
me da algunos errores que me hacen preguntarme si voy por el buen camino.

muchas gracias de antemano y un saludo.
Respuesta Responder a este mensaje
#5 josetellan
26/10/2009 - 09:50 | Informe spam
"David Martos" wrote:

Hola José,

Otra opción que tienes es poner tu código dentro de un bloque privilegiado:

http://msdn.microsoft.com/en-us/lib...leges.aspx

esto te permitirá crear los sitios con las credenciales del administrador de
la colección de sitios sin tener que guardarlas en ningún sitio.

Por otro lado, comentas que usas un httpmodule para cambiar la masterpage en
cada petición. ¿Esto te funciona bien con usuarios concurrentes? ¿Y en
cuanto al rendimiento? Yo no lo veo muy claro, porque estás haciendo una
modificación que afecta a todos los usuarios en cada una de las peticiones.
Si necesitase mostrar algo diferente en base al usuario, haría uso de
audiencias, de controles web (o de webparts) y, en última instancia, de
variaciones de sitio.

Saludos,
David Martos
http://david-martos.blogspot.com


Hola David, graci9as por el aporte del codigo privilegiado, ahora mismo me pongo con elloya lo contare aqui en el foro.


Respecto a lo del httpmodulesegun dices que el rendimiento puede estar
un poco fastidiado no???.como puedo hacer una prueba para comprobar lo
que dices de usuarios concurrentes???
de todas formas te explico un poco mas en detalle.

Se tienen 3 web application y en la que una de ellas es de apariencia blanca
y las otras dos son verdes. Tanto para las paginas que llevan asociadas la
default.master como para las que llevan la application.master tengo que
cambiarlas y ponerle las que corresponda en funcion de la application que se
pida. Pero aqui entran siteCollections en los que estan aparte y no se les
debe poner ninguna master o a veces hay que ponerle otra distinta. Con lo
cual se tienen una serie de condiciones que hacen que el metodo elegido de un
httpmodule mirando cada peticion sea el escogido...pero supongo que habra
otras alternativasasi que no va por usuarios sino por sitesCollections y
applications...
No se si lo he dejado mas claro, espero que si, jejejje
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida