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?
c#
windows-administration
Fliskov
quelle
quelle
return new WindowsPrincipal(WindowsIdentity.GetCurrent()) .IsInRole(WindowsBuiltInRole.Administrator);
quelle
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.
quelle
Die obigen Antworten mit IsInRole sind tatsächlich richtig: Es wird geprüft , ob der aktuelle Benutzer über Administratorrechte verfügt. Jedoch,
(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.
quelle
Ich dachte nur, ich würde eine andere Lösung hinzufügen. da das
IsInRole
nicht immer funktioniert.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.
quelle
Wenn Ihre Anwendung mit Administratorrechten ausgeführt werden muss, ist es richtig, ihr Manifest zu aktualisieren.
Set
requestedExecutionlevel
zurequireAdminstrator
.quelle
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>
quelle