2009-03-31 10 views
3

J'ai besoin d'accéder aux fichiers et répertoires auxquels l'IPrincipal actuel a accès via les méthodes Directory.GetDirectories() et Directory.GetFiles(), sans répertorier les autres fichiers. Le processus lui-même fonctionne en tant que SERVICE RÉSEAU, il doit donc changer le principal à l'utilisateur actuel (via IPrincipal) pour la durée de ces appels.Sécurité des fichiers et des répertoires avec IPrincipal

J'ai essayé de changer Thread.CurrentPrincipal à la nouvelle IPrincipal avant la partie d'accès au fichier, mais cela ne semble pas faire de différence.

Y a-t-il quelque chose d'autre que je puisse faire ou est-ce qu'il me manque quelque chose?

+0

Je pense que vous trouverez qu'il est IPrincipal –

Répondre

5

L'emprunt d'identité Windows résout ce problème en utilisant les informations de connexion pour acquérir un jeton d'utilisateur. Ce jeton peut ensuite être utilisé pour obtenir un WindowsIdentity, qui est ensuite utilisé pour générer un contexte d'emprunt d'identité. Dans cette étendue de contexte, vous pouvez ensuite accéder au système de fichiers en tant que l'utilisateur avec emprunt d'identité.

Bien sûr, vous devrez stocker le nom d'utilisateur et le mot de passe pour que cette approche fonctionne.

D'abord, définir les API Windows nécessaires pour obtenir un jeton d'utilisateur à partir de Windows:

internal class WindowsAPI 
{ 
    public const int LOGON32_PROVIDER_DEFAULT = 0; 
    public const int LOGON32_LOGON_INTERACTIVE = 2; 

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    public static extern bool LogonUser(String lpszUsername, 
     String lpszDomain, String lpszPassword, 
     int dwLogonType, int dwLogonProvider, ref IntPtr phToken 
    ); 

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

Ensuite, utilisez ces API pour acquérir un WindowsIdentity:

private WindowsIdentity GetIdentity(string userName, string password) 
{ 
    _userToken = IntPtr.Zero; 

    if (!WindowsAPI.LogonUser(
     userName, 
     AbbGrainDomain, 
     password, 
     WindowsAPI.LOGON32_LOGON_INTERACTIVE, WindowsAPI.LOGON32_PROVIDER_DEFAULT, 
     ref _userToken 
    )) 
    { 
     int errorCode = Marshal.GetLastWin32Error(); 
     throw new System.ComponentModel.Win32Exception(errorCode); 
    } 

    return new WindowsIdentity(_userToken); 
} 

Et enfin, utiliser cette identité générer un contexte d'emprunt d'identité:

public List<string> GetDirectories(string searchPath) 
{ 
    using (WindowsImpersonationContext wic = GetIdentity().Impersonate()) 
    { 
     var directories = new List<string>(); 

     var di = new DirectoryInfo(searchPath); 
     directories.AddRange(di.GetDirectories().Select(d => d.FullName)); 

     return directories; 
    } 
} 

Enfin, il est important de nettoyer le Windows gérer en utilisant le modèle IDisposable, en utilisant le _userToken stocké:

if (_userToken != IntPtr.Zero) 
    WindowsAPI.CloseHandle(_userToken); 
0

Je ne pense pas que vous le faites de la bonne façon. Vous devriez envisager d'utiliser l'usurpation d'identité. Par exemple, jetez un oeil à this tutoriel sur la façon de le faire.

-1

Vous pouvez utiliser DllImport et l'API LogonUser win32 pour emprunter l'identité d'un autre utilisateur.

Questions connexes