views:

137

answers:

5

I'm building a webapp with role based access control using Acegi (Spring) security. So i have different users with roles: ROLE_ADMIN, ROLE_USER and etc.
However, i need to implement various user constraints.

Let's consider an example:

Suppose, there is a site where users can watch movies online. There are users with roles ROLE_STANDARD_USER and ROLE_VIP_USER. Standard users can watch 3 movies a week and vip users can watch 10 movies a week plus have some other privileges. And there is one user in standard user group to whom i want to give additional 2 movies per week. The number of allowed movies may sometimes change.
Also, there are various categories of movies: fantasy, comedy, classic, new movies and etc. And i want that some users, regardless of their role, have access only to certain categories. The categories can be created and removed dynamicaly.

Are there any standard practices for implementing such type of user constraints?
Can/should it be done using Spring Security roles and permissions?
Or i need to consider adding a rule based engine to my app?

Thank you.

Edit:
The example above is fictional, my project is concerned with granting remote access to various networking (and other) equipment for students. However, the types of user constrains are likely to be the same.
Unfortunately, the Model for user access & constraints is not complete and stable. In the near future i might be told to implement various additional constraints for users, that are not known now.
So i would like to select a path now that will ease addition or change of new user constraints in future and would not require significant overhaul of internal model or database structure. If that at all possible.

Edit 2

Currently, basic user constraints are hardcoded (leftover from prototyping system). I guess i'll try refactoring it first to some kind of parametrized business services objects first and then think where can i go from there. I will also consider using Spring Security Authorization Decision Managers.

Thank you for all suggestions!

A: 

Before asking yourself it Acegi (or a rule-engine etc.) is the correct place to do it, I think you need to
analyze your needs precisely and completely.

Considering each topic (for example, limits on movie that can be seen), there is a huge number of ways to implement this, and you need to make functional choices. There can be no correct implementation unless you already decided in details what has to be done!

Example of a Model for your needs:

  • Limit the number of general movies per week according to the sum of:
    • role (3 or 10)
    • per-user bonus (default 0 if not mentioned)
  • Update these numbers as needed
  • Restrict the movies to a list of categories:
    • if a list is specified for the user, use it
    • otherwise, use the list that is provided for the role

This example has many implications, that may be correct or unacceptable in your case.
Implications:

  • after updating a number, the limit is changed immediately.
  • there is no memory of the weekly limits, you can't ask this for the past (to make statistics for example)
  • ...

Supposing this model doesn't fit your needs, you are facing the hard job of creating a model that really fits them. Only once you have it, then think about implementation.

KLE
+4  A: 

I would not expect a declarative role-based security system to give the fine-grained control you are seeking. You have already described quite a few "business rule" based access controls you want to implement and we might expect over time those rules to become more complex. So you need a combination of information from the security sub system (who is the user for this request? what roles do they have? ) but then programatically combine that with business data and rules (this user is entitiled to 2 free movies if today's date is in this range).

A the very least I would define services in which I encapsulate that business logic. The decision as to whether to use a fully fledged rules engine would need further study.

djna
in other words, you got to start programming it instead of thinking that a magical library and some magic configuration/incantation can get it to work the way you expect =)
Chii
The sad thing is that all too often folks start coding when the magic configuration *will* do the job :-(
djna
A: 

Sounds like you have authentication needs and authorization needs - a lot of times people get the two confused and/or joined. Thankfully Spring Security delineates the two very well. You're user will authenticate through the security chain (be it form logj, openID, SSL X509) and then once done with be authorized by your business specific Voters (in your AccessDecisionManagers) as to wether or not they have already seen their allotted number of movies. If new business logic needs to be added later it's simply a matter of writing new/more voters and injecting them into your Manager.

Gandalf
+1  A: 

If you consider Spring Security, this is one way I see you can implement your solution. Implement a AccessDecisionVoter to decide on user's access. Take a look at the reference source here

Also look at the [javadoc][2] for AccessDecisionVoter. You can implement your rules by implementing the vote method.

int vote(Authentication authentication,
         Object object,
         ConfigAttributeDefinition config)

Let Spring handle the access (Authentication and Authorization). If the decision making gets complicated use a rule engine might be wise. Let the vote method call out to a rule engine. This provide clear separation of duty. Let Spring Security handle the access, and let the rule engine compute the rules.

[2]: http://static.springsource.org/spring-security/site/apidocs/org/springframework/security/vote/AccessDecisionVoter.html#vote%28org.springframework.security.Authentication, java.lang.Object, org.springframework.security.ConfigAttributeDefinition)

lsiu