Kiểm tra xem người dùng hiện tại có phải là quản trị viên không


82

Ứ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:


95
using System.Security.Principal;

public static bool IsAdministrator()
{
    using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
    {
        WindowsPrincipal principal = new WindowsPrincipal(identity);
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
    }
}

6
Chỉ cần lưu ý rằng những điều trên sẽ không hoạt động nếu UAC được bật trong Vista hoặc Win7; bạn sẽ cần bật lên hộp xác nhận UAC và nâng cao quyền trong trường hợp đó.
MisterZimbu


1
@AnkurTripathi Bạn có phải là ...?
Nissim

5
Mã đó sẽ không hoạt động trừ khi bạn chạy ứng dụng với tư cách quản trị viên.
À.

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

39
@Nissm: Cả hai bạn đều trả lời đồng thời hoặc gần đủ 5 phút sau khi cả hai được liệt kê là đã đăng "5 phút trước". Không có lý do gì để bạn tấn công Alex; chúng tôi không ở đây để kiếm đại diện, chúng tôi ở đây để trợ giúp.
Randolpho


16

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.


2
Đây là một yếu tố của 25 phương pháp nhanh nhất để làm điều này
Tobias BROHL

14

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 .


Điều này thực sự tốt đẹp nhưng dường như vẫn chưa hoàn thiện. Điều gì sẽ xảy ra nếu miền có nhóm toàn cầu cuối cùng là thành viên của nhóm quản trị viên cục bộ? Có vẻ như điều đó không phù hợp. Tôi không thể kiểm tra điều này hôm nay vì tôi đang ở nhà nhưng có lẽ tôi sẽ chơi với nó tại nơi làm việc khi tôi trở lại văn phòng.
Christopher Painter

2

Tôi chỉ nghĩ rằng tôi sẽ thêm một giải pháp khác; vì IsInRolekhông phải lúc nào cũng hoạt động.

  • Nếu người dùng không phải là thành viên của Nhóm người dùng Windows được chỉ định trong phiên hiện tại.
  • Quản trị viên đã thực hiện các thay đổi trong Cài đặt Chính sách Nhóm
  • Tham số vai trò được coi là phương pháp 'Phân biệt chữ hoa chữ thường'.
  • Và nếu máy XP không được cài đặt Phiên bản .NET Framework thì nó sẽ khô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.



0

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

Nếu ứng dụng của bạn phải được chạy với quyền quản trị, bạn có quyền cập nhật tệp kê khai của nó.
Đặt requestedExecutionlevelthành requireAdminstrator.


0

Đâ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 csprojtệ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.manifesttệ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>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.