You are on page 1of 2

Redirect to HTTPS while using Amazon Elastic Load Balancer (includes Elastic Beanstalk)

The other week, I had the privilege of setting up staging and release servers for Locabals website. For ease of scalability, we decided it would be best to deploy our ASP.NET website on Amazons Elastic Beanstalk (EBS). By managing server instances, load balancer, and their respective configurations, EBS is Amazons Platform as a Service solution. We just drop our project into the EBS container, and it manages the provisioning of the servers to run our application. It will even monitor the health of your application and send you emails and/or spin up more server instances based on the health rules you determine. That stuff is great, but let us look at how SSL encryption is handled using these tools. SSL terminated at the load balancer is the preferred method of encryption while using Amazons Elastic Load Balancer (which is a component of the EBS solution). This means all of the traffic to our website, both port 80 and port 443, make it to the load balancer, then the load balancer communicates with the servers exclusively over port 80. Setting up your SSL certificate is fairly straight forward with the Elastic Load Balancer, but the problem occurs when your application needs to be able to check if the client is connected to the site with a secure connection.

EC2 Instances

Elastic Load Balancer

Clients

80

80, 443

Using the [RequireHttps] attribute introduced in ASP.NET MVC2 does not work when using Elastic Beanstalk because the connection between the load balancer and application server is not secure. However, you are not really concerned with the security of the connection between the load balancer and the server, but you do want to check the security of the connection between the client and the load balancer. To do this, Amazon provides a clever feature with their load balancer. At the load balancer, an extra header is added to the original request made by the client. The header key is XForwarded-Proto and it will have a value of either http or https. By checking this header, your application can determine if the client is using a secure connection.

EC2 Instances

Elastic Load Balancer

Clients

X-Forwarded-By: http or https

HTTP/HTTPS Request

There are several ways of accomplishing the redirect. The best solution I could come up with is to write a custom attribute to replace the [RequireHttps] attribute that people expect to use in MVC. Below is the code for our attribute that I mostly used Stack Overflows user Alexs answer here: http://stackoverflow.com/questions/3628181/asp-net-mvchow-to-automatically-disable-requirehttps-on-localhost . I modified the code to work with Elastic Load Balancer.
public class RequireSSLforEBSAttribute : FilterAttribute, IAuthorizationFilter { public virtual void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } if (!String.Equals(filterContext.HttpContext.Request.Headers["X-Forwarded-Proto"], "https", StringComparison.OrdinalIgnoreCase)) { HandleNonHttpsRequest(filterContext); } } protected virtual void HandleNonHttpsRequest(AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.Url.Host.Contains("localhost")) return; string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl; filterContext.Result = new RedirectResult(url); } }

You might also like