Question

Given the following Controller

namespace MyNamespace.Api.Controllers
{
    [Authorize]
    public class AccountController : ODataController
    {
        private Entities db = new Entities();

        // GET odata/Account
        [Queryable]
        [ClaimsPrincipalPermission(SecurityAction.Demand, Operation = "Read", Resource = "Account")]
        public IQueryable<Account> GetAccount()
        {
            return db.Accounts();
        }

        ...

    }

}

I override the ClaimsAuthorizationManager.CheckAccess(...)

public class AuthorizationManager : ClaimsAuthorizationManager
{
    public override bool CheckAccess(AuthorizationContext context)
    {
        var resource = context.Resource.First().Value;
        var action = context.Action.First().Value;

        return Policies.Validate(resource, action);
    }
}

This is useful only to the point where I can check whether or not the Current Principal in general can Read Account. However, if I'd want to check which accounts a certain user is allowed to Read, I am lost.

Let's say I have a Manager user who should be able to read all Accounts for which he is a manager for whereas a non-manager user should be able to read only their own account.

Is there a best practice for this or have you done something like this previously and give me a few hints to look for?

Was it helpful?

Solution

I do not use ClaimsPrincipalPermissionAttribute because I cannot pass any dynamic parameters to it like requested Account from your sample.

Have a look at the book "Pro APS.NET Web API Security" page 97. They suggest to invoke AuthorizationManager from your controller action implementation by code new IdentityConfiguration().ClaimsAuthorizationManager.CheckAccess(context), where context is constructed manually so you can pass Account requested (for example) as Resource to check it in your AuthorizationManager implementation.

Also have a look at pluralsight training "Introduction to Identity and Access Control in .NET 4.5". There are also some info about how to implement claim-based security in Web API.

Now I am in progress of implementing the security you are talking about and I am interesting in the subject too.

My case is: role Administrator is assigned by Country, every Administrator can see entities only related to the countries they have access to.

UPDATE: After several projects I forgot about Claims-based security as this is extremely difficult way to make security checks. Today I use decorator pattern where all the security checks are done. It appears to be very easy to implement security even in OData Controllers like this: public IQueriable MyQuriableEntitySet { get{ return implementationWithoutSecurity.MyQuriableEntitySet.Where(e=>e.Country.Code = currentUser.AssignedTo.CountryCode || currentUser.IsSuperAdmin); } }

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top