MVC3 EF Code First Website Security

By candice

I’ve been working on a website which will also provide a mobile website using the same application. Part of the benefits of using MVC3 is that it builds the scaffolding for new areas that you decide to add. This is great but I don’t want my visitors to be able to maintain the content on the website so I need to secure these particular areas off. The trouble is, the way you do it in ASP.NET you generally secure off an entire directory. This doesn’t really lend itself to MVC3 – well, my implementation anyway. I have read only pages as well as functional pages that allow the content for that area to be maintained stored in a central area. The whole concept of MVC3 is that I need to really retain this structure, as far as I can see.

I figured that securing off an MVC3 website wasn’t going to be the same as ASP.NET so I decided to Google the subject. I came across this link which gave a number of options of how my site could be secured off: http://blogs.msdn.com/b/rickandy/archive/2011/05/02/securing-your-asp-net-mvc-3-application.aspx. Ultimately though, it’s not the same as ASP.NET!

I worked through their example and managed to secure off the portions that needed to be. Even though the examples were good they were still a bit vague. Where do I put certain code? I am a newbie at this after all. It didn’t take me long to figure it out – here’s what I did:

I created a Security Helper class which would hold the ‘rules’ for the security made up of the code snippets provided in the above link:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc; 

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]

public sealed class AllowAnonymousAttribute : Attribute { } 

namespace MyNamespace.Helpers
{
    public sealed class LogonAuthorize : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)
            || filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true);

            if (!skipAuthorization)
            {
                base.OnAuthorization(filterContext);
            }
        }
    } 

    public class SecurityHelper
    { 

    }

}

My Security Helper file still has the SecurityHelper class present as I think I may need this for other security aspects of the site.

Then in the global.ascx.cs file I updated the code to read:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new LogonAuthorize());
filters.Add(new HandleErrorAttribute());
}

By utilising this class I now have complete flexibility over the areas I want to make secure. For this application I want that particular flexibility. What this code has done however is made the entire site secure so now I need to tell the application what I’m happy to allow anyone to view.

In the extended area of my application I have a details page that I want everyone to see. So in the Controller class I simply need to add the following code above the call to the View:

[AllowAnonymous] 

So in this instance this would read:

[AllowAnonymous]     
public ViewResult Details(int id)
{
Opportunity opportunity = db. Opportunity.Find(id);
return View(opportunity);
}

Now if I try to access a part of the site that has not been marked to allow Anonymous Access it takes me to the Login page. Once I login it automatically returns me to the page I originally wanted to access.

I may want to introduce Role permissions using the aspnet security system but for now this works for me.

Now my list page has been secured off as it’s essentially part of my custom CMS I need to create a public version that will display the data and that I can incorporate the Google Map view into. Then I can get plotting!

Until next time …

Related posts