views:

1790

answers:

5

How do I determine and force users to view my website using HTTPS only? I know it can be done through IIS, but want to know how its done programmatically.

+1  A: 

Like this: http://www.jameskovacs.com/blog/HowToAutoRedirectToASSLsecuredSiteInIIS.aspx

Byron Whitlock
this has worked for me before
Andrew Cox
A: 

This article covers moving requests in and out of SSL. Sometimes you dont want the user viewing a page in SSL because it burns proc cycles for pages that dont need to be secured.

http://weblogs.asp.net/kwarren/archive/2005/07/08/418541.aspx

keithwarren7
+5  A: 

You can write an HttpModule like this:

 /// 
    /// Used to correct non-secure requests to secure ones.
    /// If the website backend requires of SSL use, the whole requests should be secure.
    /// 
    public class SecurityModule : IHttpModule
    {
     #region IHttpModule Members
     public void Dispose()
     {
     }

     public void Init(HttpApplication application)
     {
      application.BeginRequest += new EventHandler(application_BeginRequest);
     }
     #endregion

     #region Events Handling
     protected void application_BeginRequest(object sender, EventArgs e)
     {
      HttpApplication application = ((HttpApplication)(sender));
      HttpRequest request = application.Request;
      HttpResponse responce = application.Response;

      // if the secure connection is required for backend and the current request
      // doesn't use SSL, redirecting the request to be secure
      if ({use SSL})
      {
       if (!request.IsSecureConnection)
       {
        string absoluteUri = request.Url.AbsoluteUri;
        responce.Redirect(absoluteUri.Replace("http://", "https://"), true);
       }
      }
     }
     #endregion

Where {use SSL} is a some condition whether to use SSL or not.

EDIT: and of course add a module definition in a web.config:

  <httpModules>
      <!--Used to redirect all the unsecure connections to the secure ones if necessary-->
      <add name="Security" type="{YourNamespace}.Handlers.SecurityModule, {YourAssembly}" />
      ...
     </httpModules>
    </system.web>
Alex
+2  A: 

You'd have to convert this from VB.NET to C#, but this is what I use in my sites:

Imports System.Web.HttpContext

Public Shared Sub SetSSL(Optional ByVal bEnable As Boolean = False)
  If bEnable Then
    If Not Current.Request.IsSecureConnection Then
      Dim strHTTPS As String = "https://www.mysite.com"
      Current.Response.Clear()
      Current.Response.Status = "301 Moved Permanently"
      Current.Response.AddHeader("Location", strHTTPS & Current.Request.RawUrl)
      Current.Response.End()
    End If
  Else
    If Current.Request.IsSecureConnection Then
      Dim strHTTP As String = "http://www.mysite.com"
      Current.Response.Clear()
      Current.Response.Status = "301 Moved Permanently"
      Current.Response.AddHeader("Location", strHTTP & Current.Request.RawUrl)
      Current.Response.End()
    End If
  End If
End Sub

It's more code than some of the other techniques, but there's a reason for it. This method will only redirect when it's not in the mode it should be in. And when it does do a redirect, it does a 301 (permanent) redirection. The benefit there is that search engines will follow the 301 redirection and that will prevent any possibility of them indexing the same page twice (in http and https mode). You can compare this with the default behavior of Response.Redirect (302 temporary redirect) which Google, for example, doesn't treat the same way. They will not change their index based on a temporary redirect.

So if you're on a page that you want to be SSL-encrypted, call it like this:

SetSSL(True)

Otherwise:

SetSSL(False)

And if you really need this to be globally applied, I'd call SetSSL(True) in the Application_BeginRequest of your global.asax. Beware that SSL will slow things down a bit. For that reason I'm typically very selective when switching between http and https. In fact, out of dozens of sites I've developed there's only been two that use SSL throughout the entire site.

Steve Wortham
A: 

IIR you can check the request (HttpContext.Current.Request) for the domain which you then can check what protocol is being used (http,https, ftp, etc)

acidzombie24