Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Windows Authentication inside my own login form

I have WPF application that has a login form. I would like to make all existing windows users that belong to some specific group able to log into my application.

So what I need is a way after the user have given his username and password to see if this is a user, belonging to the wanted group, and that the password is correct. The feedback I can use to decide if the user gets logged in or not.

like image 444
Øyvind Bråthen Avatar asked May 31 '11 11:05

Øyvind Bråthen


People also ask

How do I add Windows Authentication to an existing MVC project?

By default MVC apps use Form Authentication and Simple Membership, so you need to make it "false" to run Windows Authentication. Select the project name in Solution Explorer and then in the Property Explorer, click to enable Windows Authentication.

How do I enable Windows Authentication for my website?

In Control Panel, click Programs and Features, and then click Turn Windows features on or off. Expand Internet Information Services, expand World Wide Web Services, expand Security, and then select Windows Authentication. Click OK. Click Close.


2 Answers

If you need to find out if the user has membership to some AD group, you will need to use the group's SID 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 group).

(I've used this for years, but long ago lost the link to where I found it. I believe there's actually a simpler way to check for nested groups in DirectoryServices 4.0, but I have not used it).

If you're using .NET 3.5 (as indicated in the link from Travis), you can check the user's credentials like this:

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 check the credentials like this:

var user = new DirectoryEntry("", username, password)
try 
{
    user.RefreshCache();

    /* Check group membership */
}
catch (DirectoryServicesCOMException ex)
{
    /* Invalid username/password */
}
finally
{
    user.Close();
}    

Then, to check, the 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 */

The 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;
}
like image 92
Adrian Avatar answered Oct 27 '22 14:10

Adrian


Validate a username and password against Active Directory?

With the search result should be able to query the groups for that user.

like image 26
Travis Avatar answered Oct 27 '22 16:10

Travis