Anyone know how this works, I\'m using the .net membership provider
and just want to pull an xml
list. I\'m also using the .net mvc sdk
.
Alright so I figured it out but the solution may be a bit ghetto. I took the AuthorizeAttribute from .net mvc source and recoded the OnAutorization method. This definitely works for me however it just works for Basic authentication and I'm not sure if this is the most secure method to use. However it does solve the problem of web clients being able to access secure .net mvc rest services.
public virtual void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
string auth = filterContext.HttpContext.Request.Headers["authorization"];
if (!String.IsNullOrEmpty(auth))
{
byte[] encodedDataAsBytes = Convert.FromBase64String(auth.Replace("Basic ", ""));
string val = Encoding.ASCII.GetString(encodedDataAsBytes);
string userpass = val;
string user = userpass.Substring(0, userpass.IndexOf(':'));
string pass = userpass.Substring(userpass.IndexOf(':') + 1);
if (!System.Web.Security.Membership.Provider.ValidateUser(user, pass))
{
filterContext.Result = new HttpUnauthorizedResult();
}
}
else
{
if (AuthorizeCore(filterContext.HttpContext))
{
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
else
{
// auth failed, redirect to login page
filterContext.Result = new HttpUnauthorizedResult();
}
}
}
How to use REST with basic authentication is covered in the answers to this stackoverflow question:
Basic Authentication with WCF REST service to something other than windows accounts?
You can use HTTP Digest Access Authentication (some implementation details here and here) which is a lot stronger than basic but it is still a security trade-off. If you need more security putting the service behind SSL (if it is an option) would be enough.
I thought I'd add this here for anyone (like me) who isn't quite able to wrap their head around the answer the author provided here. Here's a blog post I just did describing how to accomplish this with a [CustomBasicAuthorize]
attribute that can be used the same way as the [Authorize]
attribute that comes with MVC: http://cacheandquery.com/blog/2011/03/customizing-asp-net-mvc-basic-authentication/