Last week my friend and colleague Greg Coffman had asked me if I knew of a way to restrict IP access to directories within the Sitecore web application, and I recalled reading a post by Alex Shyba quite some time ago.
Although Alex’s solution is probably good enough in most circumstances, I decided to explore other solutions, and came up with the following <httpRequestBegin> pipeline processor as another way to accomplish this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Hosting;
using Sitecore.Configuration;
using Sitecore.Diagnostics;
using Sitecore.Pipelines.HttpRequest;
using Sitecore.Web;
namespace Sitecore.Sandbox.Pipelines.HttpRequest
{
public class FilePathRestrictor : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (!ShouldRedirect(args))
{
return;
}
RedirectToNoAccessUrl();
}
private bool ShouldRedirect(HttpRequestArgs args)
{
return CanProcess(args, GetFilePath(args))
&& !CanAccess(args.Context.Request.UserHostAddress);
}
protected virtual string GetFilePath(HttpRequestArgs args)
{
if (string.IsNullOrWhiteSpace(Context.Page.FilePath))
{
return args.Url.FilePath;
}
return Context.Page.FilePath;
}
protected virtual bool CanProcess(HttpRequestArgs args, string filePath)
{
return !string.IsNullOrWhiteSpace(filePath)
&& !string.IsNullOrWhiteSpace(RootFilePath)
&& AllowedIPs != null
&& AllowedIPs.Any()
&& (HostingEnvironment.VirtualPathProvider.DirectoryExists(filePath)
|| HostingEnvironment.VirtualPathProvider.FileExists(filePath))
&& args.Url.FilePath.StartsWith(RootFilePath, StringComparison.CurrentCultureIgnoreCase)
&& !string.IsNullOrWhiteSpace(args.Context.Request.UserHostAddress)
&& !string.Equals(filePath, Settings.NoAccessUrl, StringComparison.CurrentCultureIgnoreCase);
}
protected virtual bool CanAccess(string ip)
{
Assert.ArgumentNotNullOrEmpty(ip, "ip");
return AllowedIPs.Contains(ip);
}
protected virtual void RedirectToNoAccessUrl()
{
WebUtil.Redirect(Settings.NoAccessUrl);
}
protected virtual void AddAllowedIP(string ip)
{
if (string.IsNullOrWhiteSpace(ip) || AllowedIPs.Contains(ip))
{
return;
}
AllowedIPs.Add(ip);
}
private string RootFilePath { get; set; }
private IList<string> _AllowedIPs;
private IList<string> AllowedIPs
{
get
{
if (_AllowedIPs == null)
{
_AllowedIPs = new List<string>();
}
return _AllowedIPs;
}
}
}
}
The pipeline processor above determines whether the IP making the request has access to the directory or file on the file system — a list of IP addresses that should have access are passed to the pipeline processor via a configuration file, and the code does check to see if the requested URL is a directory or a file on the file system — by matching the beginning of the URL with a configuration defined root path.
If the user does not have access to the requested path, s/he is redirected to the “No Access Url” which is specified in the Sitecore instance’s configuration.
The list of IP addresses that should have access to the directory — including everything within it — and the root path are handed to the pipeline processor via the following patch configuration file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<httpRequestBegin>
<processor patch:before=" processor[@type='Sitecore.Pipelines.HttpRequest.FileResolver, Sitecore.Kernel']"
type="Sitecore.Sandbox.Pipelines.HttpRequest.FilePathRestrictor, Sitecore.Sandbox">
<RootFilePath>/sitecore</RootFilePath>
<AllowedIPs hint="list:AddAllowedIP">
<IP>127.0.0.2</IP>
</AllowedIPs>
</processor>
</httpRequestBegin>
</pipelines>
</sitecore>
</configuration>
Since my IP is 127.0.0.1, I decided to only allow 127.0.0.2 access to my Sitecore directory — this also includes everything within it — in the above configuration file for testing.
After navigating to /sitecore of my local sandbox instance, I was redirected to the “No Access Url” page defined in my Web.config:
If you have any thoughts on this, or know of other solutions, please share in a comment.




