So in my code I want to detect if my login page is being called http, and redirect it to https.
I know there are non code ways to skin this cat, but for frustrating technical reasosn I'm backed into doing it in code.
if (!Request.IsSecureConnection)
{
string redirectUrl = Request.Url.ToString().Replace("http:", "https:");
Response.Redirect(redirectUrl);
}
So I drop this in my Page_Load(...)
, make sure my debugger uses real IIS, not VS2008s IIS, and hit debug.
Inthe debugger, waltz along, hit Response.Redirect("https://localhost/StudentPortal3G/AccessControl/AdLogin.aspx"), hit f5.
Get "Internet Explorere Cannot Display the webpage, url is HTTP, not HTTPS. Not getting an informative error... same thing happens not running in the debugger.
So what am I missing? it does not appear to be rocket science, I've seen similar code on lots of blogs...
What am I doing wrong? I figure it has to be a totally obvious Rookie mistake, but I'm not seeing it.
disclaimer - I was involved in the development of this project
I would recommend using http://nuget.org/packages/SecurePages/ It gives you the ability to secure specific pages or use Regex to define matches. It will also force all pages not matching the Regex or directly specified back to HTTP.
You can install it via NuGet:
Install-Package SecurePages
Docs are here: https://github.com/webadvanced/Secure-Page-manager-for-asp.net#secure-pages
Simple Usage:
or
You can also use the new UriBuilder:
C#
Here's my solution:
Where
Settings.CanonicalDomain
is your HTTPS hostname. It 301 redirects which may be the proper response in some cases.I usually call the following from the OnPreInit in a base class that all my pages inherit from. Of course, you could just do this in every page...but you wouldn't want to do that now would you?
Note that I've got two properties for each page so that I can specify the SSL requirement for each page (RequiresSSL) while I can also override and redirect check if I want (with IgnoreRequiresSSL, which is helpful for pages like error pages that you rewrite to and don't know whether they'll be encrypted or not), but of course, you can remove these for simple setups.
One of the ways that I was able to enforce an https redirect is to the following:
In the app pool I have my application running on just port 443 so that there is no possiblity for an unencrypted session to occur (unless encryption scheme is broken through a vulnerability..). I created another application on port 80 with the same IP address which contains just a web.config file with the following code
I'd do a
!Request.IsLocal
as well to make sure that I'm not debugging, though if you're using a real instance of IIS with a cert applied when debugging that shouldn't be an issue.Note: This answer assumes an MVC context within a Controller where
HttpContext
is a property holding the current context. If you're unlucky enough to still be using WebForms or are referencing the context in a degenerate way you will need to useHttpContext.Current.ApplicationInstance.CompleteRequest()
.Note: I've updated this to be consistent with the recommended pattern to terminate the request according to the framework documentation.