現在のユーザーが管理者かどうかを確認します


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

ayende.com/blog/158401/are-you-an-administratorまたはblogs.msdn.com/b/jaredpar/archive/2007/08/01/…についてはどうですか?どちらが良い方法ですか?
Kiquenet 2014

1
@AnkurTripathiあなたは...?
ニッシム2016

5
管理者としてアプリを実行しない限り、そのコードは機能しません。
ああ。

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

39
@Nissm:両方が同時に回答したか、「5分前」に投稿したと表示されてから5分後に回答しました。アレックスを攻撃する理由はありません。私たちは担当者を獲得するためにここにいるのではなく、支援するためにここにいます。
Randolpho

ayende.com/blog/158401/are-you-an-administratorまたはblogs.msdn.com/b/jaredpar/archive/2007/08/01/…についてはどうですか?どちらが良い方法ですか?
Kiquenet 2014

16

これを行うためにWindowsAPIを呼び出すこともできます。

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

これは、より一般的に、ユーザーが昇格された権限で実行されているかどうかを示します。


2
これは25倍でこれを行う最も速い方法です
TobiasBrohl19年

14

IsInRoleでの上記の回答は実際には正しいです:現在のユーザーが管理者権限を持っているかどうかをチェックします。しかしながら、

Windows Vista以降、ユーザーアカウント制御(UAC)がユーザーの特権を決定します。組み込みのAdministratorsグループのメンバーである場合は、標準のユーザーアクセストークンと管理者アクセストークンの2つのランタイムアクセストークンが割り当てられます。デフォルトでは、標準のユーザーロールになっています。

(MSDNから、例:https//msdn.microsoft.com/en-us/library/system.diagnostics.eventlogpermissionv = vs.110.aspx

したがって、IsInRoleはデフォルトでユーザー特権を考慮し、メソッドはfalseを返します。ソフトウェアが管理者として明示的に実行されている場合にのみ当てはまります。

https://ayende.com/blog/158401/are-you-an-administratorでADをチェックするもう1つの方法は、ユーザー名が管理者グループにあるかどうかをチェックします

したがって、両方を組み合わせた私の完全な方法は次のとおりです。

    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ロジック。


これは本当に素晴らしいですが、まだ不完全なようです。ドメインに、最終的にローカル管理者グループのメンバーであるグローバルグループがある場合はどうなりますか?それが一致するようには思えません。今日は家にいるのでこれをテストすることはできませんが、オフィスに戻ったら仕事で遊ぶかもしれません。
クリストファーペインター

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を検索している他の人にとってはページへの素晴らしい追加になると思いました。保護されたコンストラクターの背後にある私の推論により、このクラスを派生クラスとして使用して、クラスがインスタンス化されるときの状態を制御できるようになります。


ayende.com/blog/158401/are-you-an-administratorまたはblogs.msdn.com/b/jaredpar/archive/2007/08/01/…についてはどうですか?どちらが良い方法ですか?
Kiquenet 2014

0

それらを実行しているユーザーが管理者であることを確認する必要があります

アプリケーションを管理者権限で実行する必要がある場合は、マニフェストを更新するのが適切です。
に設定requestedExecutionlevelrequireAdminstratorます。


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.