I'm looking at my interface design and I am struggling to decide which is the most "correct" way to implement role-based access control, given a user
and a subject
that the user
would like to access.
As far as I can see I have three core options (with a fourth being a bastardisation of the first three and a fifth being a tweak of the fourth):
- Query the
subject
with a list of permissions that theuser
has -subject.allowAccess(user.getPermissionSet)
- Query the
user
with a list of permissions that thesubject
requires -user.hasPermissionTo(subject.getRequiredPermissions())
- Query a third-party to locate the intersections of permissions -
accessController.doPermissionSetsIntersect(subject.permissionSet, user.getPermissionSet())
- Query either the
subject
/user
, while delegating the "decision" to a third-party class - Have the
user
attempt to access thesubject
and throw an error if access is not permitted
I am leaning toward option four - Have the subject
contain an accessController
field, where calls to subject.userMayAccess(User user)
delegate the operation a la:
class Subject {
public function display(user) {
if(!accessController.doPermissionSetsIntersect(this.permissionSet, user.getPermissionSet())) {
display403(); //Or other.. eg, throw an error..
}
}
}
.. but then this raises further questions:
- should the
accessController
be a field vs a static class..? - Should a
subject
know what permissions are required to be able to view it? - where does the principle of least knowledge come into play here, with respect to calling
subject.display()
? Should callers ofsubject.display()
ever know that access control is in effect? (wheresubject.display()
is a final "template method") - have
subject.display()
manage access control, throwing an exception where the user does not have the required permission?
What would be considered "best practice" in this situation? Where should responsibility for performing the checks actually occur?
As this is somewhat both an academic excercise which will then progress into implementation, references to design patterns would be appreciated.