I think the answer to your question goes as deep as you wish to go. If you happen to think about putting roles into groups and then associating groups with users wouldn't be enough. Eventually you'll need to give specific permissions to a user on a specific object (a forum, a video etc).
I'm more close to Yuval's answer, all we need is to associate project-wide objects + actions + users. To provide this; a base object (Entity) makes perfect sense. Any object inheriting from Entity can be easily associated with a user + action this way.
As you also wish to keep things simple; my suggestion would be;
- Any object due to rbac restrictions should derive from a base Entity.
- There should be a list of roles, which are one-to-one related with an Entity.
- There should be a list of relations between users and roles.
To take things one step further, I would also reccomend the following (for an automated rbac)
- I use service-based access to my objects. That is; I create respositories of objects (which do the db-access for me) and I access repositories via service functions.
- I use a custom attribute at the beginning of every service function. This defines the required role to access that function.
- I use the User parameter to access to all my service functions, and each service function does a role check before executing itself. Reflection helps me to understand which function I call, and what kind of role it has (via custom attributes)
- I also run an initializer on my application startup, and it checks for all the functions (and their attributes) and sees if I added a new required role. If there's a role I just added and doesn't appear to be on the db, it creates it on db.
But alas, that's just available for .NET, as far as I know Java doesn't have custom attributes so that's not yet likely to be available for Java.
I'd like to come up with some code examples but I'm too lazy to do that. Still if you have questions about my way of rbac; you can ask here and I'll surely reply.