Ứng dụng của tôi cần chạy một số tập lệnh và tôi phải chắc chắn rằng người dùng đang chạy chúng là quản trị viên ... Cách tốt nhất để thực hiện việc này bằng C # là gì?
Câu trả lời:
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);
Bạn cũng có thể gọi vào Windows API để thực hiện việc này:
[DllImport("shell32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsUserAnAdmin();
điều này sẽ cho bạn biết một cách tổng quát hơn liệu người dùng có đang chạy theo các quyền được nâng cao hay không.
Các câu trả lời ở trên với IsInRole thực sự đúng: nó kiểm tra xem người dùng hiện tại có đặc quyền quản trị viên hay không. Tuy nhiên,
Bắt đầu với Windows Vista, Kiểm soát Tài khoản Người dùng (UAC) xác định các đặc quyền của người dùng. Nếu bạn là thành viên của nhóm Quản trị viên tích hợp, bạn được chỉ định hai mã thông báo truy cập thời gian chạy: mã thông báo truy cập người dùng tiêu chuẩn và mã thông báo truy cập quản trị viên. Theo mặc định, bạn đang ở vai trò người dùng tiêu chuẩn.
(từ MSDN, ví dụ: https://msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermission(v=vs.110).aspx )
Do đó, IsInRole theo mặc định sẽ coi là đặc quyền của người dùng, và do đó phương thức trả về false. Chỉ đúng khi phần mềm được chạy rõ ràng với tư cách quản trị viên.
Phương pháp khác kiểm tra AD trong https://ayende.com/blog/158401/are-you-an-administrator sẽ kiểm tra xem tên người dùng có nằm trong nhóm quản trị viên hay không.
Do đó, phương pháp hoàn chỉnh của tôi kết hợp cả hai là:
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;
}
Đối với người dùng trong nhóm quản trị viên không có đặc quyền nâng cao (đã bật UAC), phương thức này IsCurrentUserAdmin () return! CheckCurrentRole: true nếu checkCurrentRole == false, nhưng false nếu checkCurrentRole == true
Nếu bạn chạy mã YÊU CẦU đặc quyền quản trị viên, hãy coi checkCurrentRole == true. Nếu không, bạn sẽ nhận được một ngoại lệ bảo mật vào lúc đó. Do đó logic IsInRole chính xác .
Tôi chỉ nghĩ rằng tôi sẽ thêm một giải pháp khác; vì IsInRole
không phải lúc nào cũng hoạt động.
Tùy thuộc vào nhu cầu của bạn nếu bạn cần hỗ trợ các hệ thống cũ hơn; hoặc không chắc chắn về cách khách hàng của bạn quản lý thực tế hệ thống của bạn. Đây là một giải pháp tôi đã thực hiện; để linh hoạt và thay đổi.
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.
Vì vậy, đoạn mã trên có một vài cấu trúc; nó sẽ thực sự kiểm tra xem Người dùng đang sử dụng Vista hoặc cao hơn. Bằng cách đó, nếu khách hàng đang sử dụng XP mà không có khuôn khổ hoặc khuôn khổ beta từ nhiều năm trước, nó sẽ cho phép bạn thay đổi những gì bạn muốn làm.
Sau đó, nó sẽ kiểm tra vật lý để tránh giá trị rỗng cho tài khoản.
Sau đó, cuối cùng nó sẽ cung cấp kiểm tra để xác minh rằng người dùng thực sự có vai trò thích hợp.
Tôi biết câu hỏi đã được trả lời; nhưng tôi nghĩ giải pháp của mình sẽ là một bổ sung tuyệt vời cho trang cho bất kỳ ai khác đang tìm kiếm Stack. Lý do của tôi đằng sau Trình tạo được bảo vệ sẽ cho phép bạn sử dụng lớp này như một Lớp có nguồn gốc mà bạn có thể kiểm soát trạng thái khi lớp được khởi tạo.
Đây là cách tôi kết thúc ... Tôi đang buộc ứng dụng của mình chạy ở chế độ quản trị viên. Để làm điều này
1- Thêm <ApplicationManifest>app.manifest</ApplicationManifest>
vào csproj
tệp của bạn .
MyProject.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
</Project>
2- Thêm app.manifest
tệp bên dưới vào dự án của bạn.
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>