繁体   English   中英

如何检查用户是否是该计算机上的管理员

[英]How to check if user is an administrator on that machine

我需要检查用户是否是运行该应用程序的计算机上的管理员。 基本上,用户将可能从另一台计算机提供用户名,密码和域。 这些是通过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);
        }
    }
}

这是来自这个博客

您也可以使用PrincipalContext检查,但是如果Server Service未运行,则此解决方案不起作用。

Xaruth的代码关于TokenElevationTypeLimited是错误的,在这种情况下,您应该返回false,对于内置管理员,您将获得TokenElevationTypeDefault,因此在这种情况下,请检查用户是否是admin而不是仅仅返回false。 这是这篇文章中的代码: https : //candritzky.wordpress.com/2012/08/28/uac-elevation-and-the-default-administrator-account/

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM