Wednesday 25 December 2013

Identifying https or SSL connection in load balancing environment in ASP.NET

Leave a Comment
In my current project, I’ve got one situation where I’ve to found whether URL is loading over http or https protocol. I’ve used below code to determine URL protocol:
string urlProtocol = HttpContext.Current.Request.Url.Scheme.ToLower();
Above code was working as expected in development server. For example :

1.)    URL : http://www.abc.com
value of urlProtocol = http
2.)    URL : https://www.abc.com
value of urlProtocol = https

However, code was failing in Production (LIVE) servers. Production servers are setup in load balancing environment (also known as Web Farm environment). I was getting below result in LIVE environment:

1.)    URL : http://www.abc.com
value of urlProtocol = http
2.)    URL : https://www.abc.com
value of urlProtocol = http  (which is incorrect)

Finally after spending few hours on this issue, I’d finally found the solution. In our production load balancing clustered hosting environment, the method for SSL detection (https) is a little different to what you might be familiar with.  We have separate SSL load balancer to enable SSL functionality across multiple web servers in a clustered environment. SSL is configured at load balancer level which means that SSL certificate for www.abc.com is installed on load balancer directly.

Therefore in this type of load balancing environment, the SSL connection stops at the load balancer level. Thus you can never test for an SSL connection using standard methods such as:
HttpContext.Current.Request.IsSecureConnection
HttpContext.Current.Request.Url.Scheme
Request.ServerVariables("HTTPS")
HttpContext.Current.Request.Url.AbsoluteUri.Contains("https://")
A custom header field gets inserted into the header to assist in identifying a secure request (https) in a load balancing environment.  I’ve checked with my hosting provider and ask them to insert a header field such as HTTP_X_FORWARDED_PROTO. This header field can vary for different hosting scenarios. It can be X-FORWARDED-PROTO or HTTP_X_FORWARDED_PROTO or HTTP_CLUSTER_HTTPS etc. Please make sure that your SSL load balancer is actually inserting these header fields into header. You can use below code to identify all server variables for a site:
foreach (string var in Request.ServerVariables)
{
  Response.Write(var + " " + Request[var] + "
");
}
Above code will list all server variables available for a site. In my case HTTP_X_FORWARDED_PROTO was the desired server variable. I’ve used below code to determine https or SSL connection:
bool isSecureConnection = String.Equals(Request.ServerVariables["HTTP_X_FORWARDED_PROTO"], "https", StringComparison.OrdinalIgnoreCase);
HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_PROTO"] which will be set to 'HTTPS' if the user is accessing web page over SSL and will be null if the user is browsing over http.

Comments and suggestions are most welcome. Happy coding! 

0 comments :

Post a Comment