C# 如何检查用户是否是该计算机上的管理员
我需要检查用户是否是运行应用程序的计算机上的管理员。基本上,用户将提供用户名、密码和域,可能来自另一台机器。这些都是通过WCF传输的,在此阶段,我需要验证提供的用户名、密码和域是否在该计算机上具有管理员权限。这意味着不需要WMI,因为一切都发生在本地(用户只需通过WCF以字符串形式发送用户名、密码和域) 用户可以位于域上,因此链接到Active Directory,但也可以是本地用户,这意味着我无法回复以从Active Directory中查找它 我设法模拟了该用户,并可以验证该用户是否是本地组中的管理员。我使用以下命令对此进行了测试:C# 如何检查用户是否是该计算机上的管理员,c#,security,authentication,C#,Security,Authentication,我需要检查用户是否是运行应用程序的计算机上的管理员。基本上,用户将提供用户名、密码和域,可能来自另一台机器。这些都是通过WCF传输的,在此阶段,我需要验证提供的用户名、密码和域是否在该计算机上具有管理员权限。这意味着不需要WMI,因为一切都发生在本地(用户只需通过WCF以字符串形式发送用户名、密码和域) 用户可以位于域上,因此链接到Active Directory,但也可以是本地用户,这意味着我无法回复以从Active Directory中查找它 我设法模拟了该用户,并可以验证该用户是否是本地组
net localgroup administrators
我现在正在使用当前模拟用户创建WindowsPrincipal。但是,当检查此用户是否是管理员时,我得到的结果是错误的。以下是重要的代码:
// obtains user token
[DllImport("advapi32.dll", SetLastError=true)]
public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// creates duplicate token handle
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
bool bImpersonated = LogonUser(sUsername, sDomain, sPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);
bool bRetVal = DuplicateToken(pExistingTokenHandle, (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, ref pDuplicateTokenHandle);
WindowsIdentity newId = new WindowsIdentity(pDuplicateTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();
WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
if (wp.IsInRole(WindowsBuiltInRole.Administrator))
{
//is admin
}
else
{
//is not an admin (I am still getting this when user is an admin)
}
bImpersonated返回true(因此模拟工作正常)
bRetVal还返回true(因此令牌有效)
模拟代码来自(管理员检查除外)
非常感谢您的帮助。我使用代币支票:
private static Boolean IsAdministratorByToken(WindowsIdentity identity)
{
WindowsPrincipal principal = new WindowsPrincipal(identity);
// Check if this user has the Administrator role. If they do, return immediately.
// If UAC is on, and the process is not elevated, then this will actually return false.
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
{
return true;
}
// If we're not running in Vista onwards, we don't have to worry about checking for UAC.
if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
{
// Operating system does not support UAC; skipping elevation check.
return false;
}
int tokenInfLength = Marshal.SizeOf(typeof(int));
IntPtr tokenInformation = Marshal.AllocHGlobal(tokenInfLength);
try
{
IntPtr token = identity.Token;
Boolean result = NativeMethods.GetTokenInformation(token, NativeMethods.TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength);
if (!result)
{
Exception exception = Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
throw new InvalidOperationException("Couldn't get token information", exception);
}
NativeMethods.TokenElevationType elevationType = (NativeMethods.TokenElevationType)Marshal.ReadInt32(tokenInformation);
switch (elevationType)
{
case NativeMethods.TokenElevationType.TokenElevationTypeDefault:
// TokenElevationTypeDefault - User is not using a split token, so they cannot elevate.
return false;
case NativeMethods.TokenElevationType.TokenElevationTypeFull:
// TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator.
return true;
case NativeMethods.TokenElevationType.TokenElevationTypeLimited:
// TokenElevationTypeLimited - User has a split token, but the process is not running elevated. Assuming they're an administrator.
return true;
default:
// Unknown token elevation type.
return false;
}
}
finally
{
if (tokenInformation != IntPtr.Zero)
{
Marshal.FreeHGlobal(tokenInformation);
}
}
}
私有静态布尔IsAdministratorByToken(WindowsIdentity)
{
WindowsPrincipal=新的WindowsPrincipal(标识);
//检查此用户是否具有管理员角色。如果具有管理员角色,请立即返回。
//如果UAC处于打开状态,并且进程没有提升,那么实际上会返回false。
if(principal.IsInRole(WindowsBuiltInRole.Administrator))
{
返回true;
}
//如果我们没有在Vista以后的版本中运行,我们就不必担心检查UAC。
if(Environment.OSVersion.PlatformID.Win32NT | | Environment.OSVersion.Version.Major<6)
{
//操作系统不支持UAC;正在跳过高程检查。
返回false;
}
int-tokendefingth=Marshal.SizeOf(typeof(int));
IntPtr tokenInformation=Marshal.AllocHGlobal(令牌长度);
尝试
{
IntPtr token=identity.token;
布尔结果=NativeMethods.GetTokenInformation(标记,NativeMethods.TokenInformationClass.TokenElevationType,标记信息,标记长度,输出标记长度);
如果(!结果)
{
Exception Exception=Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());
抛出新的InvalidOperationException(“无法获取令牌信息”,异常);
}
NativeMethods.TokenElevationType elevationType=(NativeMethods.TokenElevationType)Marshal.ReadInt32(tokenInformation);
开关(升降式)
{
案例NativeMethods.TokenElevationType.TokenElevationType默认值:
//TokenElevationTypeDefault-用户未使用分割令牌,因此无法提升。
返回false;
案例NativeMethods.TokenElevationType.TokenElevationTypeFull:
//TokenElevationTypeFull-用户有一个拆分令牌,并且进程正在提升运行。假设他们是管理员。
返回true;
案例NativeMethods.TokenElevationType.TokenElevationTypeLimited:
//TokenElevationTypeLimited-用户有一个拆分令牌,但进程没有运行提升。假设他们是管理员。
返回true;
违约:
//未知的令牌提升类型。
返回false;
}
}
最后
{
if(令牌信息!=IntPtr.Zero)
{
FreeHGlobal元帅(令牌信息);
}
}
}
这是我的
您也可以使用
PrincipalContext
进行检查,但如果服务器服务未运行,此解决方案将不起作用。来自Xaruth的代码关于TokenElevationTypeLimited是错误的,在这种情况下,您应该返回false,并且对于内置管理员,您将获得TokenElevationTypeDefault,因此在这种情况下,检查用户是否为admin,而不是仅返回false。
以下是这篇文章的代码:
//
///基于此处找到的代码:
/// http://stackoverflow.com/questions/1220213/c-detect-if-running-with-elevated-privileges
///
公共静态类UacHelper
{
私有常量字符串uacRegistryKey=@“软件\Microsoft\Windows\CurrentVersion\Policys\System”;
private const string uacRegistryValue=“EnableLUA”;
私人建筑标准权利读取=0x00020000;
私有const-uint-TOKEN\u-QUERY=0x0008;
私有consuint TOKEN_READ=(标准权利_READ | TOKEN_QUERY);
[DllImport(“advapi32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部bool OpenProcessToken(IntPtr ProcessHandle、UInt32 DesiredAccess、out IntPtr TokenHandle);
[DllImport(“advapi32.dll”,SetLastError=true)]
公共静态外部bool GetTokenInformation(IntPtr TokenHandle、TOKEN\u INFORMATION\u CLASS tokeninformation CLASS、,
IntPtr令牌信息,uint令牌信息长度,
out uint返回长度);
公共枚举令牌\u信息\u类
{
令牌用户=1,
令牌组,
代币特权,
代币所有人,
TokenPrimaryGroup,
代币,
代币来源,
令牌类型,
令牌模拟级别,
统计数字,,
受限制的小岛屿发展中国家,
TokenSessionId,
令牌组和特权,
TokenSessionReference,
沙博森特,
这项政策,
象征起源,
标记提升类型,
TokenLinkedToken,
象征性的提升,
有限制,,
令牌访问信息,
允许令牌虚拟化,
已启用令牌虚拟化,
TokenIntegrityLevel,
令牌访问,
TokenMandatoryPolicy,
TokenLogonSid,
MaxTokenInfoCla
/// <summary>
/// Base on code found here:
/// http://stackoverflow.com/questions/1220213/c-detect-if-running-with-elevated-privileges
/// </summary>
public static class UacHelper
{
private const string uacRegistryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
private const string uacRegistryValue = "EnableLUA";
private const uint STANDARD_RIGHTS_READ = 0x00020000;
private const uint TOKEN_QUERY = 0x0008;
private const uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool GetTokenInformation(IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass,
IntPtr TokenInformation, uint TokenInformationLength,
out uint ReturnLength);
public enum TOKEN_INFORMATION_CLASS
{
TokenUser = 1,
TokenGroups,
TokenPrivileges,
TokenOwner,
TokenPrimaryGroup,
TokenDefaultDacl,
TokenSource,
TokenType,
TokenImpersonationLevel,
TokenStatistics,
TokenRestrictedSids,
TokenSessionId,
TokenGroupsAndPrivileges,
TokenSessionReference,
TokenSandBoxInert,
TokenAuditPolicy,
TokenOrigin,
TokenElevationType,
TokenLinkedToken,
TokenElevation,
TokenHasRestrictions,
TokenAccessInformation,
TokenVirtualizationAllowed,
TokenVirtualizationEnabled,
TokenIntegrityLevel,
TokenUIAccess,
TokenMandatoryPolicy,
TokenLogonSid,
MaxTokenInfoClass
}
public enum TOKEN_ELEVATION_TYPE
{
TokenElevationTypeDefault = 1,
TokenElevationTypeFull,
TokenElevationTypeLimited
}
private static bool? _isUacEnabled;
public static bool IsUacEnabled
{
get
{
if (_isUacEnabled == null)
{
var uacKey = Registry.LocalMachine.OpenSubKey(uacRegistryKey, false);
if (uacKey == null)
{
_isUacEnabled = false;
}
else
{
var enableLua = uacKey.GetValue(uacRegistryValue);
_isUacEnabled = enableLua.Equals(1);
}
}
return _isUacEnabled.Value;
}
}
private static bool? _isAdministrator;
public static bool IsAdministrator
{
get
{
if (_isAdministrator == null)
{
var identity = WindowsIdentity.GetCurrent();
Debug.Assert(identity != null);
var principal = new WindowsPrincipal(identity);
_isAdministrator = principal.IsInRole(WindowsBuiltInRole.Administrator);
}
return _isAdministrator.Value;
}
}
private static bool? _isProcessElevated;
public static bool IsProcessElevated
{
get
{
if (_isProcessElevated == null)
{
if (IsUacEnabled)
{
var process = Process.GetCurrentProcess();
IntPtr tokenHandle;
if (!OpenProcessToken(process.Handle, TOKEN_READ, out tokenHandle))
{
throw new ApplicationException("Could not get process token. Win32 Error Code: " +
Marshal.GetLastWin32Error());
}
var elevationResult = TOKEN_ELEVATION_TYPE.TokenElevationTypeDefault;
var elevationResultSize = Marshal.SizeOf((int) elevationResult);
uint returnedSize;
var elevationTypePtr = Marshal.AllocHGlobal(elevationResultSize);
var success = GetTokenInformation(tokenHandle, TOKEN_INFORMATION_CLASS.TokenElevationType,
elevationTypePtr, (uint) elevationResultSize, out returnedSize);
if (!success)
{
Marshal.FreeHGlobal(elevationTypePtr);
throw new ApplicationException("Unable to determine the current elevation.");
}
elevationResult = (TOKEN_ELEVATION_TYPE) Marshal.ReadInt32(elevationTypePtr);
Marshal.FreeHGlobal(elevationTypePtr);
// Special test for TokenElevationTypeDefault.
// If the current user is the default Administrator, then the
// process is also assumed to run elevated. This is assumed
// because by default the default Administrator (which is disabled by default)
// gets all access rights even without showing a UAC prompt.
switch (elevationResult)
{
case TOKEN_ELEVATION_TYPE.TokenElevationTypeFull:
_isProcessElevated = true;
break;
case TOKEN_ELEVATION_TYPE.TokenElevationTypeLimited:
_isProcessElevated = false;
break;
default:
// Will come here if either
// 1. We are running as the default Administrator.
// 2. We were started using "Run as administrator" from a non-admin
// account and logged on as the default Administrator account from
// the list of available Administrator accounts.
//
// Note: By default the default Administrator account always behaves
// as if UAC was turned off.
//
// This can be controlled through the Local Security Policy editor
// (secpol.msc) using the
// "User Account Control: Use Admin Approval Mode for the built-in Administrator account"
// option of the Security Settings\Local Policies\Security Options branch.
_isProcessElevated = IsAdministrator;
break;
}
}
else
{
_isProcessElevated = IsAdministrator;
}
}
return _isProcessElevated.Value;
}
}
}