开发者

best practice for permission implementation in a system?

I have an application which contains different kinds of permissions. As mentioned in (开发者_如何学运维Role Bases Security) RBC ,I grouped users into roles and assigning different permissions to roles. (and permissions are in this style :

public enum Permission {
     View = 1,
     Create =2,
     Edit =4,
     Delete =8,
     Print = 16
}

everything is ok in simple systems but when the system becomes a little complex , specific permissions come to the system such as :

  • View Just His Issued Invoices
  • View All Invoices
  • Edit Just His Issued Invoices
  • Edit All Invoices
  • Create Sale Invoice
  • Create Purchase Invoice
  • Create Proforma
  • Create Sale Report On His Own Invoices
  • Create Daily Sale Report
  • Create Monthly Sale Report -....

As you see different kind of permissions arises in system (it can grows to about 200 different permissions). So the problems are :

  • I cannot put them all in one enum . then using binary pattern (1,2,4,8,..) cannot be used because in its best case(int64) it supports up to 64 different permissions.
  • a big enum (with about 200 items) is not so good in coding

what are your ideas in this case?

thanks in advance :-)


I'm not sure why you feel that you need to try to shove all the permissions into a single flags (or so I'm inferring from the vales) enum. Permission requests and grants can be represented using lists as opposed to a single ORed value. If you use a list approach, you become free to create whatever permission representation you like. For example, you could use a non-flags enum or even multiple enums to represent your permissions.


It sounds like you need a level of indirection...

For example, you need a category (represented by an object, say) that represents "His Issued Invoices". You need a way to grant a role any of your basic permissions on that object. You need a way to test whether something is a member of that category.

Suppose "Jane" tries to view an invoice. Then you just need to check: Does Jane have a role which has View access to some category of which this invoice is a member?

This check might be slow, since you have to check all of Jane's roles against all of the invoice's categories. But presumably you can cache the result... Or your can use a "capability based" approach, where Jane asks the security manager for a handle (pointer) to the invoice with View access. The security manager does the check and hands Jane the handle, after which she can use that handle to do whatever Viewing operations the handle supports with no additional security checks.


I agree with Nicole it does seem like you are performing what may have seemed like a good optimization but you are encountering issues with scale.

Many RBC systems deal with a large number of permissions, which is one reason roles exist - regular users need only know what role they are in - leave it to the developers to figure the role-permission mapping out. Larger systems might provide a GUI for superusers to do the role-permission mapping, or even create permissions, but only to provide the power user ultimate flexibility.

However, because of J2EE, at the code level it all boils down to checking 'roles' programmatically. That tends to confuse things when what you actually want to test for is the permission to perform an operation. Just keep that semantic gap in mind.

In terms of optimization, consider not the method of assignment of permissions, but when and how you perform the check. In a web application, you may only need to check when the call from the front-end comes in, and perhaps network latency will dwarf any optimizations you perform here.

If you decide you do still want to optimize, you'll probably find simply caching the permissions at login is enough. The actual search for a permission will be all in memory, so will be tiny after the initial load from the database.

To avoid the combinatorial explosion of permissions, establish some strong logic up front - write it down - and make sure you're covering all your bases. If you see the need for new dynamic permissions to be created, such as when new entities are added in to your system, then watch out - this is better done in a mediator or manager pattern that can check your business rules before handing out the protected entity. Here you are stepping into the realm of libraries like Drools which serve to expose business logic from your application so that it can be updated based on changing business requirements.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