How To: Secure your ASP.NET MVC application and use Active Directory as the Membership Provider

โ€”

by

in

Securing your ASP.NET MVC application should be priority number one every time you start a new web application. Using the attributes Authorize andย ValidateAntiForgeryToken in every controller and action is the only way to avoid any security holes. In this post, I’ll show you how to secure your ASP.NET application by implementing the AuthorizeAttribute andย ValidateAntiForgeryTokenAttribute classes.

The basics

At the very least, you should add an [Authorize] attribute to every controller or controller Action in case you want some of the controller actions to be accessible by anonymous users. For example, you probably want ALL users to have access to the login and register actions of your web application.

By decorating the HomeController with the Authorize attribute (notice I did not specify any user role), the application will prevent any unauthenticated user from executing any of the actions in this controller.

[code language=”csharp”]
[Authorize]
public class HomeController : Controller
{
//…
}
[/code]

The following is an example of decorating a controller action with the Authorize attribute, you want to do this when you only want to restrict access to some of the actions in a controller instead of all actions.

[code language=”csharp”]
[Authorize]
public ActionResult Create()
{
//…
}
[/code]

Protecting againstย Cross-site request forgeryย attack (CSRF or XSRF)

The Authorize attribute offers protection that is sufficient in most cases. However, there is a security hole with this, and thus it opens your web application for a cross-site request forgery attack. For example, after a user logs into your site,ย the website will issue your browser an authentication token within a cookie. Each subsequent request, the browser sends the cookie back to the site to let the site know that you are authorized to take whatever action youโ€™re making, so far everything is okay.

Here is the problem with only using the Authorize attribute, let’s say that a user is logged in to your website and then they go to a spam site by clicking on a link that points to another site which causes a form post back to your site… this is bad, your browser will send the authentication cookie to your site making it appear as if the request came from your website and initiated by an authenticated user when it really didn’t.

The above scenario is called cross-site request forgeryย and can be avoided by adding theย ValidateAntiForgeryTokenย attribute available in the .NET framework, this attributeย is used to detect whether a server request has been tampered with.

The first step is to add theย ValidateAntiForgeryToken attribute to every Post Action as follows:

[code language=”csharp”]
[HttpPost, Authorize, ValidateAntiForgeryToken]
public ActionResult Create()
{
//…
}[/code]
The next step is to add the HtmlHelperย method @Html.AntiForgeryToken() inside the form in your view.

The way theย ValidateAntiForgeryToken attribute works is byย checking to see that theย cookieย andย hidden form fieldย left by theย Html.AntiForgeryToken()ย HtmlHelper essentially exists and match. If they do not existย or match, it throws anย HttpAntiForgeryException shown below:

“A required anti-forgery token was not supplied or was invalid.”

By adding theย ValidateAntiForgeryToken to your controller actions, your site will be prepared to prevent CSRF/XSRF attacks.

Implementing Forms Authentication using Active Directory (AD)

Often times you might runย acrossย a project where you need to authenticate users of your website using Active Directory credentials, the good news is that you can use the existing “Account” controller to achieve this, only a few modifications are necessary.

When you create a new MVC Web Application project and choose the Internet Application template, the Account controller is added to the project, you can use this controller with AD to authenticate your users. For the Account controller to work with AD we need to remove all Actions but the following:

  • Logon()
  • Logon(LogOnModel model, string returnUrl)
  • LogOff()

Your Account controller should look like the following after you remove the unnecessary Actions such as ChangePassword, Register, etc…

[code language=”csharp”]
public ActionResult LogOn()
{
return View();
}

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith(“/”)
&& !returnUrl.StartsWith(“//”) && !returnUrl.StartsWith(“/”))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(“Index”, “Home”);
}
}
else
{
ModelState.AddModelError(“”, “The user name or password provided is incorrect”);
}
}

// if we got this far, something failed, redisplay form
return View(model);
}

public ActionResult LogOff()
{
FormsAuthentication.SignOut();

return RedirectToAction(“Index”, “Home”);
}
[/code]
After this, go ahead and clean up the AccountModel as well so the only model class left is the LogOnModel:
[code language=”csharp”]
public class LogOnModel
{
[Required]
[Display(Name = “User name”)]
public string UserName { get; set; }

[Required]
[DataType(DataType.Password)]
public string Password { get; set; }

[Display(Name = “Remember me?”)]
public string RememberMe { get; set; }
}
[/code]
Lastly, add the following to the project’s web.config file:

adconnection

That is all! The first code snippet is the connectionstring to your Active Directory server and the second one is where we specify Active Directory as the application’s default membership provider.

Save your changes, hit Ctrl-F5 and login to your application using your domain/AD account.

Hopefully, this will help you get started to secure your ASP.NET web apps and show you a straightforward way to use ASP.NET’s membership services with Active Directory.

In this post, I show how to use Active Directory groups to restrict access to controller actions and make your application even more secure!


