【问题标题】:Getting list of AD Groups fails when ran on server在服务器上运行时获取 AD 组列表失败
【发布时间】:2018-10-18 12:21:45
【问题描述】:

我在 IIS 上的同一台服务器上托管了一个网站和 API。在 API (.NET) 中,我需要获取正在使用该网站的用户所属的 AD 组列表。它在本地工作(邮递员调用 IIS Express 上的 API),但在我们的服务器上运行时却不能。获取广告组的代码是这样的:

            string[] output = null;
            string username = GetUserName();
            using (var ctx = new PrincipalContext(ContextType.Domain))
            using (var user = UserPrincipal.FindByIdentity(ctx, username))
            {
                if (user != null)
                {
                    output = user.GetGroups() //this returns a collection of principal objects
                        .Select(x => x.SamAccountName) // select the name.  you may change this to choose the display name or whatever you want
                        .ToArray(); // convert to string array
                }
            }

用户名被正确识别,并且在 localhost 和服务器上传递了相同的值,所以这不是问题。线路:

using (var user = UserPrincipal.FindByIdentity(ctx, username))

返回异常:

类型异常 'System.DirectoryServices.DirectoryServicesCOMException' 发生在 System.DirectoryServices.AccountManagement.dll 但未在其中处理 用户代码

这可能是 IIS 设置中的问题,但我不知道是什么。我尝试将 DefaultAppPool 的标识(Web 和 API 分配到的应用程序池)设置为 NetworkService,但没有帮助。

【问题讨论】:

标签: c# .net windows active-directory


【解决方案1】:

如果您还没有启用 Windows 身份验证,则需要启用。说明在这里:https://support.microsoft.com/en-in/help/323176/how-to-implement-windows-authentication-and-authorization-in-asp-net

但基本的想法是你在 web.config 中使用它:

<system.webServer>
  <security>
    <authentication>
      <windowsAuthentication enabled="true" />
      <anonymousAuthentication enabled="false" />
    </authentication>
  </security>
</system.webServer>

那么你可以用这个来获取当前用户的UserPrincipal对象:

UserPrincipal.FindByIdentity(domain, User.Identity.Name)

但是您可能仍然会遇到正在使用的帐户的问题,因为您的网站还需要使用域凭据向 AD 进行身份验证。

DefaultAppPool 使用服务器本地的帐户,AD 无法识别。您可以在 PrincipalContext 构造函数中传递 AD 凭据,如下所示:

using (var ctx = new PrincipalContext(ContextType.Domain, null, "username", "password"))

我以为 NetworkService 使用 AD 计算机帐户进行身份验证,但可能您的服务器没有加入域?如果不是,那么您还需要在PrincipalContext 中指定域名:

using (var ctx = new PrincipalContext(ContextType.Domain, "domain.com", "username", "password"))

当您在 IIS Express 中本地运行它时它可以工作,因为 IIS Express 在您的凭据下运行并使用您的凭据向 AD 进行身份验证。

【讨论】:

  • 我想以单点登录的方式执行此操作。用户不登录应用程序,他们只是通过 Windows 身份验证获得授权。我还将 ApplicationPool 更改为 .NET v4.5 Classic,但它也不起作用。在这种情况下有没有办法做到这一点?
  • 对,我错过了问题的那一部分。我更新了我的答案。
  • 谢谢。我认为 Windows 身份验证背后的整个想法是我不必传递用户的密码?无论如何,我没有用户密码,因为我只使用 Windows 身份验证。我应该创建一些服务用户来查询 AD 吗?服务器和客户端都属于同一个域,我尝试使用具有 NetworkService 身份的不同 ApplicationPools。
  • 好的,知道了。最后缺少的部分是在 UserPrincipal.FindByIdentity 之前的 HostingEnvironment.Impersonate(),现在它可以工作了。谢谢你:)
猜你喜欢
  • 2020-10-28
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 2016-12-11
  • 2021-11-30
  • 2011-10-16
  • 2011-06-03
  • 2013-06-14
相关资源
最近更新 更多