Thinking about Access Control Lists bound to a web MVC architecture, I have a doubt on where the verification should be done.Within Models? Controllers? FrontController?Imagine a multiple module web application (like a website). I have a public site and a restricted admin zone. All public site pages are acessible by anyone.  The restricted admin area is only accessed by an authenticated user. There are some access levels for the users, such as root, admin and regular user.I gave this some thought during my lunch time today and some ideas came out.First, I needed to ask myself this question:Is access control part of business logic?After some time, I figure out that the answer should be no for most cases. Normally, for the situation I described, the business logic of the public area is about the same of the restricted one. When is not exact the same, what I normally do is to create a superset of both business logic rules, that contains all logic needed. So, even if there are several modules in my application, I normally have only one model layer.Doing the ACL within my controllers leads to code duplication, since I'd have to check it everytime I'd need. Also, I'd get a high coupling between controllers and the ACL component.Thinking about putting it inside FrontController seems to be the right approach. In deed, my initial thought was to put the ACL handler as a dependency for the FrontController.This approach would have controller methods (actions) as resources of the ACL, creating roles for my users.Some pseudo-code (mixing Java, C#, PHP):aclHandler = new DefaultAcl();aclHandler.addRole('none'); // not authenticatedaclHandler.addRole('user');aclHandler.addRole('admin', extend='user');aclHandler.addRole('root', extend='admin');aclHandler.addUser('john', 'root');aclHandler.addUser('mary', 'admin');aclHandler.addUser('jane', 'user');aclHandler.addResource('admin.content.create'); // MODULE.CONTROLLER.ACTIONaclHandler.addResource('admin.content.view');aclHandler.addResource('admin.content.edit');aclHandler.addResource('admin.content.remove');aclHandler.addResource('public.content.view');aclHandler.allow('*', 'public.*');aclHandler.deny('*', 'admin.*'); // deny from allaclHandler.allow('user', 'admin.content.view'); // allow user to view contentaclHandler.allow('admin', 'admin.content.{edit,create}'); // allow admin to edit and create contentaclHandler.allow('root', '*'); // root can do anythingThis way, my FrontController would have something like:class DefaultFrontController implements FrontControllerInterface {    AclInterface acl {get};    User currentUser {get;set};    public DefaultFrontController(AclInterface acl, User user) {        this.acl = acl;        this.currentUser = user;        // ...    }    public void dispatch(ControllerRequest request, ControllerResponse response) {        try {            this.acl.checkPrivileges(request.resource, this.currentUser);        } catch (AclException e) {            this.forbiddenAccessCallback(request, response, this.acl, this.currentUser);            return;        }        // continue impl...    }}fc = new FrontController(aclHandler, new User(name='John', role='root'));fc.dispatch(...);  // ...This implementation makes an ACL component a mandatory parameter for the FrontController constructor, so, now it's part of its state. This could be a problem when I don't need an ACL, but can be overpassed by creating a mock implementation of ACL component, like AllowFromAllAcl, that would allow any users to do anything.Any ideas? Corrections? Suggestions?
Where should the ACL handler be called in a MVC architecture?
design patterns;object oriented;object oriented design
Access control is part of business logic. If you look at use cases, or even user stories, you will see that there are actors involved in any business process. The access control lists are a method to ensure that all and only the actors CAN be involved with the business process.Access control needs to be supported in the model, the view and the controller.Access control is part of the model: By limiting the ability to change or view columns or records per the business logic, you necessarily prevent many failures. If only system administrators can change a secondary key field, then it won't be accidentally changed because someone implemented a form incorrectly. Now, I also suggest that you don't specify the restriction as based on system_administrator privilege but rather change_secondary_key privilege, which system_adminstrators have by design. This separates role from function.Access control is part of the view. By not enabling form fields to edit data for which the person doesn't have the privileges, you prevent both confusion and errors.Access control is part of the controller. The controller adjusts the page flow to present only the information appropriate to the user at a time and place that is appropriate.Certainly, you want to have central management of access controls, on the principle of DNRY (Don't Needlessly Repeat Yourself). Access control is a cross-cutting concern.