WCF data service permission on individual table columns instead of on whole entities

356 views Asked by At

Note the bounty is asking about the edited portion of this question. First part is describing the problem

I have a table

Customer 
-----
Name
Address
SocialSecurity
Phone
Etc....

I have another table called

Permissions     
-----
IdOfUser

Can_C_Address
Can_R_Address
Can_U_Address
Can_D_Address

Can_C_Phone
Can_R_Phone
Can_U_Phone
Can_D_Phone

Etc...

note CRUD stands for create, read, update and delete

How can I make sure at the server side that a user query the database as:

contex.Customers.ToList();

pretend the user that made that request to the wcf data service had no permission to see the social security. I will like that list to return with null social security numbers. How can I do that?

It is a lot of work to separate each property/tableColumn into a different entity. For example having CustomerPhone, CustomerSocial, etc all as different entities.


---------------------------------------- Edit --------------------------------------

I found a weird solution! I do not know if it is safe though. Here it is:

Lets say I have an entity called Users. Users have a phone number, social security, address etc. My problem was that I wanted to hide the social security when someone queried the database for example. To solve that problem what I did was I CREATED AN OPERATION/METHOD WITH THE SAME NAME AS THE ENTITY In other words I added the method:

[WebGet]
public IEnumerable<Data.Sub.User> Users()
{
    return this.CurrentDataSource.Users.ToList().Select(x => { x.SocialSecurity = ""; return x; });
}

Then on my client side when I did:

var context = new Data.DatabaseReference.MyEntity(); 
context.Users.ToList();  // WHEN I INVOKE THAT METHOD I SEE THAT I NEVER GET SOCIAL SECURITY!

Is it safe to take this approach?

1

There are 1 answers

3
CharlesNRice On BEST ANSWER

You have four options and none of them is going to be fun.

1) If you are using the reflection provider handle the security at the root query. If it needs to be dynamic you will probably end up using ExpressionTrees to do the projection.

2) Create a custom data service provider - http://blogs.msdn.com/b/alexj/archive/2010/01/07/data-service-providers-getting-started.aspx If you are using Entity Framework you will need to also modify the expression tree and remove all their null projections they add when using a custom provider. This isn't for the faint of heart.

3) Intercept the IQueryable and using an ExpressionVisitor remove or replace any properties that shouldn't be projected. For example of how to intercept the query you can see what you need to do wrap IQueryable here http://blogs.msdn.com/b/vitek/archive/2012/01/07/projections-in-custom-providers-simple-solution.aspx. There was a Microsoft blog on how to intercept IQueryable and replace all the constants with properties so EF would send parameters that was good but I can't find it right now.

4) Switch from WCF Data Services over to Web API where you have more control. From this blog is what they are recommending anyways http://blogs.msdn.com/b/odatateam/archive/2014/03/27/future-direction-of-wcf-data-services.aspx

That's if you just want to do it for the read in crud. Besides #2 that doesn't really touch the create, update and delete part of CRUD.