|
Imports System.Web
''' <summary>
''' The SSLHelper class provides Shared methods for ensuring that a page is rendered
''' securely via SSL or unsecurely.
''' </summary>
Public Class SSLHelper
Private Const UnsecureProtocolPrefix As String = "http://"
Private Const SecureProtocolPrefix As String = "https://"
''' <summary>
''' Requests the current page over a secure connection, if it is not already.
''' </summary>
''' <param name="hostPath">The host path to redirect to if needed.</param>
''' <param name="maintainApplicationPath">
''' A flag indicating whether or not to maintain the current application path if
''' a redirect is necessary.
''' </param>
Public Shared Sub RequestSecurePage(ByVal settings As SecureWebPageSettings)
' Is this request secure?
Dim RequestPath As String = HttpContext.Current.Request.Url.ToString()
If RequestPath.StartsWith(UnsecureProtocolPrefix) Then
' Is there a host path to redirect to?
If settings.EncryptedUri Is Nothing OrElse settings.EncryptedUri.Length = 0 Then
' Replace the protocol of the requested URL with "https"
RequestPath = RequestPath.Replace(UnsecureProtocolPrefix, SecureProtocolPrefix)
Else
' Build the URL with the "https" protocol
RequestPath = BuildUrl(True, settings.MaintainPath, settings.EncryptedUri, settings.UnencryptedUri)
End If
' Redirect to the secure page
HttpContext.Current.Response.Redirect(RequestPath, True)
End If
End Sub
''' <summary>
''' Requests the current page over an insecure connection, if it is not already.
''' </summary>
''' <param name="hostPath">The host path to redirect to if needed.</param>
''' <param name="maintainApplicationPath">
''' A flag indicating whether or not to maintain the current application path if
''' a redirect is necessary.
''' </param>
Public Shared Sub RequestUnsecurePage(ByVal settings As SecureWebPageSettings)
' Is this request secure?
Dim Request As HttpRequest = HttpContext.Current.Request
Dim RequestPath As String = Request.Url.ToString()
If RequestPath.StartsWith(SecureProtocolPrefix) Then
' Is there a different URI to redirect to?
If settings.UnencryptedUri Is Nothing OrElse settings.UnencryptedUri.Length = 0 Then
' Replace the protocol of the requested URL with "http"
RequestPath = RequestPath.Replace(SecureProtocolPrefix, UnsecureProtocolPrefix)
Else
' Build the URL with the "http" protocol
RequestPath = BuildUrl(False, settings.MaintainPath, settings.EncryptedUri, settings.UnencryptedUri)
End If
' Test for the need to bypass a security warning
Dim Bypass As Boolean
If settings.WarningBypassMode = SecurityWarningBypassMode.AlwaysBypass Then
Bypass = True
ElseIf settings.WarningBypassMode = SecurityWarningBypassMode.BypassWithQueryParam AndAlso Not Request.QueryString(settings.BypassQueryParamName) Is Nothing Then
Bypass = True
' Remove the bypass query parameter from the URL
Dim NewPath As New System.Text.StringBuilder(RequestPath)
Dim i As Integer = RequestPath.IndexOf(settings.BypassQueryParamName)
NewPath.Remove(i, settings.BypassQueryParamName.Length + Request.QueryString(settings.BypassQueryParamName).Length + 1)
' Remove any abandoned "&" character
If i >= NewPath.Length Then
i = NewPath.Length - 1
End If
If NewPath(i) = "&"c Then
NewPath.Remove(i, 1)
End If
' Remove any abandoned "?" character
i = NewPath.Length - 1
If NewPath(i) = "?"c Then
NewPath.Remove(NewPath.Length - 1, 1)
End If
RequestPath = NewPath.ToString()
Else
Bypass = False
End If
' Output a redirector for the needed page to aSub a security warning
If (Bypass) Then
Dim Response As HttpResponse = HttpContext.Current.Response
Response.Clear()
' Refresh header
Response.AddHeader("Refresh", String.Concat("0;URL=", RequestPath))
' JavaScript to replace the current location
Response.Write("<html><head><title></title>")
Response.Write("<!-- <script language=""javascript"">window.location.replace(""")
Response.Write(RequestPath)
Response.Write(""");</script> -->")
Response.Write("</head><body></body></html>")
Response.End()
Return
End If
' Redirect to the insecure page
HttpContext.Current.Response.Redirect(RequestPath, True)
End If
End Sub
''' <summary>
''' Builds a URL from the given protocol and appropriate host path. The resulting URL
''' will maintain the current path if requested.
''' </summary>
''' <param name="secure">Is this to be a secure URL?</param>
''' <param name="maintainPath">Should the current path be maintained during transfer?</param>
''' <param name="encryptedUri">The URI to redirect to for encrypted requests.</param>
''' <param name="unencryptedUri">The URI to redirect to for standard requests.</param>
''' <returns></returns>
Private Shared Function BuildUrl(ByVal secure As Boolean, ByVal maintainPath As Boolean, ByVal encryptedUri As String, ByVal unencryptedUri As String) As String
' Get the current request
Dim Request As HttpRequest = HttpContext.Current.Request
Dim CurrentUrl As String = Request.Url.ToString()
' Build the needed URL
Dim Url As New System.Text.StringBuilder
' Host path (secure.mysite.com/)
If secure Then
Url.Append(encryptedUri)
Else
Url.Append(unencryptedUri)
End If
Url.Append("/")
If maintainPath Then
' Calculate the length of the appropriate target URI
Dim RootLength As Integer = 0
If CurrentUrl.StartsWith(UnsecureProtocolPrefix) Then
RootLength = UnsecureProtocolPrefix.Length + unencryptedUri.Length
Else
RootLength = SecureProtocolPrefix.Length + encryptedUri.Length
End If
' Get the path from the current URL after the target URI
Url.Append(CurrentUrl.Substring(RootLength))
Else
' Append just the current page
Url.Append(CurrentUrl.Substring(CurrentUrl.LastIndexOf("/"c) + 1))
End If
' Replace any double slashes with a single slash
Url.Replace("//", "/")
' Prepend the protocol
If secure Then
Url.Insert(0, SecureProtocolPrefix)
Else
Url.Insert(0, UnsecureProtocolPrefix)
End If
Return Url.ToString()
End Function
End Class
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I began programming on my Commodore 64 at around the age of 12. After migrating to DOS and then Windows, I decided to take on the Web. Several languages and platforms later, I have settled in with .NET nicely. I am currently the owner of a software consulting company and lead application developer for a learning-based technology consultation company.
The love of a finished application is usually at war with the desire to improve it as soon as it's released (they're never really finished).