Comments

  1. Nice. Clear and concise. Looking forward to your next post about AD groups.

  2. Hi!

    Im followed your code and try to login, but i got an parser error message: “Unable to establish secure connection with the server” Do you know how i can fix this? I tried to google, but did not find any good answers.

    1. You need to make sure the connection string to Active Directory is correct. Check the ConnectionStrings section in your web.config and make sure it is pointing to the AD server you are trying to connect. Check this answer on ServerFault.com, it might help you find the correct connection string to your Active Directory server:

      http://serverfault.com/questions/130543/how-can-i-figure-out-my-ldap-connection-string

      1. Thanks for answering!

        But i don’t think it is my connectionstring who cause the problem. I’ve tried to connect the AD with an ASP.NET Web application and it works fine. But now i want to do it in MVC which cause more problem.

        The source error is: line 24:

        If this is not giving you any good tips to fix this, i can send you the project so you can see?

      2. add name=”ADMembershipProvider” type=”System.Web.Security.ActiveDirectoryMembershipProvider” connectionStringName=”ADConnectionString” attributeMapUsername=”sAMAccountName”

        1. That error is sometimes caused by the default trust policy configuration of ASP.NET. The ActiveDirectoryMembershipProvider instance works only in the full-trust policy default configuration of ASP.NET.

          To enable full-trust add the following to the system.web section of your web.config file:

          trust level=”Full” originUrl=””

          If that does not work, then check this answer on stackoverflow.com, it might help with this issue.

      3. None of them seems to work. I’ve tried both but it stills says “unable to establish a secure connection”. Do you have other solution? thanks!

      4. Wouter Delvaux Avatar
        Wouter Delvaux

        Maybe a little bit late but I had the same problem as nam and figured it out.
        You need to add a connectionusername and connectionpassword.
        the username should normally be the administrator.

        hope it helps :)!

      5. Wouter Delvaux Avatar
        Wouter Delvaux

        the code:

        type=”System.Web.Security.ActiveDirectoryMembershipProvider”
        connectionStringName=”ADConnectionString”
        connectionUsername=”Administrator”
        connectionPassword=”yourAdminPass”
        attributeMapUsername=”sAMAccountName”

  3. Ops! Here is the source error: Line 24:

  4. azsha Avatar
    azsha

    Thanks!!
    It was very useful for me!

  5. This was great, when will you be doing the post about the groups? I am really looking forward to that part since I would like to add that into my site.

    Thanks

    1. It is coming up soon, stay tuned!

  6. Lee James Avatar
    Lee James

    Freekin awesomely simple! After the rest of the verbose suggestions I found via google – this post was just genius.

    Cheers ๐Ÿ™‚

  7. Awesome!
    Thank you Ricardo!

  8. Thanks, your site has saved me loads of time figuring this one out. Any plans to do a blog on restricting access using AD groups any time soon ๐Ÿ˜‰

  9. Victor Avatar
    Victor

    Wow, exactly what I was looking for! Thanks man, you just save me a good deal of time trying to figure out how to do this.

  10. Jonathan Avatar
    Jonathan

    Hi – thanks for posting this. I the code blocks are images that are hard to read. Any chance you could post the actual code and/or make it downloadable? Many thanks.

  11. Fishy Avatar
    Fishy

    Thanks! I am looking forward to your next blog on using AD groups to restrict access

  12. Charlie2 Avatar
    Charlie2

    Many thanks for this writeup. I’ve been searching for this on Google and so far this is the only thing I found that relates to what I’m looking for. However, this instruction did not mention anything about the InitializeSimpleMembershipAttribute.cs file. So this file just be deleted or what? I’m using MVC4.

  13. Using model.RememberMe in the FormsAuthentication.SetAuthCookie would give the use of Remeber Me on the login page a different meaning. To persist a cookie across sessions should not be controlled by a user logging in. Remember Me should be used to remember the user name for convenience.

  14. This is awesome!! really helpful for me. Thanks for sharing with us. Following links also helped me to complete my task.

    http://www.mindstick.com/Articles/f769698f-fed6-43eb-8e61-d7baaf713819/

    http://msdn.microsoft.com/en-us/library/ff398049(v=vs.100).aspx

  15. I’m just getting into MVC for the first time after 13 years of webform programming. It’s quite a conceptual leap. However, my apps have always used AD authentication. Your guide made it soooo damn easy to get AD auth working on my first MVC project. I’m going to have to bookmark your site for future reference. Thanks!

    1. I am glad it was helpful for you!

  16. Thanks, this helped me a lot. With regard to FormsAuthentication I had the issue, where FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe); wasnt working properly;

    In WebConfig file you need to add the following lines,

    1. What lines?

  17. Tboy93 Avatar
    Tboy93

    Thanks for your article, it helped me a lot!

  18. […] been a year and one of the most popular posts in this blog still today is How To: Secure your ASP.NET MVC application and use Active Directory as the Membership Provider. In that post I promised to write about how to use Active Directory groups to restrict access to […]

Leave a Reply

Your email address will not be published. Required fields are marked *