views:

1192

answers:

3

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. So here's the problem when I add the [WebApiEnabled] at the top of my controller I can successfully pull xml/json. But when I add [Authenticate] to the top of my controller I cannot login. As an example curl -i -u "admin:pass" -H "Accept: application/xml" http://localhost%3Axxxx/Book

Thanks in advance for your help

A: 

How to use REST with basic authentication is covered in the answers to this stackoverflow question:

http://stackoverflow.com/questions/660445/basic-authentication-with-wcf-rest-service-to-something-other-than-windows-accoun

Shiraz Bhaiji
+3  A: 

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();
            }
        }


    }
Jody Brewster
A: 

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.

Maxwell Troy Milton King