it-swarm.com.de

In .NET/C # testen, ob der Prozess über Administratorrechte verfügt

Gibt es eine kanonische Methode, um zu testen, ob der Prozess auf einem Computer über Administratorrechte verfügt? 

Ich werde einen langwierigen Prozess starten, und viel später im Laufe des Prozesses wird es einige Dinge versuchen, die Administratorrechte erfordern.

Ich möchte gerne im Vorfeld testen, ob der Prozess diese Rechte hat und nicht später.

49
Clinton Pierce

Dadurch wird geprüft, ob sich der Benutzer in der lokalen Gruppe der Administratoren befindet (vorausgesetzt, Sie prüfen nicht nach Administratorrechten für Domänen).

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;
}
76
Wadih M.

Beginnend mit Wadih M-Code habe ich zusätzlichen P/Invoke-Code, um den Fall zu prüfen, in dem die Benutzerkontensteuerung aktiviert ist.

http://www.davidmoore.info/blog/2011/06/20/wie-nach-check-if-der-aetzige-benutzer-ist-administrator-icht-if-uac-is-on/

Zunächst benötigen wir etwas Code, um den GetTokenInformation-API-Aufruf zu unterstützen:

[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
}

Dann der eigentliche Code, um festzustellen, ob der Benutzer ein Administrator ist (gibt true zurück, andernfalls 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);
}
27
David Moore

Wenn Sie sicherstellen möchten, dass Ihre Lösung in Vista UAC funktioniert und über .Net Framework 3.5 oder höher verfügt, können Sie den Namespace System.DirectoryServices.AccountManagement verwenden. Ihr Code würde ungefähr so ​​aussehen:

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;
}
17
Jacob Proffitt

Bei Verwendung von .NET Framework 4.5 scheint es einfacher zu sein, zu überprüfen, ob ein Benutzer zur Gruppe der Administratoren gehört:

WindowsPrincipal principal = WindowsPrincipal.Current;
bool canBeAdmin = principal.Claims.Any((c) => c.Value == "S-1-5-32-544");
3
Jens

Versuchte Erwins Code, der aber nicht kompiliert wurde.

Hab es so funktionieren:

[DllImport("Shell32.dll")] public static extern bool IsUserAnAdmin();
2
Alex G.

Andere Antworten, die auf die IsInRole-Methode zurückgreifen, geben nur dann "true" zurück, wenn der Benutzer mit einem erhöhten Token ausgeführt wird, da andere Benutzer dies kommentiert haben. Hier ist eine potenzielle Alternative für die Überprüfung der Mitgliedschaft einer lokalen Administratorengruppe in einem Standard- und einem erhöhten Kontext:

bool isAdmin = false;
using (var user = WindowsIdentity.GetCurrent())
{
    var principal = new WindowsPrincipal(user);
    // Check for token claim with well-known Administrators group SID
    const string LOCAL_ADMININSTRATORS_GROUP_SID = "S-1-5-32-544";
    if (principal.Claims.SingleOrDefault(x => x.Value == LOCAL_ADMININSTRATORS_GROUP_SID) != null)
    {
        isAdmin = true;
    }
}

return isAdmin;
2
Noah Stahl

Mit WMI können Sie beispielsweise feststellen, ob es sich bei dem Konto um einen Administrator handelt und was Sie sonst noch über das Konto wissen möchten

using System;
using System.Management;
using System.Windows.Forms;

namespace WMISample
{
    public class MyWMIQuery
    {
        public static void Main()
        {
            try
            {
                ManagementObjectSearcher searcher = 
                    new ManagementObjectSearcher("root\\CIMV2", 
                    "SELECT * FROM Win32_UserAccount"); 

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Win32_UserAccount instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("AccountType: {0}", queryObj["AccountType"]);
                    Console.WriteLine("FullName: {0}", queryObj["FullName"]);
                    Console.WriteLine("Name: {0}", queryObj["Name"]);
                }
            }
            catch (ManagementException e)
            {
                MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
            }
        }
    }
}

Zum einfacheren Einstieg herunterladen WMI Creator

sie können dies auch verwenden, wenn Sie auf Active Directory (LDAP) oder auf etwas anderes auf Ihrem Computer/Netzwerk zugreifen 

1
Bob The Janitor

Es gibt 4 mögliche Methoden - ich bevorzuge:

(new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator);

