El problema es obvio. En la implementación actual solo tiene suplantación de usuarios y ninguna delegación. No quiero repetir información ya escrita por Stephen Martin. Solo quiero agregar al menos tres soluciones. La forma clásica de delegación que sugiere Stephen Martin es de una sola manera. Puede leer algunas formas más aquí: http://msdn.microsoft.com/en-us/library/ff647404.aspx#paght000023_delegation. Veo tres formas prácticas de que la solución de su problema:
convertir el testigo de suplantación del usuario a una ficha con el nivel de delegación de suplantación o para un nuevo identificador primario. Puede hacer esto con respecto a DuplicateToken
o DuplicateTokenEx
.
Uso S4U2Self (ver http://msdn.microsoft.com/en-us/magazine/cc188757.aspx y http://msdn.microsoft.com/en-us/library/ms998355.aspx) para recibir un nuevo token de la anterior con respecto a uno sencillo.NET instrucción WindowsIdentity wi = new WindowsIdentity(identity);
Puede acceder a otro servidor con respecto a una cuenta fija. Puede ser una cuenta de equipo en una cuenta del grupo de aplicaciones de IIS. Puede ser otra cuenta definida fija que solo se usará para acceder al sistema de archivos.
Es importante saber qué versión de Windows Server que tiene en el servidor donde se ejecuta IIS y qué nivel de función de dominio que tiene en Active Directory para el dominio (que ver esto en "dominio de Active Directory y Fideicomisos "herramienta si selecciona su dominio y elige" Elevar el nivel funcional del dominio "). También es interesante saber bajo qué cuenta se ejecuta el grupo de aplicaciones de IIS.
La primera y la tercera forma siempre funcionarán. La tercera forma puede ser mala para su entorno y para el permiso actual en el sistema de archivos. El segundo es muy elegante. Permite el control de los servidores (servidor de archivos) a los que se accede desde IIS. De esta manera tiene algunas restricciones y necesita algo de trabajo por hacer en Active Directory.
Debido a que usa ASP clásico, se debe crear un pequeño componente de software de secuencias de comandos para respaldar su implementación.
¿De qué manera prefieres?
ACTUALIZADO en base a la pregunta de comentario: Debido a que utiliza ASP clásico no se puede usar una API de Win32 directamente, pero se puede escribir un pequeño componente COM en Visual Basic 6 o en .NET que utilizan las API que se necesita. Como ejemplo, puede usar el código de http://support.microsoft.com/kb/248187/en. Pero deberías hacer algunas otras cosas adentro. Entonces explico ahora qué API de Win32 puede ayudarlo a hacer todo lo que necesita con tokens y suplantación.
Antes que nada, una pequeña explicación sobre la suplantación. Todo funciona muy facilmente Siempre hay un token primario bajo el cual se ejecuta el proceso. A cualquier hilo se le puede asignar otro token (token de hilo). Para hacer esto uno necesita tener un token de un usuario hUserToken
y llamar a la API ImpersonateLoggedOnUser(hUserToken);
.
Para volver al token de proceso original (para el hilo actual solamente) puede llamar a la función RevertToSelf()
. La señal del usuario será recibida y ya suplantada por IIS, ya que usted configuró su sitio web. Para volver al token de proceso original, debe implementar la llamada de la función RevertToSelf()
en su componente COM personalizado. Probablemente, si no necesita hacer nada más en la página ASP, será suficiente, pero le recomiendo que tenga más cuidado y guarde el token de los usuarios actuales en una variable antes de utilizar los archivos. Luego realiza todas las operaciones con el sistema de archivos y al final reasigna el token de los usuarios nuevamente al hilo actual. Puede asignar un token de suplantación a un hilo con respecto a SetThreadToken(NULL,hUserToken);
. Para dar (guardar) token de hebra actual (token de usuario en su caso) puede usar OpenThreadToken
API. Debe funcionar.
ACTUALIZADO 2: Es probable que el uso de la función RevertToSelf()
al final de una página ASP ya estaría bien para ti. El código C# correspondiente puede ser así:
Cree un nuevo proyecto en C# del tipo "Biblioteca de clases" con el nombre LoginAdmin
. Pegue el siguiente código dentro de
using System;
using System.Runtime.InteropServices;
namespace LoginAdmin {
[InterfaceTypeAttribute (ComInterfaceType.InterfaceIsDual)]
public interface IUserImpersonate {
[DispId(1)]
bool RevertToSelf();
}
internal static class NativeMethods {
[DllImport ("advapi32.dll", SetLastError = true)]
internal static extern bool RevertToSelf();
}
[ClassInterface (ClassInterfaceType.AutoDual)]
public class UserImpersonate : IUserImpersonate {
public UserImpersonate() { }
public bool RevertToSelf() {
return NativeMethods.RevertToSelf();
}
}
}
Compruebe las propiedades del proyecto en la parte "Crear" de "Registrarse para la interoperabilidad COM".En la parte "Firma" del proyecto, compruebe el ensamblaje y en "Elija un archivo de clave de nombre seguro" elija <New...>
, luego escriba cualquier nombre de archivo y contraseña (o marque "proteger mi clave ..."). Al final se debe modificar una línea de AssemblyInfo.cs en Propiedades parte del proyecto:
[assembly: ComVisible (true)]
Después de compilar este proyecto que se produzcan dos archivos, LoginAdmin.dll y LoginAdmin.tlb. La DLL ya está registrada en la computadora actual. Para registrarse, en la otra computadora, use RegAsm.exe.
Para probar esta DLL COM en una página ASP que puede hacer siguiendo
<%@ Language="javascript" %>
<html><body>
<% var objNet = Server.CreateObject("WScript.Network");
Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");
var objLoginAdmin = Server.CreateObject("LoginAdmin.UserImpersonate");
var isOK = objLoginAdmin.RevertToSelf();
if (isOK)
Response.Write("RevertToSelf return true<br/>");
else
Response.Write("RevertToSelf return false<br/>");
Response.Write("One more time after RevertToSelf()<br/>");
Response.Write("Current user: ");Response.Write(objNet.UserName);Response.Write("<br/>");
Response.Write("Current user's domain: ");Response.Write(objNet.UserDomain);Response.Write("<br/>");
var fso = Server.CreateObject("Scripting.FileSystemObject");
var path = "\\\\mk01\\C\\Oleg";
if (fso.FolderExists(path)) {
Response.Write("Yes");
} else {
Response.Write("No");
}%>
</body></html>
Si la cuenta utilizada para ejecutar el grupo de aplicaciones IIS tiene acceso a la correspondiente recurso compartido de red, la salida se ve como después de
Current user: Oleg
Current user's domain: WORKGROUP
RevertToSelf return true
One more time after RevertToSelf()
Current user: DefaultAppPool
Current user's domain: WORKGROUP
Yes
Bien, entonces, si estoy usando una suplantación, ¿qué credenciales usará el servidor cuando intente acceder a un recurso de red? Estoy muy contento de configurar el acceso a la red para la cuenta del equipo de IIS o la cuenta del grupo de aplicaciones, pero solo necesito saber exactamente a qué cuenta se le debe otorgar acceso. Si el grupo de aplicaciones se ejecuta como MYDOMAIN \ Some_Special_User, ¿utilizará la seguridad de Windows con suplantación para anular esta identidad cuando acceda a los recursos de la red? –