Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 4 authentication with Active Directory or Membership database

I´m building a web application which could get accessed in two ways. Everyone who is working in the same organisation as I can use our active directory to access the application.

Everyone from outside should join the application through a separate membership database. Everyone should have a account in the membership database with his roles, so the ad connection is just a bonus to make it easier to keep the password and username in mind. I searched the internet but couldn't find a comparable situation. This is my first time working with ad.

Does anyone know of a framework that can be used or give me a hint on how I could try to solve the problem?

At moment I implemented the membership connection with System.Web.WebData.SimpleMembershipProvider and it works fine.

In the later development of the application I also need some other connections to the ad to check some information but that is just a problem for another day.

Thanks for the help.

like image 867
Jastol Avatar asked Jun 13 '13 08:06

Jastol


People also ask

What is the default authentication while creating an MVC application?

Select MVC template and you will see that the Change Authentication button is now enabled. This is done with the Change Authentication button that appears in the New Project dialog. The default authentication is, Individual User Accounts.


2 Answers

Open up your web.config.

First of all you'll need connectionString for your ActiveDirectory:

  <connectionStrings>
    ...
    <add name="ADConnectionString" connectionString=LDAP://*adserver*/DC=*domain* />
    ...
  </connectionStrings>

Scroll down to the <membership> tag. Make sure you have defaultProvider attribute set for the <membership>, like:

<membership defaultProvider="SimpleMembershipProvider">

Then add new provider for AD members inside <providers>:

    <add name="ADMembershipProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider" connectionStringName="ADConnectionString" attributeMapUsername="sAMAccountName" />

That should do the trick for web.config. Now we need to auth AD users on Log in. Go to your AccountController Login action. First we try to authenticate user via ActiveDirectory, there is handy class called PrincipalContext in System.DirectoryServices.AccountManagement namespace. If that fails we use the default membership provider:

        public ActionResult Login(LoginModel model, string returnUrl)
        {
            try
            {
                // try to auth user via AD
                using (PrincipalContext pc = new PrincipalContext(ContextType.Domain))
                {
                    if (pc.ValidateCredentials(model.UserName, model.Password))
                    {
                        FormsAuthentication.SetAuthCookie(model.UserName, false);
                        return RedirectToAction("Index", "Home");
                    }
                }
                // try the default membership auth if active directory fails

                if (Membership.ValidateUser(model.UserName, model.Password))
                {
                    FormsAuthentication.SetAuthCookie(model.UserName, false);

                    if (Url.IsLocalUrl(returnUrl))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }
                else
                {
                    ModelState.AddModelError("", "Login failed");
                }
            }
            catch
            {
            }
            GetErrorsFromModelState();
            return View(model);
        }

For your later requirements you can get the current logged in ActiveDirectory user with UserPrincipal class:

using (var context = new PrincipalContext( ContextType.Domain)) 
{
    using (var aduser = UserPrincipal.FindByIdentity( context,IdentityType.SamAccountName, HttpContext.User.Identity.Name))
    {
        ...
    }
}

Hope this helps and I didn't miss anything.

like image 166
Tomi Lammi Avatar answered Sep 17 '22 03:09

Tomi Lammi


This Code will give you if the user with specified username and password is valid

    public bool ValidateUser(string userName, string password)
    {
        bool authenticated = false;
        string dePath = string.Empty;
        dePath += DomainController;
        if (!string.IsNullOrEmpty(BaseDomainName))
        {
            dePath += "/" + BaseDomainName; 
        }
        try
        {
            DirectoryEntry entry = new DirectoryEntry(dePath, userName, password);
            object nativeObject = entry.NativeObject;
            authenticated = true;
        }
        catch
        {
            return false;
        }
        return authenticated;
    }

You can add DomainController and BaseDomainName in web.config appSettings as keys

like image 22
spring Avatar answered Sep 17 '22 03:09

spring