最近 .Net 4 から 4.6.1 にアップグレードした MVC イントラネット アプリがあります。このアプリは、Active Directory からユーザーの詳細を照会して、Controller の User.Identity プロパティでは利用できなかった詳細をロードします。最近まで問題なく実行されていました。コードは次のようになります。
public static void foo()
{
var usr = LookupUser("MyDomain", "jbloggs");
...
}
private static UserPrincipal LookupUser(string domain, string username)
{
Console.WriteLine($"Lookup {domain}\\{username}");
using (var ctx = new PrincipalContext(ContextType.Domain, domain))
{
using (var user = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, username))
{
if (user == null)
{
Console.WriteLine("User not found");
return;
}
Console.WriteLine($"Found {domain}\\{username}");
Console.WriteLine($"DisplayName = {user.DisplayName}");
Console.WriteLine($"Office = {user.GetString("physicalDeliveryOfficeName")}");
Console.WriteLine("");
return user;
}
}
}
コードは、Visual Studio 2015 でのデバッグ時には正常に実行されますが、IIS ボックス (Windows Server 2008 R2 上の v6.1 SP1) で実行されている場合、UserPrincipal.FindByIdentity() の呼び出し時に COMException (0x80005000) がスローされます。
Web アプリは専用のアプリ プールで実行されており、その設定は次のとおりです。
- .Net フレームワーク バージョン = v4.0
- ID = MyDomain\MyAppServiceUser (非インタラクティブ AD ユーザー アカウント)
- ユーザー プロファイルの読み込み = false
その他の設定はすべてデフォルトのままです。アプリケーション自体は、匿名認証と Windows 認証の両方を有効にして実行されています。サーバーには .Net 4.6.1 がインストールされており、イントラネット アプリの他のすべての要素は正常に動作しているようです。
これをグーグルで検索した結果、ほとんどの回答は、AD を照会するサービス アカウントのアクセス許可に問題があることを示しているようです。アプリケーション プールが実行されているサービス アカウントが Active Directory をクエリするアクセス権を持っていることを確認するために、上記のコードをコンソール アプリケーションで使用し、自分自身とサーバー上のサービス アカウントの両方として実行しました。インスタンスは問題なく動作します。IIS で実行している場合にのみ爆発します。
プリンシパル コンテキスト (OU コンテナー パスなどを含む) を作成するさまざまなバリエーションを試しましたが、結果は常に同じです。
私はこれに夢中になっているので、どんな助けでも大歓迎です。
更新 - 追加情報
- 例外の種類: System.Runtime.InteropServices.COMException
- 例外メッセージ: 不明なエラー (0x80005000)
- スタックトレース:
System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail) で System.DirectoryServices.DirectoryEntry.Bind() で System.DirectoryServices.DirectoryEntry.get_AdsObject() で System.DirectoryServices.PropertyValueCollection.PopulateList() で System.DirectoryServices.PropertyValueCollection.. System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInitNoContainer() の System.DirectoryServices.AccountManagement.PrincipalContext.DoDomainInit() の System.DirectoryServices.AccountManagement の System.DirectoryServices.PropertyCollection.get_Item(String propertyName) の ctor(DirectoryEntry entry, String propertyName) System.DirectoryServices.AccountManagement.PrincipalContext.get_QueryCtx() で System.DirectoryServices.AccountManagement.Principal で .PrincipalContext.Initialize()。FindByIdentityWithTypeHelper (PrincipalContext コンテキスト、型 principalType、Nullable`1 identityType、文字列 identityValue、DateTime refDate) System.DirectoryServices.AccountManagement.Principal.FindByIdentityWithType (PrincipalContext コンテキスト、型 principalType、IdentityType identityType、文字列 identityValue) で System.DirectoryServices.AccountManagement.UserPrincipal Apollo.Security.ActiveDirectoryUser.Find(String identityName) での .FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue)DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue) at Apollo.Security.ActiveDirectoryUser.Find(String identityName)DirectoryServices.AccountManagement.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue) at Apollo.Security.ActiveDirectoryUser.Find(String identityName)