Basic Auth with Sitecore
A custom attribute can be created in order to support Basic Auth with a custom API. The end goal is to be able to use a new AuthorizeAccess attribute like this:
This new AuthorizeAccess attribute has a parameter called Role which accepts Sitecore roles and can be placed at the class or the action levels depending on the requirement. The goal is to return a 404 status code if the request comes with an authorization header (username:password base64 encoded) that does not belong to the specified role.
Let's get into the details of our new attribute, we need to create a class like this:
Now we only need to decorate our classes/actions and take advantage of Basic Auth.
Happy Sitecoring fellas!
namespace xxx.xxx.xxx
{
[AuthorizeAccess(Role = @"ROLENAME")]
public class TestController : ServicesApiController
{
[HttpGet]
public IHttpActionResult FetchItem(string identifier)
{
var contentItem = GET ITEM BASED ON THE IDENTIFIER;
if (contentItem != null)
{
return Ok(contentItem);
}
return Content(HttpStatusCode.NotFound, "Item not found");
}
}
}
This new AuthorizeAccess attribute has a parameter called Role which accepts Sitecore roles and can be placed at the class or the action levels depending on the requirement. The goal is to return a 404 status code if the request comes with an authorization header (username:password base64 encoded) that does not belong to the specified role.
Let's get into the details of our new attribute, we need to create a class like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using System.Web.Mvc;
using ActionFilterAttribute = System.Web.Http.Filters.ActionFilterAttribute;
namespace xxx.xxx.xxx
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeAccessAttribute : ActionFilterAttribute
{
public string Role { get; set; }
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext filterContext)
{
var authorizationHeader = HttpContext.Current.Request.Headers["Authorization"];
if (string.IsNullOrEmpty(authorizationHeader) || !IsUserInRole(authorizationHeader, Role))
{
filterContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden);
}
}
private bool IsUserInRole(string authorizationHeader, string role)
{
if (string.IsNullOrEmpty(authorizationHeader))
{
throw new ArgumentNullException(nameof(authorizationHeader));
}
if (string.IsNullOrEmpty(role))
{
throw new ArgumentNullException(nameof(role));
}
string credentials = Encoding.UTF8.GetString(Convert.FromBase64String(authorizationHeader.Substring(BasicAuth.Length).Trim()));
var credentialsArray = credentials.Split(':');
string username = credentialsArray.First();
string password = credentialsArray.Last();
if (string.IsNullOrEmpty(username))
{
throw new ArgumentNullException(nameof(username));
}
if (string.IsNullOrEmpty(password))
{
throw new ArgumentNullException(nameof(password));
}
if (Sitecore.Security.Authentication.AuthenticationManager.Login(username, password))
{
var user = Sitecore.Security.Authentication.AuthenticationManager.GetActiveUser();
if (user != null && user.IsInRole(role))
{
return true;
}
}
return false;
}
}
}
Now we only need to decorate our classes/actions and take advantage of Basic Auth.
Happy Sitecoring fellas!
Comments
Post a Comment