How To Make Your Episerver Website Run Via HTTPS

Security should be a big part of any Episerver project.  If your project has to deal with sensitive data, like your website visitors filling in a form with credit cards details, for example, then you will need to implement an SSL certificate so you server your web pages over HTTPS.

I recently learned that Google now even gives your website an SEO boost if you have HTTPS enabled for every page, as you can read from here.  In today’s guide, I’m going to cover how to implement HTTPS in your project.

I’m going to implement two solutions for implementing SSL in Episerver.  One will be via the web.config.  This is the easiest way but will require URLRewrite to be installed.  This route will enforce every page to use HTTPS and will not allow content editors to decide which page they want to make HTTPS.

The second option will be an Episerver specific way.  This is not as efficient in terms of total processing required, but, it will allow you to implement an ‘Enable HTTPS’ property on a page-type and allow content editors to decide.

Web.config Approach (Global)

The first thing you need to do is make sure you have URLRewrite installed on all of your web servers.  If you do not have it installed and you try and implement this solution, all you will see is a ‘500.19 – Internal Server Error’ message when you try and load your website up.  To get a copy of URLRewrite , head here.

Next, in your web.config file all you need to do is add this config (stolen from here)

  <rewrite>
      <rules>
        <clear />
        <rule name="Redirect to https" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="off" ignoreCase="true" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
        </rule>
      </rules>
    </rewrite>

It really is as simple as that, IIS will not redirect/append any request to use HTTPS instead of HTTP.

NOTE This set-up assumes that you will have an SSL certificate installed locally and your web server.  If you are running your environment over a load balancer then you have had to change the above to work with {HTTP_X_FORWARDED_PROTO} instead.

Episerver Way (Base Controller)

If you want to have a more Episerver friendly way then this is the approach you should take.  I’ve talked previously about the benefits of having a Base Mvc Page Controller that all your page type controllers should inherit from.  For this to work I’m assuming you have one already set-up.  The code should looks a bit like this for reference:

    public class BasePageController<T> : PageController<T>
        where T : PageData
    {
    }

In the base page controller, we want to override OnActionExecuting.  OnActionExecuting is the event that gets called in the MVC pipeline before an action method is invoked.  If we override this, it means we can make sure no actions are ever invoked unless they fulfill our requirements.

The first thing we need is to define an interface that we can add onto any page type that we want the ‘Required HTTPs’ options to appear on:

 public interface ISecurityProperties
 {
      bool RequiresHttps { get; }
 }

The next step is to add a check on the base controller to redirect if the page has ‘Required HTTPs’ set:

        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var requireHttps = filterContext.ActionParameters.Keys
                    .Select(key => filterContext.ActionParameters[key])
                    .OfType<ISecurityProperties>()
                    .FirstOrDefault()
                    .IfNotDefault(x => x.RequiresHttps, () => true);

            if (requireHttps)
            {
                 if (!IsRequestSecure(filterContext.HttpContext.Request))
                 {
                     var url = GetSecureUrl(filterContext.HttpContext.Request);
                     filterContext.Result = new RedirectResult(url);
                 }
            {

            base.OnActionExecuting(filterContext);
        }

        private static bool IsRequestSecure(HttpRequestBase request)
        {
            return request != null && (request.IsSecureConnection || ProxyIsSecureConnection(request));
        }

        private static string GetSecureUrl(HttpRequestBase request)
        {
            if (request == null)
                return string.Empty;

            var requestUrl = request.Url;
            if (requestUrl == null)
                throw new InvalidOperationException("\"requestUrl\" cannot be null.");

            return $"https://{requestUrl.Host}{request.RawUrl}";
        }

        private static bool ProxyIsSecureConnection(HttpRequestBase request)
        {
            InputValidator.ValidateObject(request);

            return request.Headers["HTTPS"] != null && request.Headers["HTTPS"].Equals("true", StringComparison.OrdinalIgnoreCase);
        }

In the code, we check if the ‘RequiredHttps’ boolean is set. We get this out of the request directly out of the Session key value pair, rather than trying to cast to a safely typed Episerver page object.  If the page is set as require HTTPS, we then call IsRequestSecure() to make sure the request is an HTTPS request.

I won’t go over the code in too much detail of IsRequestSecurehere, as this is all very bog standard .NET stuff.  I’m getting the current URL, checking the HTTP Request header to check that IsSecureCOnnection is set or at a minimum, HTTPS exists in the header.  If it doesn’t exist then I create a new Url with HTTPS included in the URL, and then set the request to re-direct to it.

Conclusion

In today’s guide, I’ve covered how to set-up and enable SSL on your web project to enable HTTPs to work.  We went over two options.  One that works directly in the web.config. This is good if you want to enforce that all your page works over HTTPS.  If you want to have more control over which pages work over HTTPs in Episerver then I also covered the code you will need to do this.  In your base page controller, we override the OnActionExecuting method, check if the current page object has the ‘RequireHttps’ boolean enabled.  If it has we check the current request is not HTTPS already.  If it is we carry on as normal, if it isn’t then we force a re-direct to use HTTPs.

Jon D Jones

Software Architect, Programmer and Technologist Jon Jones is founder and CEO of London-based tech firm Digital Prompt. He has been working in the field for nearly a decade, specializing in new technologies and technical solution research in the web business. A passionate blogger by heart , speaker & consultant from England.. always on the hunt for the next challenge

More Posts

2 replies
  1. Adrian Chandler
    Adrian Chandler says:

    You say this is just bog standard c# but these lines throw errors?

    .IfNotDefault(x => x.RequiresHttps, () => true);

    $”https://{requestUrl.Host}{request.RawUrl}”;

    I’m assuming they are custom and not described here?

    Reply
    • Jon D Jones
      Jon D Jones says:

      ifNotDefault() is a custom extension method i use. The request line is all part of the code. You can swap it out for .Where(x => x.RequiresHttps == true)

      The second part is .net 4.5.2. You can replace with a string.format(“https://{1}{2}”, requestUrl.Host, request.RawUrl);
      Sorry forgot about that one 😛

      Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *