I think this is a veryinteresting topic and one where I'm sure there are as many opinions as there are folks who monitor this forum. But it is something I've been thinking about for a while now so this is as good as anytime to comment.
Firstly, code doesn't live in it's own world. An application has to be managed for years and years after it is written, and probably long after the developer is long gone. Every developer should put themselves in the shoes of the administrator who's going to have to maintain or operate what the developercreates.
To get to the heart of the matter, I don't think that it is reasonable to have the STS generate permission claims. This belief mainly stems from the fact that in many cases the approach simply won't scale.
In the referenced article there is the following code:
if (Roles.IsUserInRole(identity.Name, "Guests")) { listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read, ClaimsAuthorizationPolicy.Resources.Customers, Rights.PossessProperty)); listClaims.Add(new Claim(ClaimsAuthorizationPolicy.ClaimTypes.Read, ClaimsAuthorizationPolicy.Resources.Orders, Rights.PossessProperty)); } etc...
With all apologies to the author of the article, I can't really think of anything that it would be worse than this approach from an enterprise architecture point of view.
Now it does appear that this app was not written with Geneva in mind as the claims issuance source. In the Geneva scenario, there is an STS (or series of STS's) which are creating claims and delivering them to the application. This article describes an approach where the app is building it's own claim set based on roles which are derived directly from identity. But the approach can be mapped to Geneva if you imagine that this code (or the equivalent) lives in the STS instead of in the app and that the permission claims are sent by the STS to the app.
So what are the specific problems with this approach?
Consider:
1) Any change to policy requires a change to code 2) There is no administrative way to view/audit the policy - you have to crack open the code 3) What this policy would look like if there were 500 roles and 50,000 resources. How would you maintain it? 4)The performance overhead of generating a claim for every possible permissionwith large numbers of roles and/or resources
Any of these, IMO, make this idea a non-starter for Enterprise Application scenarios.
Fine-grained authorization decisions involve an Actor (or properties of the actor), a Resource, and an Action. The STS in the Geneva implementation only really knows about the Actor. It does know about the application, but an application is not the same thing as a resource. In this way, the STS is much like authenticating systems that have come before it, e.g.the Kerberos KDC. Like the KDC, it is reasonable for the STS to generate broadly applicable claims about the user (or principal) but fine-grained authorization decisions will require a fine-grained authorization policy. The STS, therefore, is an inappropriate place to generate authorization decisions.
It seems that the best approach to this problem will be to take advantage of the STS and the claims paradigm to be able to generate better and more relevant information about the actor during authentication, but employ some other mechanism to resolve authorization. Generically, you need an interface:
bool AccessCheck(Claims, Resource, Action)
For manageability, this interface needs to make it's decisions based on information that can be changed without changing code. In other words there needs to be a friendly UI on top the mappings that lead to the boolean authorization decision.
Just my 2 cents. I'm sure others will have a different opinion.
|