I'm a newbie with quite a situation here. I must implement an users' rights control which will allow (or not) my users to Insert/Edit/Delete/Print in a web app. So, at every requested page, I must check if the user has the rights corresponding to this page. If he doesn't have the right to print, for instance, I'll not allow the "print" button to appear.
Let me tell you what I'm doing and you tell me how not-elegant that is: My user logs in, and as soon as he does so I'll store A LOT of attributes in the session: user, logged (true/false), CanInsertClient, CanInsertProduct, CanEditClient, CanEditProduct, CanDeleteClient, CanDeleteProduct... and so on. After he's logged and using the system, I'll check at every page if he is indeed logged and I'll check the rights corresponding to this specific page. Since I'll have all the needed info stored on the session, I could easily do the checking in my jsp, hiding buttons as needed (using c:if or c:when).
My questions: - First of all, how far from the correct is it? - It it safe? - Could I do it using the intercepting filter? 'Cause I don't know much about it, but afaik I couldn't use the information on it to hide things without using scriplets. - What's the best or a better way to do it? - Since I'm loading a lot of attributes in the session, could my app run out of memory easier or have any other problem?
First of all, how far from the correct is it? You have the right idea. I recommend creating a permissions object and putting that in the session instead of loose canXXX attributes. This will make it easier to maintain in the long run.
It it safe? Mostly. It's not enough to simply hide the button. What if someone knows the link is "/AddXXX"? The AddXXX action/servlet would also need to check the addXXX attribute is in the session. And if not, send back an error.
Could I do it using the intercepting filter? 'Cause I don't know much about it, but afaik I couldn't use the information on it to hide things without using scriplets. Potentially, but it would be harder. You would have to parse the HTML file and remove some code. I like your approach better.
What's the best or a better way to do it? See my comments interspersed throughout this post.
Since I'm loading a lot of attributes in the session, could my app run out of memory easier or have any other problem? Putting a lot of small attributes in the session isn't a problem. Putting a lot of data is. So you wouldn't want to put a list of 1000 things in the session.
To add some salts to the question, how do you handle the synchronization between the session authorization tokens and the authorization access control list in the data store? Meaning if the administrator updating the user rights concurrently, would you refresh the information stored in the session?
SCJP, SCWCD, SCJWS, IBM 700,IBM 701, IBM 704, IBM 705, CA Clarity Technical<br /> <br /><a href="http://eddyleesinti.blogspot.com" target="_blank" rel="nofollow">http://eddyleesinti.blogspot.com</a>
Joined: Sep 02, 2005
First of all, thank you so much for the answers and your time. Jeanne, I'll do just what you said, create the object and so on. As I'm using struts, I'll also write an action to check the rights and have it in my struts-config forwarding to the requested actions, if the user is logged. Eddy... well, as what I'm building is just a part of a larger system (which was written in another language and already works) I still don't plan to have this module of changing permissions. Anyway, I suppose the best thing would be to restart a session. Or wouldn't it?
Thank you a lot, guys. I feel a lot more confident now.
Joined: Sep 02, 2005
Let me just ask you one more opinion now that I've gone back to the code. It's about setting the object in the session. I have two classes: Module and Right. In module, I have: number, name, status. In Right, I have: right, module, print, edit, insert, delete.
Being that they're not fixed, it could happen that one of this module is created and I'd have to change the code, if the object has them fixed. Would it be better to send both tables' contents to a List and put the 2 Lists in the session, having an action to get the specified module from the list and set it back, isolated, on the session... or would it be better to write an object with fixed rights and have it on the session even if I have to add attributes to it every time something is added?
My usual approach is to have a security class with a static methods like these:
The first one just names a resource. We often bend the resource name into more of an action like "EditFrammistats" or "RetrieveWoozles". The second one lets you specify the action with some enumeration like Create, Retrieve, Update, Delete, Execute, etc. The third gives you an object that holds all the actions so it might have canCreate() or canRetrieve().
Note that this hides the database design and physical implementation. We have often mapped users to roles and roles to resources so you administrators can give a user one role that gives him many resources. The role-to-resource map could hold all those action bits.
Caching is still an issue. It would be nice to cache the user's abilities to avoid database hits, but you have to be sure to update or invalidate the cache entry when an administrator changes a user's roles. That gets tricky (to say the least) in a cluster.
Finally we use these both in the view and in the model. The view hides buttons for things you cannot do but the business logic always has final responsibility for checking that the caller can do what they request.
Any of that help?
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
subject: Best way to implement login + access rights