HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Restrict environment access

Describes how to restrict access to the different environments available when working with solutions in Optimizely Digital Experience Platform (DXP).

📘

Note

This article pertains to the Optimizely Content Management System (CMS) 12/Optimizely Customized Commerce 14 versions. For CMS 11/Customized Commerce 13, see this article._

Customers may want to add security to their solution by restricting access to environments or views, such as locking the Integration and Preproduction environments, or to specific interfaces, such as the edit or admin view. Access is limited based on a particular range of IP addresses. See the following Microsoft documentation on how to restrict client IP address. You need to make modifications to get the correct IP address from the CDN.

The following code snippet blocks traffic except GET requests:

public class AdminSafeListMiddleware {
  private readonly RequestDelegate _next;
  private readonly ILogger < AdminSafeListMiddleware > _logger;
  private readonly byte[][] _safelist;

  public AdminSafeListMiddleware(
    RequestDelegate next,
    ILogger < AdminSafeListMiddleware > logger,
    string safelist) {
    var ips = safelist.Split(';');
    _safelist = new byte[ips.Length][];
    for (var i = 0; i < ips.Length; i++) {
      _safelist[i] = IPAddress.Parse(ips[i]).GetAddressBytes();
    }

    _next = next;
    _logger = logger;
  }

  public async Task Invoke(HttpContext context) {
    if (context.Request.Method != HttpMethod.Get.Method) {
      var remoteIp = GetRemoteIPAddress(context);
      _logger.LogDebug("Request from Remote IP address: {RemoteIp}", remoteIp);

      var bytes = remoteIp.GetAddressBytes();
      var badIp = true;
      foreach(var address in _safelist) {
        if (address.SequenceEqual(bytes)) {
          badIp = false;
          break;
        }
      }

      if (badIp) {
        _logger.LogWarning(
          "Forbidden Request from Remote IP address: {RemoteIp}", remoteIp);
        context.Response.StatusCode = (int) HttpStatusCode.Forbidden;
        return;
      }
    }

    await _next.Invoke(context);
  }

  private IPAddress GetRemoteIPAddress(HttpContext context, bool allowForwarded = true) {
    if (allowForwarded) {
      // Use the following code in DXP where IP restrictions are configured to
      // restrict access to only use CDN. If running the code elsewhere, ensure that you are
      // restricting access to Cloudflare IPs (https://www.cloudflare.com/ips/) or that you use
      // headers you trust.
      string header = (context.Request.Headers["CF-Connecting-IP"].FirstOrDefault() ?? context.Request.Headers["X-Forwarded-For"].FirstOrDefault());
      if (IPAddress.TryParse(header, out IPAddress ip)) {
        return ip;
      }
    }
    return context.Connection.RemoteIpAddress;
  }
}

If you want to block all traffic, including GET requests, remove this line from the code snippet:

if (context.Request.Method != HttpMethod.Get.Method)

📘

Note

Be aware that if you use an IP allowlist, legitimate services and integrations may not function as expected, such as example monitoring tools and validation of site responses during deployments.

See also: Sample Code