在.NET/C#test中,如果进程具有管理权限

Cli*_*rce 49 .net c# windows security

是否有一种规范的方法来测试该进程是否具有计算机的管理权限?

我将开始一个长期运行的过程,并且在此过程的生命周期中,它会尝试一些需要管理员权限的事情.

如果流程具有这些权利而不是以后,我希望能够预先测试.

Wad*_* M. 78

这将检查用户是否在本地Administrators组中(假设您没有检查域管理员权限)

using System.Security.Principal;

public bool IsUserAdministrator()
{
    //bool value to hold our return value
    bool isAdmin;
    WindowsIdentity user = null;
    try
    {
        //get the currently logged in user
        user = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal(user);
        isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
    catch (UnauthorizedAccessException ex)
    {
        isAdmin = false;
    }
    catch (Exception ex)
    {
        isAdmin = false;
    }
    finally
    {
        if (user != null)
            user.Dispose();
    }
    return isAdmin;
}
Run Code Online (Sandbox Code Playgroud)

  • 我在启用了UAC的Windows Server 2008上测试了这个.它的工作方式如下:提升管理员 - > true,非提升管理员 - > false,标准用户 - > false (11认同)
  • @Jared:它还隐藏了该块中可能发生的任何严重错误.它应该删除. (5认同)
  • 这将确定用户是否在BUILTIN\Administrators组中,但它是否会显示用户是否在Vista上升级? (3认同)
  • 如果启用了UAC,则无法在Vista中使用.原因是UAC为具有管理权限的用户创建了"拆分令牌",并且"拆分令牌"明确排除了所有管理员角色(包括"域管理员"之类的内容). (3认同)
  • @Jacob Proffitt如果你是非高架管理员`principal.IsInRole(WindowsBuiltInRole.Administrator);`将返回false,如果你是一个提升的管理员,它只返回true. (3认同)

Dav*_*ore 27

从Wadih M的代码开始,我有一些额外的P/Invoke代码来尝试处理UAC启用时的情况.

http://www.davidmoore.info/blog/2011/06/20/how-to-check-if-the-current-user-is-an-administrator-even-if-uac-is-on/

首先,我们需要一些代码来支持GetTokenInformation API调用:

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, IntPtr tokenInformation, int tokenInformationLength, out int returnLength);

/// <summary>
/// Passed to <see cref="GetTokenInformation"/> to specify what
/// information about the token to return.
/// </summary>
enum TokenInformationClass
{
     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
}

/// <summary>
/// The elevation type for a user token.
/// </summary>
enum TokenElevationType
{
    TokenElevationTypeDefault = 1,
    TokenElevationTypeFull,
    TokenElevationTypeLimited
}
Run Code Online (Sandbox Code Playgroud)

然后,检测用户是否为管理员的实际代码(如果是,则返回true,否则为false).

var identity = WindowsIdentity.GetCurrent();
if (identity == null) throw new InvalidOperationException("Couldn't get the current user identity");
var 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
{
    var token = identity.Token;
    var result = GetTokenInformation(token, TokenInformationClass.TokenElevationType, tokenInformation, tokenInfLength, out tokenInfLength);

    if (!result)
    {
        var exception = Marshal.GetExceptionForHR( Marshal.GetHRForLastWin32Error() );
        throw new InvalidOperationException("Couldn't get token information", exception);
    }

    var elevationType = (TokenElevationType)Marshal.ReadInt32(tokenInformation);

    switch (elevationType)
    {
        case TokenElevationType.TokenElevationTypeDefault:
            // TokenElevationTypeDefault - User is not using a split token, so they cannot elevate.
            return false;
        case TokenElevationType.TokenElevationTypeFull:
            // TokenElevationTypeFull - User has a split token, and the process is running elevated. Assuming they're an administrator.
            return true;
        case 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);
}
Run Code Online (Sandbox Code Playgroud)


Jac*_*itt 17

如果要确保您的解决方案在Vista UAC中运行,并且具有.Net Framework 3.5或更高版本,则可能需要使用System.DirectoryServices.AccountManagement命名空间.您的代码看起来像:

bool isAllowed = false;
using (PrincipalContext pc = new PrincipalContext(ContextType.Machine, null))
{
    UserPrincipal up = UserPrincipal.Current;
    GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "Administrators");
    if (up.IsMemberOf(gp))
        isAllowed = true;
}
Run Code Online (Sandbox Code Playgroud)

  • 请不要硬编码管理员(非常确定这是localisable字符串,而不是BUILTIN\ADministrators众所周知的字符串) (7认同)
  • 根据MSDN页面,您可以使用SID,我认为它是"S-1-5-32-544".http://msdn.microsoft.com/en-us/library/bb359434.aspx (4认同)