Mike Taulty's Blog
Bits and Bytes from Microsoft UK
ADO.NET Data Services - More Sketchy Thoughts on Access Control

Blogs

Mike Taulty's Blog

Elsewhere

One of the things that I briefly mentioned in this post was the idea that because Data Services sits atop of WCF you can plug in a ServiceAuthorizationManager which gets a chance to look at every request before it gets dispatched into your data service.

Whilst you can write explicit interceptors that pick up CRUD operations for particular entities, you might want to just have some roles such as createRole, readRole, updateRole, deleteRole and it'd be a bit painful to have to write lots of interceptor methods to enforce this.

That is, it'd be nice if Data Services had a single place where you could inject code to run before (and possibly after) each operation but I don't think it has one in the current CTP.

A ServiceAuthorizationManager implementation might help a little here though. I might do something like this to try and determine who it is that's calling my service and whether I allow them to do it based on a role;

public class AuthManager : ServiceAuthorizationManager
{
  static AuthManager()
  {
    // Probably want these defined externally...
    roleMap = new Dictionary<string, string>();
    roleMap.Add(httpGet, "readRole");
    roleMap.Add(httpPost, "createRole");
    roleMap.Add(httpPut, "updateRole");
    roleMap.Add(httpDelete, "deleteRole");
  }
  protected override bool CheckAccessCore(OperationContext operationContext)
  {
    bool authorised = false;

    WebOperationContext webCtx = WebOperationContext.Current;
    HttpContext ctx = HttpContext.Current;

    if (ctx != null)
    {
      IPrincipal principal = ctx.User;

      string roleName = null;

      if ((principal != null) && roleMap.TryGetValue(
        webCtx.IncomingRequest.Method.ToUpper(), out roleName))
      {
        authorised = principal.IsInRole(roleName);
      }
    }
    return (authorised);
  }
  private static Dictionary<string, string> roleMap;

  // Pretty sure these are defined somewhere else...
  private const string httpPost = "POST";
  private const string httpPut = "PUT";
  private const string httpGet = "GET";
  private const string httpDelete = "DELETE";
}

and then that'd be configured just like it was in the previous post.


Posted Tue, Jan 15 2008 3:29 AM by mtaulty

Comments

Jason Haley wrote Interesting Finds: January 15, 2008
on Tue, Jan 15 2008 7:22 AM
Mike Taulty's Blog wrote Authorising with ADO.NET Data Services
on Tue, Jun 3 2008 1:23 AM
Once we've got a request authenticated the next thing we might want to consider is authorising those...