Mit diesem Code erhalten Sie eine Liste aller relevanten Anspruchsdaten für die Identität Ihres aktuellen Benutzers.

HINWEIS: Es gibt einen großen Unterschied zwischen der Anspruchsliste, die zwischen WindowsPrincipal.Current . Claims und (neuem WindowsPrincipal (WindowsIdentity.GetCurrent ())) Claims zurückgegeben wird 

Console.WriteLine("press the ENTER key to start listing user claims:");
Console.ReadLine();

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
bool canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole(WindowsBuiltInRole.Administrator);
Console.WriteLine("GetCurrent IsInRole: canBeAdmin:{0}", canBeAdmin);

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).Claims.Any((c) => c.Value == "S-1-5-32-544");
Console.WriteLine("GetCurrent Claim: canBeAdmin?:{0}", canBeAdmin);

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole("Administrator");
Console.WriteLine("GetCurrent IsInRole \"Administrator\": canBeAdmin?:{0}", canBeAdmin);

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
canBeAdmin = (new WindowsPrincipal(WindowsIdentity.GetCurrent())).IsInRole("Admin");
Console.WriteLine("GetCurrent IsInRole \"Admin\": canBeAdmin?:{0}", canBeAdmin);

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
canBeAdmin = WindowsPrincipal.Current.IsInRole("Admin");
Console.WriteLine("Current IsInRole \"Admin\": canBeAdmin:{0}", canBeAdmin);


Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
canBeAdmin = WindowsPrincipal.Current.IsInRole("Administrator");
Console.WriteLine("Current IsInRole \"Administrator\": canBeAdmin:{0}", canBeAdmin);

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
canBeAdmin = WindowsPrincipal.Current.Claims.Any((c) => c.Value == "S-1-5-32-544");
Console.WriteLine("Current Claim: canBeAdmin?:{0}", canBeAdmin);

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
Console.WriteLine("WindowsPrincipal Claims:");
Console.WriteLine("---------------------");

var propertyCount = 0;
foreach (var claim in WindowsPrincipal.Current.Claims)
{
    Console.WriteLine("{0}", propertyCount++);
    Console.WriteLine("{0}", claim.ToString());
    Console.WriteLine("Issuer:{0}", claim.Issuer);
    Console.WriteLine("Subject:{0}", claim.Subject);
    Console.WriteLine("Type:{0}", claim.Type);
    Console.WriteLine("Value:{0}", claim.Value);
    Console.WriteLine("ValueType:{0}", claim.ValueType);
}

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
Console.WriteLine("WindowsPrincipal Identities Claims");
Console.WriteLine("---------------------");

propertyCount = 0;
foreach (var identity in WindowsPrincipal.Current.Identities)
{
    int subPropertyCount = 0;
    foreach (var claim in identity.Claims)
    {
        Console.WriteLine("{0} {1}", propertyCount, subPropertyCount++);
        Console.WriteLine("{0}", claim.ToString());
        Console.WriteLine("Issuer:{0}", claim.Issuer);
        Console.WriteLine("Subject:{0}", claim.Subject);
        Console.WriteLine("Type:{0}", claim.Type);
        Console.WriteLine("Value:{0}", claim.Value);
        Console.WriteLine("ValueType:{0}", claim.ValueType);
    }
    Console.WriteLine();
    propertyCount++;
}

Console.WriteLine("---------------------");
Console.WriteLine("---------------------");
Console.WriteLine("Principal Id Claims");
Console.WriteLine("---------------------");

var p = new WindowsPrincipal(WindowsIdentity.GetCurrent());
foreach (var claim in (new WindowsPrincipal(WindowsIdentity.GetCurrent())).Claims)
{
    Console.WriteLine("{0}", propertyCount++);
    Console.WriteLine("{0}", claim.ToString());
    Console.WriteLine("Issuer:{0}", claim.Issuer);
    Console.WriteLine("Subject:{0}", claim.Subject);
    Console.WriteLine("Type:{0}", claim.Type);
    Console.WriteLine("Value:{0}", claim.Value);
    Console.WriteLine("ValueType:{0}", claim.ValueType);
}

Console.WriteLine("press the ENTER key to end");
Console.ReadLine();
0
OzBob

Wie wäre es mit:

using System.Runtime.InteropServices;

internal static class Useful {
    [DllImport("Shell32.dll", EntryPoint = "IsUserAnAdmin")]
    public static extern bool IsUserAnAdministrator();
}
0
Erwin Mayer