C# 在服务器上运行时,获取广告组列表失败

C# 在服务器上运行时,获取广告组列表失败,c#,.net,windows,active-directory,C#,.net,Windows,Active Directory,我有一个网站和API托管在IIS的同一台服务器上。在API(.NET)中,我需要获取使用网站的用户所属的广告组列表。它在本地工作(在IIS Express上由邮递员调用API),但在我们的服务器上运行时不起作用。获取广告群的代码如下: string[] output = null; string username = GetUserName(); using (var ctx = new PrincipalContext(C

我有一个网站和API托管在IIS的同一台服务器上。在API(.NET)中,我需要获取使用网站的用户所属的广告组列表。它在本地工作(在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
                }
            }
正确识别用户名,并在本地主机和服务器上传递相同的值,所以这不是问题。行:

using (var user = UserPrincipal.FindByIdentity(ctx, username))
返回一个异常:

类型的例外 在中发生“System.DirectoryServices.DirectoryServicesCOMException” System.DirectoryServices.AccountManagement.dll,但未在中处理 用户代码


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

如果尚未启用Windows身份验证,则需要启用Windows身份验证。说明如下:

但基本思想是在web.config中使用:

<system.webServer>
  <security>
    <authentication>
      <windowsAuthentication enabled="true" />
      <anonymousAuthentication enabled="false" />
    </authentication>
  </security>
</system.webServer>
但是,由于您的网站还需要使用域凭据对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进行身份验证。

如果您尝试了,它可能会重复,但不起作用。如果我使用DefaultAppPool与此有任何关系,请不要介意,但我还是希望在路上以单号的形式完成这项工作。用户不登录应用程序,他们只是通过Windows身份验证获得授权。我还将ApplicationPool更改为.NETV4.5Classic,但它也不起作用。在这种情况下,有没有办法做到这一点?对,我错过了问题的那一部分。我更新了我的答案。谢谢。我认为Windows身份验证背后的整个想法是我不必传递用户的密码?无论如何,我没有用户密码,因为我只使用Windows身份验证。我应该为查询广告创建一些服务用户吗?服务器和客户端都是同一个域的一部分,我尝试使用具有NetworkService标识的不同应用程序池。好的,明白了。最后一个缺少的部分是HostingEnvironment.Impersonate(),在UserPrincipal.FindByIdentity之前,它现在可以工作了。谢谢:)
using (var ctx = new PrincipalContext(ContextType.Domain, "domain.com", "username", "password"))