0

ユーザーが Active Directory でグループを管理できるようにするアプリケーションを作成しています。アプリケーションにログインする必要がないように、現在ログインしているユーザーの ID を使用したいと考えています。アプリケーションはリモートで問題なく動作しますが、テスト サーバー (Windows 2008R2 IIS6) に展開した後、私の代わりに IIS APPPOOL ID を使用しようとしています。

関連する web.config 設定:

<authentication mode="Windows"></authentication>
<identity impersonate="true" />

身元を確認するコード:

Session("Username") = ActiveDirectory.GetUsername( _
    WindowsIdentity.GetCurrent.User.Translate(GetType(NTAccount)).Value _
)

ActiveDirectory はヘルパー関数のクラスであり、偽装ロジックは含まれていません。

IIS APPPOOL ユーザーではなく、アプリケーションにアクセスしているユーザーの ID を取得するにはどうすればよいですか?

4

2 に答える 2

2

アプリケーションはアプリケーション プールの ID で実行されると思います。別の ID として実行するには、ユーザーを偽装する必要があります。MSDNには、それに関する記事があります。これは、同様のことを達成するのに役立った記事に基づいて作成したクラスです。

class Impersonator : IDisposable
  {
      [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
      private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
          int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

      [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
      private extern static bool CloseHandle(IntPtr handle);

      WindowsIdentity newId;
      WindowsImpersonationContext impersonatedUser;
      private bool isDisposed;

      public Impersonator(string user, string password, string domain)
      {
          SafeTokenHandle safeTokenHandle;
          const int LOGON32_PROVIDER_DEFAULT = 0;
          //This parameter causes LogonUser to create a primary token. 
          const int LOGON32_LOGON_INTERACTIVE = 2;

          // Call LogonUser to obtain a handle to an access token. 
          bool returnValue = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out safeTokenHandle);

          newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
          impersonatedUser = newId.Impersonate();
      }

      public void Dispose()
      {

          this.Dispose(true);
          GC.SuppressFinalize(this);
      }

      public void Dispose(bool disposing)
      {
          if (!this.isDisposed)
          {
              if (disposing)
              {
                  if (impersonatedUser != null)
                  {
                      this.impersonatedUser.Dispose();
                  }

                  if (newId != null)
                  {
                      this.newId.Dispose();
                  }
              }
          }

          this.isDisposed = true;
      }

      ~Impersonator()
      {
          Dispose(false);
      }

      private sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
      {
          private SafeTokenHandle()
              : base(true)
          {
          }

          [DllImport("kernel32.dll")]
          [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
          [SuppressUnmanagedCodeSecurity]
          [return: MarshalAs(UnmanagedType.Bool)]
          private static extern bool CloseHandle(IntPtr handle);

          protected override bool ReleaseHandle()
          {
              return CloseHandle(handle);
          }
      }
  }

基本的に、ユーザーを偽装する場合はクラスの新しいインスタンスを作成し、完了したらクラスを破棄します。

これが役立つことを願っています!

于 2013-03-29T15:17:04.060 に答える
1

これがあなたがやろうとしていることの線に沿っているかどうかはわかりません。ただし、ユーザーを取得するには、次のようなものを使用します。

WindowsIdentity user = WindowsIdentity.GetCurrent();
WindowsPrincipal role = new WindowsPrincipal(user);

上記のソリューションを使用すると、実際にロールも確認したり、情報を提供するように定義Identity.Nameしたりできます。

別の解決策:

Environment.UserName;
Environment.GetEnvironmentVariable("USERNAME");

WindowsIdentityこれで、 がドメインを横断することはわかりましたが、他のドメインがActive Directoryをどのように処理するかはわかりません。したがって、 Domain Contextで何かをする必要があるかもしれません。

// Define Context
PrincipalContext context = new PrincipalContext(ContextType.Domain);

// Find User
UserPrincipal user = UserPrincipal.Current;

// Check User
if (user != null)
{
    string loginName = user.SamAccountName; // Whatever "Login Name Means"
}

ここにも良いリソースがあります:

ディレクトリ セキュリティの管理:

アカウント管理に関する MSDN ドキュメント

それがまさにあなたの意図したものかどうかはわかりませんが、お役に立てば幸いです。

于 2013-03-29T15:12:27.200 に答える