Issues

Authenticate to Umbraco 7.3+ Using Active Directory

So I’m feeling a little weary - as I’m now writing my second skrift article for this edition. Both have been about logging into Umbraco with Active directory (AD) - and as I painfully discovered there are some big breaking changes in Umbraco 7.3.

If you are working with versions before 7.3, right back to early versions of 6, just read the original article.

If you are on 7.3 - you have an issue - that is where the breaking change appeared - and you probably want to get onto at least 7.3.1 to follow this article.

The good news is - that after all of the discussion around the breaking change - it is now really simple to get AD authentication working in Umbraco. There are even docs!

RTFM

The improvement in the Umbraco documentation in recent years is amazing - this article would have been so much longer without this page:

These are the first steps you need to take.

If you’ve follow the above - you’ll have an empty class - that implements IBackOfficeUserPasswordChecker something like this:

using System.Threading.Tasks;
using Umbraco.Core.Models.Identity;
using Umbraco.Core.Security;

namespace WebApplication22.Classes
{
    public class AdPasswordChecker : IBackOfficeUserPasswordChecker
    {
        public Task CheckPasswordAsync(BackOfficeIdentityUser user, string password)
        {
            return Task.FromResult(BackOfficeUserPasswordCheckerResult.ValidCredentials);
        }
    }
}

Assuming you followed all of Shannon’s steps in the official documentation this method should get hit when you try to login to Umbraco.

Adding the logic

Unless you want everyone to be able to login regardless of the password that they enter - you’ll need to add the following simple logic.

bool isValid;
using (var pc = new PrincipalContext(ContextType.Domain, "MYDOMAIN"))
{
    isValid = pc.ValidateCredentials(user.UserName, password);
}

var result = isValid
    ? BackOfficeUserPasswordCheckerResult.ValidCredentials
    : BackOfficeUserPasswordCheckerResult.InvalidCredentials;

return Task.FromResult(result);

You’ll need to add a reference to the following namespace in your project:

using System.DirectoryServices.AccountManagement

Is it that easy?

Well.. Yes and No.

If the above example works for you - then you are happy - but there are a few things that may get in your way.

The AD membership provider used in previous versions of Umbraco would create an Umbraco user with minimum permissions when they authenticated for the first time via AD. In the new approach, an admin would need to create the user in Umbraco first - the override above just does password validation, so they must  exist in Umbraco already.

In the example above the web server that you are authenticating to is joined to the domain that you are authenticating against - and the web server is allowed to make authentication queries. If the machine is off domain or there are any firewalls sitting between servers, you may have some unpicking to do.

Custom requirements

If you are an enterprise with thousands of users, it may not be ideal to have to create them all in Umbraco in advance and you may need to create them upon first login and assign them access to certain sections within Umbraco.

The entry point above isn’t workable in this instance as it only gets called to validate a password once Umbraco has verified that the user exists.

Can it be done?

Maybe, but we’ll need to ask Shannon :)

I can see certain entry points, but the methods aren’t overridable so it’d mean providing classes with tons of duplicate code. For those searching these look like the places to hook in and create users if they don’t exist:

  • FindByNameAsync method (Umbraco.Core.Security.BackOfficeUserStore)

  • GetByUsername (Umbraco.Core.Services)

You could also write some kind of scheduled job, that synchronises your active directory and Umbraco user database - some might argue that this is a better solution - creating and syncing users probably shouldn’t probably happen while authenticating.

That's all folks

This is a reasonably short and sweet article - due to the simple entry point for authenticating an Umbraco user.

Although this article just focuses on AD - the addition of ASP.NET Identity to Umbraco means the possibility to login with a number of services (Facebook, Google, Twitter etc).

For those of you looking for some help syncing AD users with Umbraco, feel free to get in touch - I have some code up my sleeve (too long to post here).

I hope you enjoyed the article - dry as the subject matter may be!

Darren Ferguson

When he's not losing sleep over breaking changes, Darren Ferguson is the owner of Moriyama, an Umbraco gold partner and official training provider with over 15 years of experience.

comments powered by Disqus