Search code examples
c#.netasp.net-mvcasp.net-coreasp.net-core-5.0

.net core 5 Windows Authentication and Active Directory resources


Hey guys just a straight up question with no code. I am struggling mightily to even find basic answers to simple questions.

How on earth can and should I use windows authentication (not integrated windows authentication) with active directory for authentication and then authorization? You would think there would be a million sample projects but 80% of my search results for .net core come up with older asp.net articles that are outdated and don't work on newer versions.

I have a bunch of working examples here at work but they are all older using System.Web classes/libraries that are all now deprecated and no longer of use to me.

The code and methods I have from older asp.net projects all look pretty straight forward otherwise and am baffled why I cannot find anything similar for .net core? Everything is some niche third party package in most articles I read while I just want to do it the vanilla Microsoft way, I find it hard to believe there is not a simple solution for a login screen and authentication against AD. The Microsoft docs feel like they are targeted at experts who get a small hint and know exactly what to do.

I am a newly postgrad working for only 4 months and am new to .net core.

I have gone down LDAP, claims, principal, cookies and more rabbit holes but just get more confused than anything with all the varying versions of .net and their classes/libraries etc.


Solution

  • There's a nuget that handles this; System.DirectoryServices.AccountManagement

    It's Windows only, there's a Novel ldap version that I think is cross platform.

    To authenticate:

    using (var ctx = new PrincipalContext(ContextType.Domain))
    {
        if (!ctx.ValidateCredentials(user_name, password))
            throw new Exception("unknown username or password");
    
        using (var userPrincipal = new UserPrincipal(ctx)) {
            userPrincipal.SamAccountName = user_name;
    
            using (var search = new PrincipalSearcher(userPrincipal))
            {
                UserPrincipal user = (UserPrincipal) search.FindOne();
                if (user == null) {
                    throw new Exception("user authenticated but not found in directory");
                }
                return user; // auth'ed user
            }
        }
    }
    

    To authorize (by group membership):

    using (var ctx = new PrincipalContext(ContextType.Domain))
    {
        using (var groupPrincipal = new GroupPrincipal(ctx))
        {
            groupPrincipal.SamAccountName = groupName;
            using (var search = new PrincipalSearcher(groupPrincipal))
            {
                member_list = GetMembersOfPrincipalGroup((GroupPrincipal)search.FindOne());
            }
            // member_list contains all the users of a group. 
            // I cache these in a Dictionary for faster group membership checks
        }
    }
    

    Note that the ContextType enum handles local machine users as well as domain. Search on the nuget package for more examples.