UserPrincipal.FindByIdentity fails with System.Runtime.InteropServices.COMException (0x80005000): Unknown error (0x80005000)

Jonathan Stewart 1 Reputation point
2020-12-14T21:04:00.977+00:00

The code below works on my development machine when debugging in Visual Studio. The development machine is on a different domain than the staging and production servers but creating the principal context with a username and password seemed to solve the issues I had there.

When run on the staging server ValidateCredentials passes but the FindByIdentity() calls fails with the stack trace below.

The IIS pool is running as ApplicationPoolIdentity but I don't think that should matter as ValidateCredentials works (so contacting the domain controller works) and the PrincipalContext is created with a valid username and password for the domain (so the user the pool runs as shouldn't matter).

I found suggestions to use HostingEnvironment.Impersonate() but I'm pretty sure that's not an option with .Net 5/Core and as I'm passing an explicit username and password to the PrincipalContext it shouldn't be in play anyway.

I found https://stackoverflow.com/a/39118337/ and I can try creating a new app pool and moving the site there but I don't like "black magic" fixes and think it's rather unlikely to work.

using var principalContext = new PrincipalContext(ContextType.Domain, _activeDirectoryConfiguration.ControllerNameOrIp, username, password);

if (!principalContext.ValidateCredentials(username, password))
{
    _logger.LogWarning(ErrorMessages.UNABLE_TO_AUTHENTICATE + " {0}", username);
    errors.Add("", ErrorMessages.UNABLE_TO_AUTHENTICATE);
    return (null, errors);
}

IEnumerable<string> userGroups;
UserPrincipal adUser;
adUser = UserPrincipal.FindByIdentity(principalContext, username);
userGroups = adUser.GetAuthorizationGroups().Select(x => x.Name).ToList();
DirectoryEntry dirEntry = (DirectoryEntry)adUser.GetUnderlyingObject();
string office = dirEntry.Properties["physicalDeliveryOfficeName"].Value.ToString();

Stack Trace:

System.Runtime.InteropServices.COMException (0x80005000): Unknown error (0x80005000)
   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 XXX.ActiveDirectoryService.Authenticate(String username, String password) in XXX\Services\ActiveDirectoryService.cs:line 55
   at XXX.AuthService.Authenticate(String username, String password) in XXX\Services\AuthService.cs:line 59

I asked this on StackOverflow but didn't get any answers https://stackoverflow.com/questions/65012219/

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,208 questions
Active Directory
Active Directory
A set of directory-based technologies included in Windows Server.
5,932 questions
{count} votes