How to use Windows Active Directory Authentication and Identity Based Claims?

hlyates picture hlyates · Mar 5, 2015 · Viewed 33.1k times · Source

Problem

We want to use Windows Active Directory to authenticate a user into the application. However, we do not want to use Active Directory groups to manage authorization of controllers/views.

As far as I know, there is not an easy way to marry AD and identity based claims.

Goals

  • Authenticate users with local Active Directory
  • Use Identity framework to manage claims

Attempts (Fails)

  • Windows.Owin.Security.ActiveDirectory - Doh. This is for Azure AD. No LDAP support. Could they have called it AzureActiveDirectory instead?
  • Windows Authentication - This is okay with NTLM or Keberos authentication. The problems start with: i) tokens and claims are all managed by AD and I can't figure out how to use identity claims with it.
  • LDAP - But these seems to be forcing me to manually do forms authentication in order to use identity claims? Surely there must be an easier way?

Any help would be more than appreciated. I have been stuck on this problem quite a long time and would appreciate outside input on the matter.

Answer

Shoe picture Shoe · Mar 6, 2015

Just hit AD with the username and password instead of authenticating against your DB

// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindByNameAsync(model.UserName);
        if (user != null && AuthenticateAD(model.UserName, model.Password))
        {
            await SignInAsync(user, model.RememberMe);
            return RedirectToLocal(returnUrl);
        }
        else
        {
            ModelState.AddModelError("", "Invalid username or password.");
        }
    }
    return View(model);
}

public bool AuthenticateAD(string username, string password)
{
    using(var context = new PrincipalContext(ContextType.Domain, "MYDOMAIN"))
    {
        return context.ValidateCredentials(username, password);
    }
}