I have an ASP MVC3 restful service that uses basic authentication. After searching stack overflow, I created the following code.
public class BasicAuthentic
1) Is an ActionFilterAttribute
the best way to do this?
I think so. This approach mirrors the implementation of the built in Authorize
attribute.
2) Is setting filterContext.Result
the correct way to deny access to the controller method?
Yes. Thats whats it there for. (1)
3) Is there anything I'm doing wrong?
HttpUnauthorizedResult()
to send a http
401 error instead of a http 404 error via HttpNotFoundResult()
.Below in my implementation of your code (which I'm sure has its issues too).
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
if (String.IsNullOrEmpty(filterContext.HttpContext.Request.Headers["Authorization"]))
{
filterContext.Result = new HttpUnauthorizedResult();
}
else
{
if (filterContext.HttpContext.Request.Headers["Authorization"].StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
{
string[] credentials = ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(filterContext.HttpContext.Request.Headers["Authorization"].Substring(6))).Split(':');
if (credentials.Length == 2)
{
if (String.IsNullOrEmpty(credentials[0]))
{
filterContext.Result = new HttpUnauthorizedResult();
}
else if (!(credentials[0] == "username" && credentials[1] == "passwords"))
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
else
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
else
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
base.OnActionExecuting(filterContext);
}
catch
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
Notes
References
(1) http://msdn.microsoft.com/en-us/magazine/gg232768.aspx