好了,檢查的WindowsIdentity
和WindowsPrincipal
類的源代碼後,我發現,越來越原因「拒絕訪問」是我檢索到的令牌在首位的方式。 讓我們從頭開始:
WindowsIdentity
是一個表示進程/線程令牌的類。所以初始化一個方法是提供一個令牌。在我的情況下,我使用OpenProcessToken
函數從另一個進程中檢索到該令牌。
這適用於查詢令牌數據和檢索信息。就像我的情況一樣。但是,在WindowsPrincipal
班旁邊使用時,這還不夠。
WindowsPrincipal.IsInRole
使用CheckTokenMembershipEx
來查看令牌是否屬於用戶組。但爲了能夠使用CheckTokenMembershipEx
函數,您需要模擬進程/線程令牌。 WindowsPrincipal.IsInRole
完全意識到這一點,並且如果提供的WindowsIdentity
具有模擬級別None
,將使用DuplicateTokenEx
創建模擬令牌。
不幸的是,我犯了一個錯誤。當打開獲取令牌的過程時,我並沒有期待這種行爲。事實上,我甚至不知道WindowsPrincipal.IsInRole
在底層使用了CheckTokenMembershipEx
函數。所以打開進程標記時我沒有要求Duplicate
訪問。這導致DuplicateTokenEx
失敗並顯示「訪問被拒絕」消息。添加正確的,解決了一切。
這裏是任何有興趣的代碼:
public static WindowsIdentity GetProcessIdentity(Process process)
{
SafeTokenHandle token = SafeTokenHandle.InvalidHandle;
try
{
if (!Methods.OpenProcessToken(process.Handle, TokenAccessLevels.Query | TokenAccessLevels.Duplicate, out token))
{
throw new Win32Exception();
}
return new WindowsIdentity(token.DangerousGetHandle());
}
finally
{
token.Dispose();
}
}
private static TokenElevationType GetTokenElevation(IntPtr token)
{
var elevationTypeLength = Marshal.SizeOf(typeof (int));
var elevationType = (TokenElevationType) 0;
if (!Methods.GetTokenInformation(token,
TokenInformationClass.TokenElevationType,
ref elevationType, elevationTypeLength, out elevationTypeLength))
{
throw new Win32Exception();
}
return elevationType;
}
public static bool IsProcessElevated(Process process)
{
WindowsIdentity processIdentity = GetProcessIdentity(process);
var tokenElevation = GetTokenElevation(processIdentity.Token);
if (tokenElevation == TokenElevationType.Limited)
{
return false;
}
if (tokenElevation == TokenElevationType.Full)
{
return true;
}
// Do we have a Default elevation type? Then the process elevation status depends directly
// to the owner user being a member of the Administrative group.
return new WindowsPrincipal(processIdentity).IsInRole(WindowsBuiltInRole.Administrator);
}
您可能,例如,使用的System.DirectoryServices,通過所有的用戶,直到找到所需的一個再檢查她的組 –
你能告訴我們你怎麼弄SID通過Win32?如果這可以在.Net中完成,則可以調用IsInRole –
@AlexK。更多信息添加。 –