Requiring HTTPS for Certain ASP.NET Pages
I'm currently working on a project that has SSL capabilities. Users reach the site through a partner site, with the user's session using SSL only if the partner site also used secure communications. There's also an administrative section that, regardless of whether or not the user entered using SSL, must be accessed via SSL. How, then, do you ensure that when a user visits a particular page or subset of pages that they do so via a secure channel?
There are a couple of techniques that I'm aware of. Probably the most sound way is to make the setting through IIS. If you go to the IIS metabase you can right-click on the folder or website you want to require be accessed only through SSL and go to Properties. Next, tab over to the Directory or File Security tab (depending on if you're configuring a directory or file) and, in the Secure Communications section, click the Edit button. This will bring up the Secure Communications dialog box; from there you can click the "Require secure channel" checkbox and, voila, the directory or file can now only be visited through HTTPS.
Once you have made this setting if a client attempts to visit such a configured resource through HTTP (rather than HTTPS) an HTTP Error 403.4 - Forbidden: SSL is required to view this resource.
You can also require SSL programmatically through your ASP.NET pages' code-behind classes, which can be useful if you don't have direct access to the web server's metabase to make the settings as described above). (Realize that setting the "Require secure channel" option through IIS has the advantage that it requires a secure channel for all types of resources - ASP.NET pages, HTML pages, images, and so on. By making this setting through ASP.NET - either in a code-behind class or in an HTTP Module - will only require SSL in resources requests that IIS hands off the the ASP.NET worker process.)
With the ASP.NET code-behind technique you basically add a bit of code to your code-behind class (or, better yet, a base class or HTTP Module) that checks to see if the request is through a secure channel; if not, it redirects the user to the same URL but through HTTPS. An example can be seen in this blog entry: 443 <--> 80 - Seamlessly moving requests in and out of SSL.
In my project I ended up using both techniques, actually. For the ASP.NET pages in the administrative interface I used a technique very similar to the one described in the blog entry. My main difference, though, was that I added a check to see if the incoming request was coming through
localhost. If it was, then I didn't sweat the HTTP --> HTTPS translation. I just stayed with HTTP. (I did this because locally I do not have an SSL cert; sure, I could easily create and setup one, but why bother?) I went with the programmatic approach because the user might already 'legally' be on the site through HTTP and then click on a link to go to the admin page. I guess I could have went back and ensured that all admin links were fully qualified with URLs starting with
https://, but instead I opted to let the person hit the admin page through HTTP only to be auto-redirected to the same page, but through HTTPS. I used the IIS approach in a couple of places where I had
.htm files that needed to be protected. Also, I am using ELMAH on the site and wanted to ensure that its error log viewing page (
elmah/default.aspx) could only be viewed through SSL, so potentially sensitive information couldn't 'accidentally' be sent over an insecure channel.
In closing, here are some additional resources I found on this topic that are worth reading: