Hello,
We need to implement business methods that return different (filtered) data based on a user's security roles. For example, a "manager" calls a business method that returns a List of Employees. An Employee object might contain a "salary" property, but in this case a "manager" should not be allowed to see the salary. However, when the "cfo" calls the same business method, he should be able to see the salary. It is important that the business logic itself filter this value out (instead of just hiding the value at the application level), because we will be eventually exposing the business logic as a service for other, possibly untrusted, clients to access. We have settled on Hibernate... but how should we go about this one?
Here is what we are currently thinking.
First, our architecture is pretty typical: stateless session bean provides a facade to a business POJO which uses a DAO, implemented with Hibernate, to do Create, Read, Update, and Delete operations. The persistent objects returned from Hibernate are the value objects (which means they are passed, as is, back to the client).
Our current thinking is to create some system wide object that represents a "secured" field:
public class SecuredField implements Serializable { }
We would have to store all our fields as Objects internally, doing appropriate typecasting in the "getter". We would also have to modify our "getters" to throw an exception (SecuredFieldException) if the field is secured. Then we perform this algorithm for any persistent object that leaves a business method: for each field in the persistent object, if the current user does not have access to the field, then replace the field's value with an instance of SecuredField. This way, no sensitive information leaves the method in any way. The client will just have to be aware of and handle any SecuredFieldException. Additionally, this approach would allow us to define field level security "declaratively" (we could store information in the XML or in the DB as to what fields require what roles).
This part is doable (though maybe someone has a better idea on this aspect). The hard part is when the client modifies a persistent object and sends it back to a business method to be updated. Going back to our example, the "salary" property has now been modified: it no longer contains the employee's salary. It now contains an instance of SecuredField. Moreover, if Hibernate attempts to call the getter, Hibernate will be handed an exception. What would be really nice is if we could just dynamically tell Hibernate not to persist those (secured) fields. Another option, though ineffecient, would be to reload the persistent object from the DB, merge it with the client's changes, and then update the DB. We simply don't have enough experience with Hibernate to know how doable either of these options are.
Any ideas, critque, or help would be greatly appreciated.
|