Thursday, June 27, 2013

How to enforce secure HTTP access to an ASP.NET MVC Application.

To ensure that your actions are called through only Https, you can decorate your action methods with RequireHttps attribute. But this will not work in your development server as usually the development box is not configured with HTTPS. Basically you need to to apply this attribute conditionally based on a configurable item. This can be achieved by creating a custom class that is derived from RequireHttpsAttribute and by overridding its OnAuthorization().


using System;
using System.Configuration;
using System.Web;
using System.Web.Mvc;

public class RequireSslAttribute : RequireHttpsAttribute
    {
        private const string EnableSslKey = "EnableSSLForMySite";

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentException("filterContext");
            }

            if (!IsHttpContextNull(filterContext) && !IsEnableSsl())
            {
                return;
            }

            BaseOnAuthorization(filterContext);
        }

        protected virtual void BaseOnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
        }

        protected virtual bool IsHttpContextNull(AuthorizationContext filterContext)
        {
            return filterContext.HttpContext == null;
        }

        protected virtual bool IsEnableSsl()
        {
            var enableSslForMySite = HttpRuntime.Cache.Get(EnableSslKey);
            bool isEnableSsl = false;

            if (enableSslForMySite == null)
            {
                string configEnableSsl = ConfigurationManager.AppSettings[EnableSslKey] ?? string.Empty;

                isEnableSsl = (configEnableSsl.ToLower() == "true");
                HttpRuntime.Cache.Insert(EnableSslKey, isEnableSsl);
            }
            else
            {
                bool.TryParse(enableSsl.ToString(), out isEnableSsl);
            }

            return isEnableSsl;
        }
    }
BaseController
    [RequireSsl]
    public abstract class BaseController : Controller
    {
    }

No comments:

Post a Comment