我有一个在本地机器系统帐户下运行的Windows服务 . 在此服务中,它尝试读取远程共享文件夹上可用的远程.ini文件 . 尝试读取此文件的代码使用LogonUser进行模拟(下面是代码的简化版本,以了解它正在做什么) . 模拟成功开始模拟配置的用户,但是当它尝试读取远程网络共享上找到的远程ini文件时,会抛出UnauthorizedAccessException . 即使配置的用户对远程计算机具有读/写权限,也会发生这种情况 . 当我修改代码以删除所有模拟,而是以配置的用户身份运行Windows服务时,对远程.ini文件的所有访问都是成功的 . 我宁愿使用模拟来访问此文件,而不是像用户那样运行服务 . 任何人都可以在示例中看到模拟代码的错误吗?我需要在我的Vista 64位盒上做些什么来启用它吗?我的IT同事需要启用特定的活动目录权限吗?
private WindowsImpersonationContext _impersonatedUser;
private IntPtr _token;
// Declare signatures for Win32 LogonUser and CloseHandle APIs
[DllImport("advapi32.dll", SetLastError = true)]
static extern bool LogonUser(
string principal,
string authority,
string password,
LogonSessionType logonType,
LogonProvider logonProvider,
out IntPtr token);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
enum LogonSessionType : uint
{
Interactive = 2,
Network,
Batch,
Service,
NetworkCleartext = 8,
NewCredentials
}
enum LogonProvider : uint
{
Default = 0, // default for platform (use this!)
WinNT35, // sends smoke signals to authority
WinNT40, // uses NTLM
WinNT50 // negotiates Kerb or NTLM
}
....
var result = LogonUser(exchangeUserId, exchangeDomain,
password,
LogonSessionType.Network,
LogonProvider.Default,
out _token);
var id = new WindowsIdentity(_token);
_impersonatedUser = id.Impersonate();
try
{
//Validate access to the file on the remote computer/share
File.GetAccessControl(remoteFileAvailableInSharedFolder);
}
catch (UnauthorizedAccessException unauthorized)
{
...
}
....
// Stop impersonation and revert to the process identity
if (_impersonatedUser != null)
{
_impersonatedUser.Undo();
_impersonatedUser = null;
}
if (_token != IntPtr.Zero)
{
CloseHandle(_token);
_token = IntPtr.Zero;
}
1 回答
进一步研究我发现了模拟代码引起的核心问题 . 我不得不添加api DuplicateToken的使用,并添加了api RevertToSelf的用法 . 在进行这些更改(请参阅下面的类)时,模拟工作以及在我的域用户下运行整个服务时代码执行的操作 . 希望代码可以帮助其他人解决同样的问题 .