IIS模拟返回应用程序池用户

时间:2013-03-29 15:00:38

标签: c# vb.net iis iis-6 impersonation

我正在编写一个允许用户管理Active Directory中的组的应用程序。我想使用当前登录用户的身份,以便他们不必登录应用程序。该应用程序可以远程运行,但在部署到测试服务器(Windows 2008R2 IIS6)后,它尝试使用IIS APPPOOL标识而不是我的标识。

相关的web.config设置:

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

检查身份的代码:

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

ActiveDirectory是一类辅助函数,不包含任何模拟逻辑。

如何获取访问应用程序的用户的身份而不是IIS APPPOOL用户?

2 个答案:

答案 0 :(得分:2)

我相信应用程序将使用应用程序池的标识运行。要以不同的身份运行,您需要模拟用户。 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);
          }
      }
  }

当您想要模仿用户并在完成后处理该类时,基本上创建该类的新实例。

我希望这有帮助!

答案 1 :(得分:1)

我不确定这是否符合您的要求。但要检索用户,您可以使用以下内容:

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

使用上述解决方案,您实际上也可以检查角色,或定义Identity.Name以便为您提供信息。

另一种解决方案:

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

现在我知道WindowsIdentity会跨越但其他人我不确定他们将如何处理 Active Directory 。因此,您可能需要对域上下文执行某些操作。

// 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"
}

这里也有很好的资源:

Managing Directory Security:

MSDN Docs On Account Management

不确定这是否与您的意思相符,但希望有所帮助。