UPDATED: 4/25/2008 – See my new post of Partial SSL in Asp.Net MVC using the RequireSSL attribute from the MVC Futures Project
Tonight I was working on a small Asp.Net MVC project and was trying to add authorization and “require ssl” to specific pages using IIS. Of course you don’t have pages like you used to in Web Forms, so setting security and SSL on a per directory and per file basis doesn’t work like I’m used to.
The authorization requirement is actually pretty easy to handle once I approached the problem from a strictly MVC point of view. Using the Authorize attribute, which is included with Asp.Net MVC, I was able to pick and choose which controller actions I wanted to secure. In the code sample below I’m requiring the requestor to belong to the Users role.
[AcceptVerbs(HttpVerbs.Get), RequireSslFilter(Order=1), Authorize(Roles="Users",Order=2)]
public ActionResult ToServer()
{
return View("ToServer");
}
When you need a little more control, you can implement a class that inherits from AuthorizeAttribute. Examples of when you might want to do this, would be if you wanted to change the authorized role at runtime, or not require any role (perhaps in your dev environment), or when you want to require SSL. In the above example you can see the RequiresSslFilter, which is a custom filter implemented as shown below which requires the use of SSL.
public class RequireSslFilter:AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
if (httpContext.Request.IsLocal == false && httpContext.Request.IsSecureConnection == false)
httpContext.Response.Redirect(httpContext.Request.Url.ToString().ToLower().Replace("http", "https"));
return base.AuthorizeCore(httpContext);
}
}
In the code, I’m checking for if the request is local and secure, and redirecting to a secure version of the request. The check for IsLocal is useful for development scenarios. I added the Order parameter to the use of the RequiresSslFilter attribute to ensure that I check for the use of SSL before the check for the role. This helps ensure that credentials are only sent over SSL.