Using Windows Authentication in My Own Login Form

I have a WPF application that has a login form. I would like all existing window users belonging to a specific group to be able to log into my application.

So, I need a way when the user gave his username and password to find out if this is a user from the wanted group and that the password is correct. Feedback that I can use to decide if the user is logged in or not.

+6
source share
3 answers

If you need to find out if the user is a member of any AD group, you will need to use the SID of the group if the user is not a "direct" member of the group (i.e. the user is a member of a nested group, which itself is a member of the "desired" AD groups).

(I have used this for many years, but have long lost the link to where I found it. I believe that there is actually an easier way to test nested groups in DirectoryServices 4.0, but I have not used it).

If you are using .NET 3.5 (as indicated in the link from Travis), you can verify the user credentials as follows:

using (PrincipalContext pc = new PrincipalContext(ContextType.Domain) { if (pc.ValidateCredentials(username, password)) { /* Check group membership */ } } 

If you are not using .NET 3.5, you can still verify the credentials as follows:

 var user = new DirectoryEntry("", username, password) try { user.RefreshCache(); /* Check group membership */ } catch (DirectoryServicesCOMException ex) { /* Invalid username/password */ } finally { user.Close(); } 

Then, to verify AD group membership, use the following:

 var user = new DirectoryEntry("", username, password); var searcher = new DirectorySearcher(); searcher.Filter = "(&(objectCategory=group)(samAccountName=" + YourGroupName + "))"; var group = searcher.FindOne(); if (group != null && IsMember(group.GetDirectoryEntry(), user)) /* User is a direct OR nested member of the AD group */ 

IsMember Helper Method:

 static bool IsMember(DirectoryEntry group, DirectoryEntry user) { group.RefreshCache(new string[] { "objectSid" }); SecurityIdentifier groupSID = new SecurityIdentifier((byte[])group.Properties["objectSid"].Value, 0); IdentityReferenceCollection refCol; user.RefreshCache(new string[] { "tokenGroups" }); IdentityReferenceCollection irc = new IdentityReferenceCollection(); foreach (byte[] sidBytes in user.Properties["tokenGroups"]) { irc.Add(new SecurityIdentifier(sidBytes, 0)); } refCol = irc.Translate(typeof(NTAccount)); PropertyValueCollection props = user.Properties["tokenGroups"]; foreach (byte[] sidBytes in props) { SecurityIdentifier currentUserSID = new SecurityIdentifier(sidBytes, 0); if (currentUserSID.Equals(groupSID)) { return true; } } return false; } 
+4
source

Confirm username and password in Active Directory?

The search result should be able to query groups for this user.

+2
source

The above IsMember function worked for me, checking for the existence of domain users in domain groups and local users and local groups, but when checking for the existence of a domain user in a local group such as IIS_IUSRS, this did not work. I changed it a bit to use the group members property and search for matches for each user added with this user's SID.

Here is the code

 private static bool IsMember(DirectoryEntry group, DirectoryEntry user) { SecurityIdentifier userSId = new SecurityIdentifier((byte[])user.Properties["objectSid"].Value, 0); foreach (object member in (IEnumerable)group.Invoke("Members")) { using (var memberEntry = new DirectoryEntry(member)) { var groupSId = new SecurityIdentifier((byte[])memberEntry.Properties["objectSid"].Value, 0); if (userSId.Equals(groupSId)) { return true; } } } return true; } 
0
source

Source: https://habr.com/ru/post/889441/


All Articles