web-dev-qa-db-ja.com

Active Directory COM例外-操作エラーが発生しました(0x80072020)

メソッドGroupPrincipal.FindByIdentityを使用してActive Directoryをクエリしようとすると、断続的なCOM例外 "操作エラーが発生しました(0x80072020)"(下図)が表示されます。

ここに私のコードがあります:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, Environment.UserDomainName);
GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, "Group to find");

私は例外を受け取っています:

Inner Exception: System.Runtime.InteropServices.COMException (0x80072020): An operations error occurred.
  at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
  at System.DirectoryServices.DirectoryEntry.Bind()
  at System.DirectoryServices.DirectoryEntry.get_AdsObject()
  at System.DirectoryServices.PropertyValueCollection.PopulateList()
  at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
  at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
  at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer()
  at System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit()
  at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
  at System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx()
  at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithTypeHelper(PrincipalContext context, Type principalType, Nullable`1 identityType, String identityValue, DateTime refDate)
  at System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType(PrincipalContext context, Type principalType, IdentityType identityType, String identityValue)
  at System.DirectoryServices.AccountManagement.GroupPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)

コードは、Windowsサービス/Windows 2003 SP2サーバーから実行されています。

別のスタックオーバーフローの質問 Active Directory、ユーザーグループの列挙、COM例外 を見つけました。これは、Kerberosを有効にすることを示唆しています PrincipalContextコンストラクターのオプションとしてこの問題を修正しますが、 この質問とは異なる16進コード

私の質問は

  1. この特定のCOM例外は間違いなく認証の問題ですか?ソフトウェアをリリースする前に、これにより問題が100%修正されることを確認する必要があります。
  2. 将来的に少しでも良くできるように、可能なすべてのCOM例外16進コードをリストするリソースがどこかにありますか?
27
ghostJago

私は今、別の答えを見つけました Dynamics CRMのCrmService APIでユーザーを追加できません 0x80072020が実際に許可の問題であると述べています。ローカルシステムアカウントではなくドメインレベルアカウントで実行するようにサービスを変更しましたが、これで問題が解決したようです。

19
ghostJago

問題は、多くの場合、Active Directory呼び出しが行われるコンテキストが、権限を持たないユーザーの下にあることです(identity impersonate="true" ASP.NETでは、ユーザートークンは次のサーバーからの認証時に使用できない「セカンダリトークン」であるため、 https://social.technet.Microsoft.com/Forums/ en-US/f188029c-51cf​​-4b50-966a-eee7160d0353/an-operations-error-occured )。

次のコードは、実行中のコードブロックが、サービスまたはサイトが実行されている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
   }

}

ただし、非常に重要な詳細の1つは、Active Directoryを呼び出すすべてのコードがそのブロック内にある必要があるということです。私のチームメンバーが書いたコードは、LINQ(カスタムクラス)型のUsersクエリ結果を返していましたが、式を評価していませんでした(悪い習慣)。したがって、結果の代わりに式ツリーが返されました。

最終的には、呼び出しコードが結果を評価し、An operations error occurredメッセージは引き続き表示されます。上記のコード修正は機能しませんでしたが。実際にはそうでしたが、ブロック外の結果を評価するコードがありました。

一言で言えば、Active Directoryにアクセスするためのallコードがそのusingブロック内にあり、例外がサービス/アプリがサーバーにデプロイされます。

41
atconway

これが2年後であることを認めると、私はこれに出くわし、次のことが私の問題を解決したことがわかりました。

using System.Web.Hosting;
...
...
// Code here runs as the logged on user

using (HostingEnvironment.Impersonate()) {
// This code runs as the application pool user
     DirectorySearcher searcher ...
}

参照

9
Jake1164

これは、Web.configをいじっていたASP.NET(Windows 2008 R2/IIS7)で発生し、このエラーはFindByIdentityの呼び出しごとに発生し始めました。根本的な原因は、App PoolがDefaultAppPoolとして実行されていたため、ネットワークサービスとして実行するように変更すると再び機能し始めたことです。なぜ変更されるのかよくわかりませんが、変更されました。

4
NightShovel

同じ問題がありました。以下のようにアプリケーションプールを変更した後、成功しました。プロセスモデルの読み込みユーザープロファイル= true

2
jose comar

エラーコードを受け取った場合、 "操作エラーが発生しました(0x80072020)"、つまり "アクセス拒否「

  • ADドメインにあるかどうかにかかわらず、Webサーバーを確認してください
    • そうでない場合、認証をPrincipalContextに入れる必要があります。
public bool foo(String username, String password) {
    string ADIPaddress = "[ipaddress]";
    ContextOptions options = ContextOptions.Negotiate;
    PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, AD_IPaddress, null, options, username, password);
    bool isAuthenticated = principalContext.ValidateCredentials(username, password, options);
    return isAuthenticated;
}
0
Angus Wu

私にとっては、ドメインコントローラーの1つにログインしようとすると同じ問題が発生しました。2つのドメインコントローラーがあり、そのうちの1つが機能し、もう1つが機能していません。まだ調査中...

0
NanoHead

私の場合、Webアプリプールは「DefaultAppPool」として実行されていたため、会社のActive Directoryに接続するための十分なアクセス権がありませんでした。そのため、コードでADにアクセスできるアカウントを偽装し、すべてが正常に機能しました。

0
Arshad Mohammad