On Windows Server 2012 R2 we want to get the Security Groups of an user from the Active Directory by C#-code. The application is an ASP.NET MVC5-project and is hosted by an IIS.
At first, we query the user account from the Active Directory by UserPrincipal.FindByIdentity(...)
. That works fine. At next, we use the WindowsIdentity
class to query the Security Groups from the active directory. We use the class WindowsIdentity
because the response is very fast.
Here is the code:
var lDomain = "MyDomain";
var lSamAccountName = "Simon";
using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, lDomain))
{
// Get User Account from Active Directory
using (UserPrincipal lUserPrincipal = UserPrincipal.FindByIdentity(ctx, IdentityType.SamAccountName, lSamAccountName))
{
var lUpn = lUserPrincipal.UserPrincipalName; // get UPN
// get Security Groups of the user
using (WindowsIdentity lWindowsIdentity = new WindowsIdentity(lUpn)) // Exception: System.Security.SecurityException: The user name or password is incorrect
{
var lGroups = lWindowsIdentity.Groups;
}
}
}
The problem: When instanciating the WindowsIdentity
class (and passing the UPN) then an exception occurs:
“Upn: 'simon@MyDomain' Exception: System.Security.SecurityException: The user name or password is incorrect.
at System.Security.Principal.WindowsIdentity.KerbS4ULogon(String upn, SafeAccessTokenHandle& safeTokenHandle)
at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName, String type)
at System.Security.Principal.WindowsIdentity..ctor(String sUserPrincipalName)
at ...
This is curious because the query with UserPrincipal.FindByIdentity(...)
was successful. Some accounts are working. Some accounts are not working. I cannot find a difference between the working und not working accounts.
Question: Who knows what I am doing wrong?
Additional Notes:
- The Applicationpool Identity is: LocalSystem
- In the Web.config, there is the following entry:
<identity impersonate="false" />
When I query the groups by the following alternative, then no exception occurs and the result is satisfying. That´s curious:
var lResult = new List<SecurityIdentifier>(); DirectorySearcher lDirectorySearcher = new DirectorySearcher(); lDirectorySearcher.Filter = string.Format(CultureInfo.InvariantCulture, "(&(objectClass=user)(distinguishedName={0}))", lUserPrincipal.DistinguishedName); // for the object lUserPrincipal, look @ code above lDirectorySearcher.SearchScope = SearchScope.Subtree; SearchResult lSearchResult = lDirectorySearcher.FindOne(); DirectoryEntry lDirectoryEntry = lSearchResult.GetDirectoryEntry(); lDirectoryEntry.RefreshCache(new string[] { "tokenGroups" }); // get groups for (int i = 0; i < lDirectoryEntry.Properties["tokenGroups"].Count; i++) { SecurityIdentifier lSid = new SecurityIdentifier((byte[])lDirectoryEntry.Properties["tokenGroups"][i], 0); lResult.Add(lSid); // Translate into NTAccount to get Domain and SAMAccountname etc... [...] }