3

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...
        [...] 
    }
    
Simon
  • 4,157
  • 2
  • 46
  • 87

3 Answers3

1

I really do not know if this helps, but somewhere I found this:

  • If IIS is set to allow anonymous access you can use the userPrincipleName format (username@domain).
  • If anonymouse access is NOT enabled in IIS you need to use the username in the form domain\username.

Seems weird though that for some accounts the UPN works and for others it does not..

Theo
  • 57,719
  • 8
  • 24
  • 41
  • Thank you for your hint. In this Web Application, Anonymous Authentication is enabled to make it possible to show a custom login page. Unfortunately, your posted answer not focuses my question. – Simon Aug 17 '18 at 06:15
0

Resolution 1:

Use ADSI Edit (via MMC.exe) to manually populate the userPrincipalName attribute of the desired Windows Service Account.

The format of a userPrincipalName is

<username>@<fully_qualified_domain_name>

For example, for the example log lines above, the expected UPN value should be

goodadmin@example.com

Allow a few minutes for Active Directory replication to complete before attempting to use the service account credentials.

Resolution 2:

Ensure the Active Directory Service Account information has the necessary permissions on the local BEMS host as Local Administrator and Logon As A Service.

Ensure the Active Directory Service Account information entered is actually valid. For example, ensure the password is entered correctly and that the account is not locked out in Active Directory.

Ensure the Active Directory Service Account information has the necessary Active Directory Group Permissions.

RTCUniversalReadOnlyAdmins
Prabhu Manoharan
  • 311
  • 2
  • 10
0

Here you can find how to get groups base on the UserPrincipal

How to create WindowsIdentity/WindowsPrincipal from username in DOMAIN\user format

    // find all groups the user is member of (the check is recursive).
    // Guid != null check is intended to remove all built-in objects that are not really AD gorups.
    // the Sid.Translate method gets the DOMAIN\Group name format.
    var userIsMemberOf = p.GetAuthorizationGroups().Where(o => o.Guid != null).Select(o => o.Sid.Translate(typeof(NTAccount)).ToString());

    // use a HashSet to find the group the user is member of.
    var groups = new HashSet<string>(userIsMemberOf), StringComparer.OrdinalIgnoreCase);
    groups.IntersectWith(groupNames);
wolszakp
  • 1,109
  • 11
  • 25
  • GetAuthorizationGroups is known to me, but too slow. Tested it in many environments and does not answer my question. – Simon Aug 21 '18 at 11:05