问题
I've an MVC Intranet app that I've recently upgraded from .Net 4 to 4.6.1. This app queries user details from Active Directory to load details that aren't available in the Controller's User.Identity property and until lately has done so flawlessly. The code looks something like this:
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;
}
}
}
The code runs fine when debugging in Visual Studio 2015, but when it's running on the IIS box (v6.1 SP1 on Windows Server 2008 R2), throws a COMException (0x80005000) when calling UserPrincipal.FindByIdentity()
The web app is running on a dedicated App Pool, the settings for which are as follows:
- .Net Framework Version = v4.0
- Identity = MyDomain\MyAppServiceUser (Non-interactive AD User Account)
- Load User Profile = false
All other settings are as per the defaults. The application itself is running with both Anonymous and Windows Authentication enabled. The server has .Net 4.6.1 installed and all other elements of the intranet app seem to be running just fine.
Having googled this to death, most of the answers seem to indicate that it's a problem with the service account's permissions to query AD. In order to confirm that the service account that the App Pool is running as DOES have access to query Active Directory, I've used the above code in a console app and run it as both myself and the service account on the server - in both instances it works just fine. It only bombs out when running under IIS.
I've tried numerous variations creating the PrincipalContext (including the OU container path, etc) but the results are always the same.
I'm doing my nut on this, so any help would be greatly appreciated.
Update - additional details
- Exception Type: System.Runtime.InteropServices.COMException
- Exception Message: Unknown error (0x80005000)
- Stack Trace:
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.UserPrincipal.FindByIdentity(PrincipalContext context, IdentityType identityType, String identityValue) at Apollo.Security.ActiveDirectoryUser.Find(String identityName)
回答1:
Talk about a head-scratcher. I've spent the best part of a day on this going around in circles.
Thanks to Rahul for all the help. In the end, at his suggestion, I created a new app pool running as Network Service and the AD lookups worked perfectly under that. Unfortunately, because my app accesses networked resources it needs to run as an AD User, so just for the heck of it I changed the credentials over to the AD Service Account I'd been using before and IT STILL WORKED.
?!?
I have no idea why this should be the case - both app pools have exactly the same setup yet one can perform the lookups and the other can't. I've switched both the test and production instances over to the new app pool and deleted the old one and everything is ticking along nicely.
回答2:
For us this was due to McAfee HIPS service blocking outbound/inbound WMI connections over TCP port 135
来源:https://stackoverflow.com/questions/39102630/userprincipal-findbyidentity-results-in-com-error-0x80005000