Überprüfen Sie, ob der aktuelle Benutzer Administrator ist

80

In meiner Anwendung müssen einige Skripte ausgeführt werden, und ich muss sicher sein, dass der Benutzer, der sie ausführt, ein Administrator ist. Wie kann dies am besten mit C # durchgeführt werden?

Fliskov
quelle

Antworten:

94
using System.Security.Principal;

public static bool IsAdministrator()
{
    using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
    {
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}
Nissim
quelle
6
Nur ein Hinweis, dass das oben Genannte nicht funktioniert, wenn die Benutzerkontensteuerung in Vista oder Win7 aktiviert ist. In diesem Fall müssen Sie ein UAC-Bestätigungsfeld öffnen und die Berechtigungen erhöhen.
MisterZimbu
1
@AnkurTripathi Bist du ...?
Nissim
4
Dieser Code funktioniert nur, wenn Sie die App als Administrator ausführen.
AH.
34
return new WindowsPrincipal(WindowsIdentity.GetCurrent())
    .IsInRole(WindowsBuiltInRole.Administrator);
Alex Reitbort
quelle
38
@Nissm: Sie haben beide gleichzeitig oder fast 5 Minuten nach der Tatsache geantwortet, dass Sie beide als "vor 5 Minuten" gepostet haben. Es gibt keinen Grund für dich, Alex anzugreifen. Wir sind nicht hier, um Repräsentanten zu verdienen, wir sind hier, um zu helfen.
Randolpho
14

Sie können dazu auch die Windows-API aufrufen:

[DllImport("shell32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsUserAnAdmin();

Hier erfahren Sie allgemeiner, ob der Benutzer unter erhöhten Rechten ausgeführt wird.

Rick Strahl
quelle
2
Dies ist um den Faktor 25 die schnellste Methode, um dies zu tun
Tobias Brohl
14

Die obigen Antworten mit IsInRole sind tatsächlich richtig: Es wird geprüft , ob der aktuelle Benutzer über Administratorrechte verfügt. Jedoch,

Ab Windows Vista bestimmt die Benutzerkontensteuerung (User Account Control, UAC) die Berechtigungen eines Benutzers. Wenn Sie Mitglied der Gruppe "Integrierte Administratoren" sind, werden Ihnen zwei Laufzeitzugriffstoken zugewiesen: ein Standardbenutzerzugriffstoken und ein Administratorzugriffstoken. Standardmäßig befinden Sie sich in der Standardbenutzerrolle.

(von MSDN, z. B. https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermission(v=vs.110).aspx )

Daher berücksichtigt IsInRole standardmäßig die Benutzerberechtigung, und daher gibt die Methode false zurück. Nur wahr, wenn die Software explizit als Administrator ausgeführt wird.

Die andere Methode zur Überprüfung von AD unter https://ayende.com/blog/158401/are-you-an-administrator überprüft, ob sich der Benutzername in einer Administratorgruppe befindet.

Meine vollständige Methode, die beide kombiniert, lautet also:

    public static bool IsCurrentUserAdmin(bool checkCurrentRole = true)
    {
        bool isElevated = false;

        using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
        {
            if (checkCurrentRole)
            {
                // Even if the user is defined in the Admin group, UAC defines 2 roles: one user and one admin. 
                // IsInRole consider the current default role as user, thus will return false!
                // Will consider the admin role only if the app is explicitly run as admin!
                WindowsPrincipal principal = new WindowsPrincipal(identity);
                isElevated = principal.IsInRole(WindowsBuiltInRole.Administrator);
            }
            else
            {
                // read all roles for the current identity name, asking ActiveDirectory
                isElevated = IsAdministratorNoCache(identity.Name);
            }
        }

        return isElevated;
    }

    /// <summary>
    /// Determines whether the specified user is an administrator.
    /// </summary>
    /// <param name="username">The user name.</param>
    /// <returns>
    ///   <c>true</c> if the specified user is an administrator; otherwise, <c>false</c>.
    /// </returns>
    /// <seealso href="https://ayende.com/blog/158401/are-you-an-administrator"/>
    private static bool IsAdministratorNoCache(string username)
    {
        PrincipalContext ctx;
        try
        {
            Domain.GetComputerDomain();
            try
            {
                ctx = new PrincipalContext(ContextType.Domain);
            }
            catch (PrincipalServerDownException)
            {
                // can't access domain, check local machine instead 
                ctx = new PrincipalContext(ContextType.Machine);
            }
        }
        catch (ActiveDirectoryObjectNotFoundException)
        {
            // not in a domain
            ctx = new PrincipalContext(ContextType.Machine);
        }
        var up = UserPrincipal.FindByIdentity(ctx, username);
        if (up != null)
        {
            PrincipalSearchResult<Principal> authGroups = up.GetAuthorizationGroups();
            return authGroups.Any(principal =>
                                  principal.Sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid) ||
                                  principal.Sid.IsWellKnown(WellKnownSidType.AccountDomainAdminsSid) ||
                                  principal.Sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) ||
                                  principal.Sid.IsWellKnown(WellKnownSidType.AccountEnterpriseAdminsSid));
        }
        return false;
    }

Für einen Benutzer in einer Administratorgruppe ohne erhöhte Berechtigung (UAC aktiviert) gibt diese Methode IsCurrentUserAdmin ()! CheckCurrentRole zurück: true, wenn checkCurrentRole == false, aber false, wenn checkCurrentRole == true

Wenn Sie Code ausführen, für den Administratorrechte erforderlich sind, berücksichtigen Sie checkCurrentRole == true. Andernfalls erhalten Sie bis dahin eine Sicherheitsausnahme. Daher die richtige IsInRole- Logik.

EricBDev
quelle
Das ist wirklich schön, scheint aber immer noch unvollständig zu sein. Was wäre, wenn die Domäne eine globale Gruppe hätte, die letztendlich Mitglied der lokalen Administratorgruppe wäre? Es scheint nicht so, als würde das zusammenpassen. Ich kann das heute nicht testen, da ich zu Hause bin, aber vielleicht spiele ich bei der Arbeit damit, wenn ich wieder im Büro bin.
Christopher Painter
2

Ich dachte nur, ich würde eine andere Lösung hinzufügen. da das IsInRolenicht immer funktioniert.

  • Wenn der Benutzer in der aktuellen Sitzung kein Mitglied der angegebenen Windows-Benutzergruppe ist.
  • Der Administrator hat Änderungen in den Gruppenrichtlinieneinstellungen vorgenommen
  • Der Rollenparameter wird als "Groß- und Kleinschreibung beachten" behandelt.
  • Und wenn auf einem XP-Computer die .NET Framework-Version nicht installiert ist, funktioniert dies nicht.

Abhängig von Ihren Anforderungen, wenn Sie ältere Systeme unterstützen müssen. oder sind sich nicht sicher, wie Ihr Client Ihr System physisch verwaltet. Dies ist eine Lösung, die ich implementiert habe. für Flexibilität und Änderungen.

class Elevated_Rights
    {

        // Token Bool:
        private bool _level = false;

        #region Constructor:

        protected Elevated_Rights()
        {

            // Invoke Method On Creation:
            Elevate();

        }

        #endregion

        public void Elevate()
        {

            // Get Identity:
            WindowsIdentity user = WindowsIdentity.GetCurrent();

            // Set Principal
            WindowsPrincipal role = new WindowsPrincipal(user);

            #region Test Operating System for UAC:

            if (Environment.OSVersion.Platform != PlatformID.Win32NT || Environment.OSVersion.Version.Major < 6)
            {

                // False:
                _level = false;

                // Todo: Exception/ Exception Log

            }

            #endregion

            else
            {

                #region Test Identity Not Null:

                if (user == null)
                {

                    // False:
                    _level = false;

                    // Todo: "Exception Log / Exception"

                }

                #endregion

                else
                {

                    #region Ensure Security Role:

                    if (!(role.IsInRole(WindowsBuiltInRole.Administrator)))
                    {

                        // False:
                        _level = false;

                        // Todo: "Exception Log / Exception"

                    }

                    else
                    {

                        // True:
                        _level = true;

                    }

                    #endregion


                } // Nested Else 'Close'

            } // Initial Else 'Close'

        } // End of Class.

Der obige Code enthält also einige Konstrukte. Es wird tatsächlich getestet, ob der Benutzer Vista oder höher verwendet. Auf diese Weise können Sie ändern, was ein Benutzer tun möchte, wenn er unter XP ist und seit Jahren kein Framework oder Beta-Framework mehr hat.

Anschließend wird physisch getestet, um einen Nullwert für das Konto zu vermeiden.

Als letztes wird dann überprüft, ob der Benutzer tatsächlich die richtige Rolle spielt.

Ich weiß, dass die Frage beantwortet wurde. Aber ich dachte, meine Lösung wäre eine großartige Ergänzung der Seite für alle anderen, die nach Stack suchen. Meine Überlegungen hinter dem geschützten Konstruktor würden es Ihnen ermöglichen, diese Klasse als abgeleitete Klasse zu verwenden, mit der Sie den Status steuern können, in dem die Klasse instanziiert wird.

Greg
quelle
0

Ich muss sicher sein, dass der Benutzer, der sie ausführt, ein Administrator ist

Wenn Ihre Anwendung mit Administratorrechten ausgeführt werden muss, ist es richtig, ihr Manifest zu aktualisieren.
Set requestedExecutionlevelzu requireAdminstrator.

Qwertiy
quelle
0

So komme ich zum Ende ... Ich zwinge meine App, als Administratormodus ausgeführt zu werden. Um dies zu tun

1- Fügen Sie <ApplicationManifest>app.manifest</ApplicationManifest>Ihrem hinzucsproj Datei hinzufügen.

MyProject.csproj

<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>    
</Project>

2- Fügen Sie das Folgende hinzu app.manifest Datei zu Ihrem Projekt hinzu.

app.manifest

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
Alper Ebicoglu
quelle