Note: This guide describes Kentico CMS version 7. Unfortunately, we cannot support this guide from version 8 forward. Go to latest documentation

Skip to end of metadata
Go to start of metadata

In some scenarios, SSL decryption and encryption may not performed directly by your application's server. Instead, the decryption and encryption is performed via a reverse proxy, which is equipped with an SSL offload hardware (for example, an SSL accelerator). This means that requests are forwarded to the application internally using the standard HTTP protocol, even when the client accesses the page through HTTPS. If the settings for using SSL are enabled for the website, it may result in a redirection loop.

You can solve this issue by adding custom code to the application's request handlers. It is necessary to appropriately set the IsSSL static property of the CMS.GlobalHelper.URLHelper class. If set to true, the system will treat all requests as secured, regardless of their URL format, and redirection to HTTPS page versions will not be performed by the application. Of course, it is necessary to correctly identify which requests originally used SSL, e.g., by checking the request headers.

 

 

Setting the IsSSL property

  1. Open your web project in Visual Studio, expand the App_Code folder (or Old_App_Code if you installed the project as a web application) and add a new class into it called SSLRequestLoader.cs.
  2. Edit the class and add the following references:

    using System.Collections.Specialized;
    
    using CMS.SettingsProvider;
    using CMS.GlobalHelper;
  3. Extend the CMSModuleLoader partial class and define a new attribute for it:

    [SSLRequestLoader]
    public partial class CMSModuleLoader
    {
        /// <summary>
        /// Module registration
        /// </summary>
        private class SSLRequestLoaderAttribute : CMSLoaderAttribute
        {
            ...
        }
    }
  4. Enter the following code into the SSLRequestLoaderAttribute class:

    /// <summary>
    /// Called automatically when the application starts
    /// </summary>
    public override void Init()
    {
        // Assigns a handler which is called before each request is processed
        CMSRequestEvents.Begin.Before += HandleSSLRequests;
    }
    
    // Checks if requests are forwarded as SSL
    private static void HandleSSLRequests(object sender, EventArgs e)
    {
        if ((HttpContext.Current != null) && (HttpContext.Current.Request != null))
        {
            // Loads the request headers as a collection.
            NameValueCollection headers = HttpContext.Current.Request.Headers;
    
            // Gets the value from the X-Forwarded-Ssl header.
            string forwardedSSL = headers.Get("X-Forwarded-Ssl");
                           
            URLHelper.IsSSL = false;
    
            // Checks if the original request used HTTPS.
            if (forwardedSSL == "On")
            {                
                URLHelper.IsSSL = true;
            }
        }
    }

In this example, we used the override of the Init() method (executed automatically when the application starts) to assign a handler that will be called before each request is processed. We also used the X-Forwarded-Ssl header to check if the original request was submitted via HTTPS before the SSL accelerator forwarded it to the application. If this is the case, the IsSSL property is set to true and the system processes the request as if it used the HTTPS protocol.

The proxy device may use a different method to identify requests that were originally secured by SSL. In such case, you will have to write a condition that fits your specific scenario (another typical approach is to check if the value of the X-Forwarded-Proto request header is https). You may also include additional custom code to fulfill any other security requirements, such as validation of the proxy's IP address.