Безопасность файлов и каталогов с помощью IPrincipal - PullRequest
3 голосов
/ 01 апреля 2009

Мне нужно получить доступ к файлам и каталогам, к которым у текущего IPrincipal есть доступ через методы Directory.GetDirectories () и Directory.GetFiles (), без перечисления других файлов. Сам процесс работает как NETWORK SERVICE, поэтому он должен сменить принципала на текущего пользователя (через IPrincipal) на время этих вызовов.

Я пытался изменить Thread.CurrentPrincipal на новый IPrincipal до части доступа к файлу, но, похоже, это не имеет значения.

Есть ли что-то еще, что я могу сделать, или я что-то упускаю?

Ответы [ 3 ]

5 голосов
/ 06 апреля 2009

Олицетворение Windows решает эту проблему, используя данные для входа в систему для получения токена пользователя. Затем этот токен можно использовать для получения идентификатора WindowsIdentity, который затем используется для создания контекста олицетворения. В рамках этого контекста вы можете получить доступ к файловой системе как под именем пользователя.

Конечно, вам нужно будет сохранить имя пользователя и пароль, чтобы этот подход работал.

Сначала определите API-интерфейсы Windows, необходимые для получения токена пользователя из 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 );
}

Затем используйте эти API для получения идентификатора Windows:

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 );
}

И, наконец, используйте эту идентичность для создания контекста олицетворения:

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;
    }
}

Наконец, важно очистить дескриптор окна, используя шаблон IDisposable, используя сохраненный _userToken:

if ( _userToken != IntPtr.Zero )
    WindowsAPI.CloseHandle( _userToken );
0 голосов
/ 01 апреля 2009

Вы можете использовать DllImport и Win32 API LogonUser для олицетворения другого пользователя.

0 голосов
/ 01 апреля 2009

Я не думаю, что вы делаете это правильно. Вы должны изучить использование подражания. Например, посмотрите этот учебник о том, как это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...