Recently I had a bit of a problem with a site on AppHarbor which I wrote about on their support forums: Request.IsSecureConnection always returns false
In short, because the load balancer is decrypting the HTTPS traffic before it hits the web app, attributes such as Request.IsSecureConnection
and configuration like requireSSL
on forms auth is not behaving as expected. In fact in the latter case, you can't even authenticate as the app thinks the request isn't coming over HTTPS.
It's the forms auth which is especially problematic because without it, cookies aren't set to "secure" and are sent back over HTTP if the site is accessed by domain name only and implicitly serves up the insecure URL scheme.
What would be the best workaround for this? I'd prefer to leverage the native security configuration, can anyone see a way to override the implementation which checks if the connection is secure? It's easy enough to detect whether the request was served over HTTPS (either based on Request.Url.Scheme
or the X_FORWARDED_FOR
header), it's just a question of neatly tying this in.
Alternatively, you can use the URL rewrite module to trick ASP.NET into thinking that it is running under a HTTPS context, and leave the requireSSL flags in place (which means the cookies will be set as secure - and only available if you really are running under HTTPS)
You can set the following in your web.config:
<rewrite>
<rules>
<rule name="HTTPS_AlwaysOn" patternSyntax="Wildcard">
<match url="*" />
<serverVariables>
<set name="HTTPS" value="on" />
</serverVariables>
<action type="None" />
</rule>
</rules>
</rewrite>
You'll also need to add HTTPS to the list of allowedServerVariables in the applicationHost.config (or through the URL REwrite config)
<rewrite>
<allowedServerVariables>
<add name="HTTPS" />
</allowedServerVariables>
</rewrite>
With thanks to Levi Broderick on the ASP.NET team who sent me in the right direction to this solution!
Turn off the RequireSSL setting and add the following code to your app. This should secure your authentication/session cookies.
void Application_EndRequest(object sender, EventArgs e)
{
if (Response.Cookies.Count > 0)
{
foreach (string s in Response.Cookies.AllKeys)
{
if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
{
Response.Cookies[s].Secure = true;
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With