0

This question is about Claims-Based Authorization and Windows Identity Foundation (unfortunately I lack the priviledge to create a tag for this).

Consider the following simple use case:

  • I have a class User and a class Project,
  • (for the sake of simplicity) each project has exactly one assigned User,
  • The access control policy is that

A user can only read data of projects he is assigned to.


I am trying to model this using WIF and Claims-Based Authorization.

So I have the following method for which I want to check the access:

public Project ReadProject(int id)

To do this, I would have to make a call to the ClaimsAuthorizationManager with an AuthorizationContext containing the principal (=the user) and Claims for resources he wants to access and actions he want to perform on these resources.

What I am not clear on: In the above use case, the permission is based on the fact project.AssignedUserID == user.ID. What would the Claims look like?

  • Is this requirement a Claim on the User/Principal, like "User has access project ID X", that I have to set before calling the ClaimsAuthorizationManager? If yes, at which point would I assign that Claim to the User? And would that not screw up the whole point of having centralized place to declare and check policies?
  • Is it rather something that the ClaimsAuthorizationManager would check by looking up the database? If so, how would I translate the fact which project he wants to access into a Claim?

Most examples I find for CBA are based on attributes about the user (e.g. what country he is from), so I have no idea how to perform checks on the User-Data relation.

2

Well there are a couple options here. The first is to reverse it such that your user has a collection of claims that define which projects they have access to:

Claims:

  • Project: 123
  • Project: 124
  • Project: 125
  • Project: 129

This could be unmanageable depending on how often the projects are created and the number of projects per user as you'd have to refresh the claims any time something changes.

You could do a database check in CAM but that gets noisy quickly, and can potentially slow down the system considerably as the CAM is designed to be called often. If possible it should only make its decisions based on the claims present in the principal.

Alternatively you can pass in a composite resource like "project:{id}:{assignedUserId}" and your CAM could parse it out so if the resource begins with "project" you can parse out the project ID and assigned user ID and do a check to see if the principals claims contains something like 'UserId: 123'. The project Id wouldn't necessarily be needed in this case but if you're sticking logging into the CAM it might be useful to include the project Id too.

  • Not sure I understood the last part. Are you suggesting that I pass the project-user-relation to the CAM as a resource, so it can work with this data? Wouldn't that mean the relying party has to know in advance what policy the CAM is going to check? (In this case: that it will need the assignedUserID of the project.) Wouldn't that defeat the purpose of a centralized CAM? If for example I change the policy to only allow access to the user if the project's name is "Foo", I would have to go back to all calling points and pass along the project name as well. Am I missing something? – magnattic May 8 '14 at 16:01
  • What are you passing into the CAM as a resource then? – Steve May 8 '14 at 16:41
  • The id and the type of the resource, I guess. (e.g. "Project" and "123") However, that actually was my question (what to pass and how to pass it in this scenario?). – magnattic May 8 '14 at 16:57
  • I also see the problems you mentioned that appear when you let the CAM do the heavy lifting and query the necessary information from the DB. But if I am not mistaken, this seems to be the common approach when following ACAB, where the PDP queries a PIP for additional resource information. So I want to know if this is the CBA way to do things as well, or how else I would solve this. – magnattic May 8 '14 at 17:00
  • In that case the first option I mentioned still works, but you will have keep the claims updated, which is a perfectly valid thing to do. – Steve May 8 '14 at 17:01
0

You need attribute-based access control. Claims-based access control is powerful but not flexible enough here in particular because you have to think of all the possible claims up front.

Attribute-based access control (as defined here by NIST) takes on the premise that everything can be described in terms of attributes: users, resources, context, and action.

With that in mind, take your original authorization requirement

A user can only read data of projects he is assigned to.

The next step is to identify attributes:

  • action == read
  • resourceType == data
  • dataProject
  • userAssignedProject

You can then rewrite your authorization requirement in terms of these attributes.

A user can do the action == read on resource of resourceType == data if and only if dataProject is in the list of userAssignedProject.

The next question is: how do you implement this? Use XACML, the eXtensible Access Control Markup Language, the de facto standard for authorization that has been developed for the last 12 years at OASIS.

XACML gives you:

  • an architecture
  • a policy language
  • a request / response scheme.

XACML Architecture courtesy of Axiomatics

With XACML you can fully externalize your authorization such that your code focuses exclusively on business logic and then it calls out to the authorization layer.

One of the key benefits is that if you change your original authorization requirement, then you can easily update your authorization policy and not touch the code at all.

This is what your policy would look like in the ALFA pseudo-code:

/**
 * Control access to data in projects
 */
policy accessData{
    target clause actionId=="read" and resourceType=="data" 
    apply firstApplicable
    /**
     * Allow if same project
     */
    rule sameProjectAccess{
        permit
        condition stringAtLeastOneMemberOf(dataProject, userAssignedProject)
    }
}

This whole space is called Externalized Authorization Management. You can read more on it on Gartner's website.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.