Patterns / design suggestions for permission handling
We have a rather complicated system of permission handling in our (ASP.NET web) application. Users can have specific permissions on different kinds of objects, some permissions are even packed into groups / roles that are assigned to users. All in all this ends up in a pretty complicated mess where for determining whether a user can do / see something you have to evaluate many different sources of permissions and this is done somehow on-demand and based on specific situations.
My question is (from a high level point of view) wheth开发者_如何学Cer there are some suggestions / common design patterns to deal with permission concept in general and probably also what is your experience with handling them in your architecture.
I've seen several complicated permission scheme. There was always a justification for it, but unfortunately, at a point in time, they all became too complicated to deal with and were reduced to something simpler.
My personal conclusion now is: stick to Role base access control (RBAC) this is the only reasonable one that everybody understands. It's somehow limited, but sufficient for most cases.
Also, use deny by default policy, that is, you grant rights only. Again, I've seen system with the opposite (allow by default) or even configurable default policy (!) and I don't think it reasonable.
Users and Groups with the ability to test bool UserHasPermission( SOME_PERMISSION )
for an atomic permission associated with a Group is the standard approach for authorization, however things are changing to Claims-based:
http://msdn.microsoft.com/en-us/magazine/ee335707.aspx
http://msdn.microsoft.com/en-us/magazine/cc163366.aspx
http://www.infoq.com/news/2009/10/Guide-Claim-Based-Identity
It however, is not ideal for all situations.
For the old model, I find that performance can be gained by using memoization during permissions checks. That way I'm not going to the database n times per session to check access control. Memoization effectively stores in a cache the result of a call with the same parameters, so all calls by a particular user to check XYZ permission would return the same result. Of course, you'd make sure you stored the memoized permissions for the user in the Session so it's per-user. If you load the permissions at login then you don't need to cache them, but in large systems with many permissions sometimes it's best to get them only when needed.
http://www.infoq.com/news/2007/01/CSharp-memory
I have not dealt with this from an application development standpoint, but often when dealing with permissions it is a good practice to set permissions for objects using roles, rather than giving users permission directly to the object. If a user needs access to a particular set of objects, you don't give them access directly, you instead give them a role, which in turn has the needed access. This in a way "reuses" the work that was put into creating the role.
Dealing with this in code however can get complicated, since you need to iterate through each of a user's roles and determine if the role gives the user permission to the object. I don't know any specific suggestions on dealing with that other than the obvious of trying to factor that kind of code into its own framework.
精彩评论