현재 사용자가 관리자인지 확인


82

내 응용 프로그램에서 일부 스크립트를 실행해야하고 스크립트를 실행하는 사용자가 관리자인지 확인해야합니다. C #을 사용하여이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

답변:


96
using System.Security.Principal;

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

6
위의 내용은 Vista 또는 Win7에서 UAC가 활성화 된 경우 작동하지 않습니다. 이 경우 UAC 확인 상자를 표시하고 권한을 높여야합니다.
MisterZimbu 2010 년


1
@AnkurTripathi 당신은 ...?
Nissim

5
이 코드는 관리자 권한으로 앱을 실행하지 않으면 작동하지 않습니다.
AH.

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

39
@Nissm : 두 사람이 동시에 답변했거나 "5 분 전"게시 한 것으로 등록 된 후 5 분 이내에 답변했습니다. Alex를 공격 할 이유가 없습니다. 우리는 담당자를 얻기 위해 여기있는 것이 아니라 도움을주기 위해 여기에 있습니다.
Randolpho


16

이를 위해 Windows API를 호출 할 수도 있습니다.

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

더 일반적으로 사용자가 상승 된 권한으로 실행되고 있는지 여부를 알려줍니다.


2
이것은 25의 요인에 의해이 일의 가장 빠른 방법입니다
토비아스 BROHL

14

IsInRole에 대한 위의 답변 은 실제로 정확합니다. 현재 사용자에게 관리자 권한이 있는지 확인합니다. 하나,

Windows Vista부터 UAC (사용자 계정 컨트롤)는 사용자의 권한을 결정합니다. 기본 제공 관리자 그룹의 구성원 인 경우 표준 사용자 액세스 토큰과 관리자 액세스 토큰의 두 가지 런타임 액세스 토큰이 할당됩니다. 기본적으로 표준 사용자 역할에 있습니다.

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

따라서 IsInRole 은 기본적으로 사용자 권한을 고려하므로 메서드는 false를 반환합니다. 소프트웨어가 관리자 권한으로 명시 적으로 실행되는 경우에만 해당됩니다.

https://ayende.com/blog/158401/are-you-an-administrator 에서 AD를 확인하는 다른 방법 은 사용자 이름이 관리자 그룹에 있는지 확인합니다.

두 가지를 결합하는 완전한 방법은 다음과 같습니다.

    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;
    }

상승 된 권한 (UAC 활성화 됨)이없는 관리자 그룹의 사용자의 경우이 메서드 IsCurrentUserAdmin ()은! checkCurrentRole을 반환합니다. checkCurrentRole == false이면 true, checkCurrentRole == true이면 false입니다.

관리자 권한이 필요한 코드를 실행하는 경우 checkCurrentRole == true를 고려하십시오. 그렇지 않으면 그때까지 보안 예외가 발생합니다. 따라서 올바른 IsInRole 논리입니다.


이것은 정말 좋지만 여전히 불완전한 것 같습니다. 도메인에 궁극적으로 로컬 관리자 그룹의 구성원 인 글로벌 그룹이있는 경우 어떻게됩니까? 일치하지 않는 것 같습니다. 오늘은 집에 있기 때문에 테스트 할 수 없지만 사무실에 돌아 오면 직장에서 가지고 놀 수있을 것입니다.
Christopher Painter 19 년

2

다른 솔루션을 추가 할 것이라고 생각했습니다. IsInRole항상 작동 하는 것은 아닙니다.

  • 사용자가 현재 세션에서 지정된 Windows 사용자 그룹의 구성원이 아닌 경우.
  • 관리자가 그룹 정책 설정을 변경했습니다.
  • 역할 매개 변수는 '대소 문자 구분'방법으로 처리됩니다.
  • XP 컴퓨터에 .NET Framework 버전이 설치되어 있지 않으면 작동하지 않습니다.

필요에 따라 이전 시스템을 지원해야하는 경우; 또는 클라이언트가 시스템을 물리적으로 어떻게 관리하고 있는지 확실하지 않습니다. 이것은 내가 구현 한 솔루션입니다. 유연성과 변경을 위해.

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.

따라서 위의 코드에는 몇 가지 구조가 있습니다. 실제로 사용자가 Vista 이상을 사용하는지 테스트합니다. 이렇게하면 고객이 몇 년 전의 프레임 워크 또는 베타 프레임 워크없이 XP를 사용하는 경우 원하는 작업을 변경할 수 있습니다.

그런 다음 계정의 null 값을 피하기 위해 물리적으로 테스트합니다.

그런 다음 마지막으로 사용자가 실제로 적절한 역할에 있는지 확인하는 검사를 제공합니다.

나는 질문에 대한 답을 알고 있습니다. 하지만 내 솔루션이 Stack을 검색하는 다른 사람을 위해 페이지에 큰 도움이 될 것이라고 생각했습니다. Protected Constructor에 대한 저의 추론은이 클래스를 클래스가 인스턴스화 될 때의 상태를 제어 할 수있는 파생 클래스로 사용할 수 있도록합니다.



0

이를 실행하는 사용자가 관리자인지 확인해야합니다.

애플리케이션을 관리자 권한으로 실행해야하는 경우 매니페스트를 업데이트하는 것이 좋습니다.
로 설정 requestedExecutionlevel합니다 requireAdminstrator.


0

이것이 내가 끝내는 방법 ... 내 앱이 관리자 모드로 실행되도록 강제합니다. 이것을하기 위해

추가 1 <ApplicationManifest>app.manifest</ApplicationManifest>당신에 csproj파일.

MyProject.csproj

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

2- app.manifest프로젝트에 아래 파일을 추가하십시오 .

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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.