146

.NET でユーザーを偽装する簡単な方法はありますか?

これまでのところ、すべての偽装要件に対して、コード プロジェクトのこのクラスを使用してきました。

.NET Framework を使用してそれを行うより良い方法はありますか?

偽装する必要がある ID を表すユーザー資格情報セット (ユーザー名、パスワード、ドメイン名) があります。

4

7 に答える 7

320

.NET 空間での「偽装」とは、通常、特定のユーザー アカウントでコードを実行することを意味します。これは、ユーザー名とパスワードを介してそのユーザー アカウントにアクセスすることとは多少異なる概念ですが、これら 2 つの概念は頻繁に組み合わされます。両方について説明し、次にそれらを内部で使用するSimpleImpersonationライブラリの使用方法を説明します。

なりすまし

System.Security.Principal偽装用の API は、名前空間を介して .NET で提供されます。

  • 新しいコード (.NET 4.6+、.NET Core など) は通常WindowsIdentity.RunImpersonated、ユーザー アカウントのトークンへのハンドルを受け入れる を使用し、コードを実行するためにActionまたはを使用する必要があります。Func<T>

    WindowsIdentity.RunImpersonated(tokenHandle, () =>
    {
        // do whatever you want as this user.
    });
    

    また

    var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
    {
        // do whatever you want as this user.
        return result;
    });
    
  • 古いコードでは、このメソッドを使用してオブジェクトWindowsIdentity.Impersonateを取得していました。WindowsImpersonationContextこのオブジェクトは を実装しているため、通常はブロックIDisposableから呼び出す必要があります。using

    using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
    {
        // do whatever you want as this user.
    }
    

    この API は .NET Framework にまだ存在しますが、通常は避けるべきであり、.NET Core または .NET Standard では使用できません。

ユーザー アカウントへのアクセス

ユーザー名とパスワードを使用して Windows のユーザー アカウントにアクセスするためのLogonUserAPI は、Win32 ネイティブ API です。現在、それを呼び出すための組み込みの .NET API がないため、P/Invoke に頼る必要があります。

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

これは基本的な呼び出し定義ですが、本番環境で実際に使用するには、さらに多くの考慮事項があります。

  • 「安全な」アクセス パターンでハンドルを取得します。
  • ネイティブ ハンドルを適切に閉じる
  • コード アクセス セキュリティ (CAS) の信頼レベル (.NET Framework のみ)
  • SecureStringユーザーのキーストロークで安全に収集できる場合は合格です。

これらすべてを説明するために記述するコードの量は、StackOverflow の回答、IMHO にあるはずのものを超えています。

組み合わせたより簡単なアプローチ

このすべてを自分で作成する代わりに、私のSimpleImpersonationライブラリを使用することを検討してください。これは、偽装とユーザー アクセスを 1 つの API にまとめたものです。同じ単純な API を使用して、最新のコード ベースと古いコード ベースの両方でうまく機能します。

var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
}); 

また

var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
    // do whatever you want as this user.
    return something;
});

APIと非常によく似ていWindowsIdentity.RunImpersonatedますが、トークン ハンドルについての知識は必要ありません。

これはバージョン 3.0.0 の API です。詳細については、プロジェクトの readme を参照してください。ライブラリの以前のバージョンでは、 のIDisposableようなパターンの API を使用していたことにも注意してくださいWindowsIdentity.Impersonate。新しいバージョンははるかに安全であり、両方ともまだ内部で使用されています。

于 2011-08-30T21:39:17.017 に答える
62

ここでは、.NET 偽装の概念の概要を説明します。

基本的に、.NET フレームワークですぐに使用できるこれらのクラスを利用します。

ただし、コードはしばしば長くなる可能性があるため、プロセスを簡素化しようとする参照のような多くの例が見られます。

于 2008-09-24T04:01:16.917 に答える
21

これはおそらくあなたが望むものです:

using System.Security.Principal;
using(WindowsIdentity.GetCurrent().Impersonate())
{
     //your code goes here
}

しかし、あなたを助けるためにもっと詳細が必要です。構成ファイルを使用して (Web サイトでこれを実行しようとしている場合)、または WCF サービスの場合はメソッド デコレータ (属性) を使用して偽装を行うことができます。

また、特定のサービス (ま​​たは Web アプリ) を呼び出したクライアントの偽装について話している場合は、適切なトークンを渡すようにクライアントを正しく構成する必要があります。

最後に、委任が本当に必要な場合は、ユーザーとマシンが委任に対して信頼されるように、AD を正しくセットアップする必要もあります。

編集:別のユーザーになりすます方法と詳細なドキュメントについては、こちら
をご覧 ください。

于 2008-09-24T04:04:15.740 に答える