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?
Antworten:
using System.Security.Principal;
public static bool IsAdministrator()
{
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
{
WindowsPrincipal principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
return new WindowsPrincipal(WindowsIdentity.GetCurrent())
.IsInRole(WindowsBuiltInRole.Administrator);
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.
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.
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.
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>