简体   繁体   English

仅在服务器上查询Active Directory时出错

[英]Getting Error Querying Active Directory On The Server Only

I have the following block of code that queries Active Directory for users by Group Name using System.DirectoryServices.AccountManagement : 我有以下代码块,使用System.DirectoryServices.AccountManagement通过组名向Active Directory查询用户:

var domainContext = new PrincipalContext(ContextType.Domain, "company.container.internal");
var groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, IdentityType.Name, "Lvl1Users");
if (groupPrincipal != null)
{
  //Read the values
}

Now the site uses the following: 现在,该网站使用以下内容:

  • IIS7 on Win2k8 Win2k8上的IIS7
  • Windows Authentication Windows验证
  • Impersonation = True 假冒=真
  • App Pool on .NET 4.0 using 'NETWORK SERVICE' as the account 使用“网络服务”作为帐户的.NET 4.0上的应用程序池

On my local machine (you know how this goes) it all works great. 在我的本地计算机上(您知道如何运行),一切都很好。 My peers that try it locally also it works well. 在本地尝试的同行们也很好用。 However once deployed to the server it shows the following: 但是,一旦部署到服务器,它将显示以下内容:

An operations error occurred. 发生操作错误。

Everything I research says it's a permissions issue. 我研究的所有内容都说这是权限问题。 1 thing to note, on my local machine I'm on the MainNetwork domain which is the parent to company.container.internal domain which I am querying. 需要注意的一件事是,在本地计算机上,我位于MainNetwork域上,该域是我正在查询的company.container.internal域的父级。 The IIS machine is on company.container.internal and is querying the same domain. IIS计算机位于company.container.internal并且正在查询同一域。 So honestly, I would think the more challenging situation is reading AD on my local machine which is on a different domain, but it works. 坦白说,我认为更具挑战性的情况是在本地计算机上读取AD,该本地计算机位于其他域中,但是可以正常工作。 On the server which is querying the same domain, it fails. 在查询相同域的服务器上,它失败。

Here is what I've tried, and none of these has worked: 这是我尝试过的, 但没有一个起作用:

  • Change AppPool to 'LocalSystem' 将AppPool更改为“ LocalSystem”
  • Change AppPool to use a static super-duper Admin account 更改AppPool以使用静态超级管理员帐户
  • Used Impersonation in code to manipulate the context of the calls in a local block with an admin user on the MainNetwork domain. 在代码中使用模拟来与MainNetwork域上的admin用户一起操纵本地块中的调用上下文。
  • Used Impersonation in code to manipulate the context of the calls in a local block with an admin user on the company.container.internal domain. 在代码中使用了模拟,以与company.container.internal域上的管理员用户一起在本地块中操纵调用的上下文。
  • Adding in using (HostingEnvironment.Impersonate()) using (HostingEnvironment.Impersonate())

What gives here? 这里有什么? I have tried impersonating every type of power admin on both domains, and used multiple AppPool settings, and I keep getting the same error. 我尝试在两个域上模拟每种类型的电源管理员,并使用了多个AppPool设置,但我始终遇到相同的错误。 Is there anything that needs to change in the code with the declaration of the domains, or is there a permissions issue I'm missing? 域声明中是否需要更改代码中的任何内容,或者我缺少权限问题?

I figured this out and it turned out that using HostingEnvironment.Impersonate() was still at the root to solve the problem. 我发现了这一点,结果发现使用HostingEnvironment.Impersonate()仍然是解决问题的根源。 I had already tried this, but there was another issue with my code. 我已经尝试过了,但是我的代码还有另一个问题。

The issue is often that the context for which the Active Directory calls is made is under a user that does not have permissions (also can happen when identity impersonate="true" in ASP.NET, due to the fact that the users token is a "secondary token" that cannot be used when authenticating against another server from: http://bit.ly/1753RjA ). 问题常常是,进行Active Directory调用的上下文是在没有权限的用户下进行的(由于用户令牌是一个事实,因此在ASP.NET中,如果identity impersonate="true"也会发生这种情况)通过以下网址对另一台服务器进行身份验证时无法使用的“辅助令牌”: http : //bit.ly/1753RjA )。

The following code will ensures that the block of code running, is run under the context of say the AppPool (ie NETWORKSERVICE ) that the ASP.NET site is running under. 下面的代码将确保运行该代码块是在运行ASP.NET站点的AppPool (即NETWORKSERVICE )的上下文中运行的。

using (HostingEnvironment.Impersonate())
{
   var domainContext = new PrincipalContext(ContextType.Domain, "myDomain.com");
   var groupPrincipal = GroupPrincipal.FindByIdentity(domainContext, IdentityType.Name, "PowerUsers");
   if (groupPrincipal != null)
   {
      //code to get the infomation
   }

}

However, one super important detail is that all the code calling Active Directory must be in that block. 但是,一个非常重要的细节是, 所有调用Active Directory的代码都必须在该块中。 I had used some code a team member of mine wrote that was returning a LINQ query results of type Users (custom class), but not evaluating the expression (bad practice). 我曾经使用过我的一个团队成员编写的一些代码,该代码返回类型为Users (自定义类)的LINQ查询结果,但未评估表达式(错误的做法)。 Therefore the expression tree was returned instead of the results. 因此,返回了表达式树而不是结果。

What ended up happening is the calling code eventually evaluated the results and the An operations error occurred message still appeared. 最终发生的是调用代码最终评估了结果,并且仍然出现“ An operations error occurred消息。 I though the code fix above didn't work. 我虽然上面的代码修复不起作用。 When in fact it did, but there was code evaluating the results outside the block. 实际上确实可以,但是有代码在块外评估结果。

In a nutshell, make sure all code to access Active Directory is inside that using block and the exception should be fixed one the service/app is deployed to the server. 简而言之,请确保所有用于访问Active Directory的代码都在using块的内部,并且应该修复将服务/应用程序部署到服务器的异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM