In more traditional scenarios the SSL certificate is installed in the web server (IIS) and the web server uses the certificate to encrypt data sent between the client web browser and the web server when requests are made using the https protocol.

SSL Proxy servers have been around for a long time but are becoming much more common in the age of cloud computing for a number of reasons. One reason is because cloud computing often involves multiple web servers such as a web farm. When you have mutltiple web servers it becomes more complicated to install SSL certificates and keep them updated on each node of the web farm or cluster. Usually in those scenarios you will have a load balancer that delgates the incoming traffic to the different nodes of the web farm to divide the load among the available servers. A load balancer is just another kind of proxy server in that it acts as a proxy for the real web server. Client requests from web browsers in this scenario do not go directly to the web server or servers but to the proxy server which in turn makes a request on behalf of the client to the web server, gets the result and sends it back to the client. The client in this case doesn't know that it is not talking directly to the web server. So proxy servers are like a middle man between the web browsers and the web servers. A proxy server can do various tasks to process the web requests, we already mentioned load balancing, but a proxy server can also have the SSL certificate installed on it instead of on the web server(s). In this case the proxy server is the one that encrypts the traffic between itself and the web browser. The web server in this case does not have an SSL certificate so it is not encrypting anything, usually the proxy server talks to the web server over a private network using the standard port 80 and the http protocol. So the web server in this case is not seeing secure requests it just just seeing normal web traffic, while the proxy server is taking the result from the web server and encrypting it before sending it back to the web browser.

So how does that affect mojoPortal?

When you add this setting in appSettings:

<add key="SSLIsAvailable" value="false" />

it does several things. It causes mojoPortal to try to secure the pages that it knows need to be secure such as login, register, user profile pages.

mojoPortal will also surface a new page setting so that you can set indivudual pages to require ssl/https, and it surfaces a new site setting that can be used to force all pages in the site to use ssl/https.

But here is the rub, in order for mojoPortal to be able to force secure requests, it has to be able to detect the difference between a secure request and a non secure request, so that it can redirect the non secure requests to be secure. The normal way to detect a secure request is to check the value of 

HttpContext.Current.Request.IsSecureConnection

But in this scenario it always returns false, because as stated the traffic between the web server and the proxy server is not really secure, only the traffic between the proxy server and the web browser is secure.

So what happens as a result is an infinite redirect loop. A non secure request comes in, gets redirected to https but then it is still not detected as a secure request so it just keeps redirecting.

How Do We Solve That?

One option is to just set SSLIsAvailable to false and ask your host if they have a way to force all traffic to be secure.

Other options depend on the proxy server. Most proxy servers create some kind of custom server variable that can be used from web code to know that it is really a secure request even though the web server is not the one making it secure. In mojoPortal we have a built in page that can show the server variables but it is disabled by default, you can enable it by finding this in Web.config and set it to true, or copy it to user.config and set it to true there:

<add key="EnableDeveloperMenuInAdminMenu" value="false" />

Now when you login as admin, you can go to Administration > Advanced Tools > Developer Tools > Server Variables

You will need to keep SSLIsAvailable as false while doing this otherwise the login link will get stuck in the redirect.

What you want to do is compare the server variables you see at

http://yoursiteroot/DevAdmin/ServerVariables.aspx
and at
https://yoursite/DevAdmin/ServerVariables.aspx

You are looking for a variable that either changes values under https or a variable that only appears under https.

For one of my customers he saw that when using https there was a variable named HTTP_HTTPS that appeared, but when using http, it disappeared.
For that case, it would be solved by adding this in Web.config or user.config

<add key="SecureConnectionServerVariableForPresenceCheck" value="HTTP_HTTPS" />

For another customer he saw that when using https it had a variable named HTTP_X_FORWARDED_PROTO with a value of https, and when he used http, the same variable exists but it has a value of http. For that case it would be solved by adding this in Web.config or user.config

<add key="SecureConnectionServerVariableForValueCheck" value="HTTP_X_FORWARDED_PROTO" />
<add key="SecureConnectionServerVariableSecureValue" value="https" />

In both cases we are telling mojoPortal code something it can look for in the server variables to determine if the request is secure or not, and now we can set SSLIsAvailable back to true and it should work correctly. 

What if I Don't See any Custom Server Variables That Indicate a Secure Request.

In that case, you will have to leave SSLIsAvailable as false and ask your host if they have a way to force all your traffic to be secure.

 

Created by Joe Audette on Jan 19, 2015