vb.net IIS 模拟返回应用程序池用户

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15705817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 13:02:23  来源:igfitidea点击:

IIS impersonation returns app pool user

c#vb.netiisiis-6impersonation

提问by Phillip Copley

I am writing an application allowing users to manage groups in Active Directory. I want to use the identity of the currently logged in user so that they do not have to log into the application. The application works without issue remotely but after deploying to the test server (Windows 2008R2 IIS6) it is attempting to use the IIS APPPOOL identity instead of mine.

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

Relevant web.config settings:

相关的 web.config 设置:

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

Code to check identity:

验证身份的代码:

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

ActiveDirectory is a class of helper functions and doesn't contain any impersonation logic.

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

How can I get the identity of the user accessing the application and not the IIS APPPOOL user?

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

回答by MisterXero

I believe the application will run with the identity of the application pool. In order to run as a different identity you will need to impersonate a user. MSDNhas an article about it. Here is a class I wrote based off the article that helped me accomplish something similar.

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

Basically create a new instance of the class when you want to impersonate the user and dispose of the class when you are done.

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

I hope this helps!

我希望这有帮助!

回答by Greg

I'm not sure if this is along the lines of what you are trying to do. But to retrieve a user you would use something like this:

我不确定这是否与您正在尝试做的事情一致。但是要检索用户,您将使用以下内容:

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

With the above solution you can actually check the role as well, or define Identity.Nameto supply you the information.

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

Another solution:

另一种解决方案:

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

Now I know the WindowsIdentitywill pull across a Domainbut the others I'm not sure how they will handle Active Directory. So you might have to do something with a Domain Context.

现在我知道它们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"
}

Here are good resources as well:

这里也有很好的资源:

Managing Directory Security:

管理目录安全:

MSDN Docs On Account Management

MSDN 帐户管理文档

Not sure if that is exactly what you meant, but hope that helps.

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