Secure Sitecore website with Basic Authentication using Global.asax

When it comes to websites generally or Sitecore individually, they should be protected and prevented from external access while they are being developed or under staging or UAT. There are some approaches to do this such as internal network restriction, whitelist IP limitation. In Sitecore, we can write custom code and inject to Sitecore pipeline to make the authentication. However, in relation to .NET, we also have a simpler way, that is taking advantages of Global.asax file.

Basically, Global.asax allows us to write code that runs in response to system level events such as the application begin request, application start or application error handling. In this blog, we will use Application_BeginRequest:

This is the default content of Global.asax in an empty Sitecore project:

<%@Application Language='C#' Inherits="Sitecore.Web.Application" %>

<%-- WARNING: Every custom application must derive from the Sitecore.Web.Application class. Otherwise some Sitecore features will not be available or will not work correctly. --%> 

We will modify to add some code for Application_BeginRequest:

private const string credentials = "[yourusername]:[yourpassword]";
private string[] allow = new string[] { "/404", "/500", "/api/" };

void Application_BeginRequest(object sender, EventArgs e)
{
	if (string.IsNullOrWhiteSpace(credentials)) return;

	var application = sender as HttpApplication;
	if (application == null) return;

	var context = application.Context as HttpContext;
	if (context == null) return;

	var request = context.Request as HttpRequest;
	if (request == null) return;

	var response = context.Response as HttpResponse;
	if (response == null) return;

	if (allow.Any(o => request.Url.AbsolutePath.StartsWith(o, StringComparison.OrdinalIgnoreCase))) return;

	var authorization = request.Headers["Authorization"];
	if (String.IsNullOrWhiteSpace(authorization) || !IsValid(authorization))
	{
		response.StatusCode = 401;
		response.AddHeader("WWW-Authenticate", "Basic realm=\"" + (request.Url.Host.ToLower()) + "\"");
		response.Write("Access Denied");
		response.Flush();
		response.Close();
		application.CompleteRequest();
	}
}
  1. credentials: defines the username and password
  2. allow: defines some URIs allowed under authentication. Its very useful if we want some URLs to be bypassed the authentication
  3. IsValid(authorization): checks the “Authorization” info from Header

The IsValid function looks like below. We parse the “Authorization” info and compare with the credentials which is pre-defined above.

private bool IsValid(string authorization)
{
	try
	{
		var parts = authorization.Split(new char[] { ' ' }, 2);
		if (parts.Length != 2 || !String.Equals(parts[0], "Basic", StringComparison.OrdinalIgnoreCase) || String.IsNullOrWhiteSpace(parts[1])) return false;
		Encoding encoding = Encoding.GetEncoding("iso-8859-1");
		var decoded = encoding.GetString(Convert.FromBase64String(parts[1]));
		if (String.Equals(decoded, credentials, StringComparison.OrdinalIgnoreCase)) return true;

	}
	catch (ArgumentException) { /* Authentication Failed */ }
	catch (FormatException) { /* Authentication Failed */ }
	return false;
}

And, this is the result:

After filling the correct username + password, we can see the website:

The full Global.asax can be downloaded here.

Got issues?

If you get issues or would like to discuss more, please leave a message or drop me an email at [email protected].

Thanks for reading and happy Sitecore coding!

Related Articles:

Leave a Comment