Setting up SSL correctly with IIS and ASP.NET

I recently acquired an SSL certificate for my client, and I discovered that while things are not that hard to setup, there are also things that are not really documented anywhere.

First, lets assume that you actually want to force SSL, which seems like a good thing in many cases, but you also want to have an automatic and graceful redirect should someone try to use regular http.  So what do we do?  You could add code to all of your pages, or to your base page, or in the global events, to check if https was used, and if not then issue a redirect to https -- you could, but I wouldn't.  Why not?  This requires code changes specifically for your SSL situation, which will make it harder to run on developer configurations, at least without some more elaborate code options.  This will also make it harder to turn off the requirement to use SSL should something go wrong, and it ignores any non ASP.NET files that you also want to protect with SSL -- so you really should be looking at IIS instead.  The first thing we do is open the IIS MMC tool, select properties for our site, go to the directory security tab, click the edit button at the bottom in secure communications, and then check the require secure channel option.  That's the easy part, of course, since you'll quickly discover that there is no option to automatically redirect your http traffic to https -- although it seems like this would be an obvious option for MS to add to IIS.  If this is all you do then you'll notice that the user will see a 403;4 error, which should be the next hint to what we want to do -- setup a custom error in IIS -- again sticking to IIS and not relying on the web.config custom errors will better protect all your files.  So the next thing we do, again in the IIS MMC tool under our site's properties, is go to the custom errors tab, select the 403;4 error type, edit its properties to be a URL in your site -- something like /NonSSL/SSLRedirect.aspx for instance.  The next step should be clear at this point -- create the appropriate file for the custom error, /NonSSL/SSLRedirect.aspx in my example, and have it issue the redirect -- something like Response.Redirect("https://www.YourDomain.com/").  We're almost there now, but we have one or two circular cases, depending on your configuration, that we have to handle in order for it to work properly.  The first circular case will affect everyone -- basically your custom error can't redirect the user to a page in your http site if SSL is required for the entire site.  So using the IIS MMC tool, select the properties for the custom error file or directory you have created, the NonSSL directory in my example, go to the directory security tab, click the edit button at the bottom in secure communications, and then UN-check the require secure channel option.  That might be enough for your site, but if you use ASP.NET authentication you'll need to do one more thing -- otherwise your custom error redirect will end up redirecting to your login page back on the http site -- and you'll have another circular case.  So to finish off this automatic redirect for SSL, just edit your site's web.config file by adding a location tag for your redirect file, location path="NonSSL/SSLRedirect.aspx" in my example, and then add the authorization tag for allow users="?,*".  That may seem like you're removing security, but its only for the specific file that you want all of your users to get to, even before they are authenticated, in order for them to be able to successfully be redirected to your SSL site.

There's also a few oddities that you may or may not experience when forcing SSL that are separate from the redirect issue, and once again they are not well documented in any obvious manner.  Does your site have any files that are downloaded dynamically through aspx files?  By this I don't mean a hard-coded link somewhere, but an aspx page that sets the appropriate content type and header and writes the content to the stream, so that a virtual file is downloaded.  If so, then most examples I've seen tell you to set the cache policy to nocache to make sure you always get the real download from the server, but this nocache will fail with SSL for your IE users!  That last part is quite interesting -- your FireFox users will not have a problem -- just your IE users!  I'm still not sure I like taking out the nocache policy, but I left the code to immediately expire the response, so hopefully this will not be an issue if you have some similar code for expiring the response.  Another oddity I have is that I have a couple of virtual directories that are mapped to network shares with a specific set of security tokens.  There's not actually a problem with this scenario, but if you incorrectly answer the popup dialogs that the IIS MMC might give you when setting SSL to be required, then you may find that your security credentials are "lost".  Or maybe you turn off the requirement for SSL for some reason -- that can also cause your sub-directories to lose their settings, whether it be network share security tokens or special SSL settings like we did for the NonSSL directory above.  So the best policy is to always check your special settings that apply to any sub-directories or files, including the setting of network share security tokens, whenever you change the requirement for SSL -- regardless of whether you are enabling or disabling it.

I believe that this is all that is necessary, although there may be other special situations that I haven't encountered, but whatever you do make sure this is documented for yourself and your administrators -- else you will find yourself having new problems everytime one is fixed!

6 Comments

  • Well I never said that setting up SSL for auto-redirects was "hard" or that it would take more than 10 minutes -- just that there are some gotchas to watch out for. I still prefer doing it in IIS personally, instead of having to learn and include a 3rd party module, but its nice to see alternatives anyhow.

  • Couldn't you simply use host headers in IIS to solve this problem by performing a 301 redirect on the 80 port to the 443 port?

    Not sure if this will work but you would set up 2 separate sites in iis. One site has only the 80 port configured. This site would do a permanent redirect to the other site which only has the 443 port configured. This way any traffic coming in from port 80 would get permanently redirected to the actual site on the 443 port.

    This avoids placing scripts in a site.

  • Sounds like an easy and direct alternative Matt.

  • Carlos you cant do that as it requires an absolute url. It can't start with http:// or https://.

    It's not neccessary to do the redirect with code. I serve RedirectSSL.file which is an empty file. IIS is configured to redirect all traffic to the file to the https website. Substantially easier than redirecting with code :)

  • Another way around the non-ssl IIS issue is to set a host header that will never occur, e.g nevergonnahappen.com. This will completely close the door to requests to the website.

  • Great post. Excellent solution.

Comments have been disabled for this content.