ZF-Commons / zfc-rbac

Role-based access control module to provide additional features on top of Zend\Permissions\Rbac
BSD 3-Clause "New" or "Revised" License
181 stars 111 forks source link

Option to disable guards if one granted access #333

Closed Moongazer closed 8 years ago

Moongazer commented 8 years ago

Hi everyone. I would like to have a chain of guards for different tasks, but not all of them should be excecuted. Means, if one Guard granted access already, the following guards do not need to check by their logic. Lets see an example:

In an application I have a standard user auth and RBAC permission system, which is working great with ZFC-RBAC. Now I need to access some resources without a previous user authentication and without a user session, instead I want to use a JWT (JSON Web Token). My idea was to create a JwtGuard which proofes the X-Auth header of the current request and validate the JWT in isGranted(). The JwtGuard has the priority -10, so it will executed before the default RouteGuard (what is working great). Unfortunately the following RouteGuard is executed after it and deny the access, because no user identity with roles/permissions is found. It is possible do disable this check somehow?

Workflow: Order of defined Guards: 1) JwtGuard, 2) RouteGuard Example:

danizord commented 8 years ago

Ok, we can make it the way middlewares works, instead of not running next guards, you can tell next guards that you already authorized the user. In case of successful authorization in JwtGuard, you can add some param to MvcEvent telling that user is already authorized, and your RouteGuard will check this param and return true if already authorized.

In case of failure, it is AbstractGuard::onResult() that makes the request fail if not authorized. Your JwtGuard can override this method and remove this behavior (or better you can use a generic event listener instead of a guard).

What do you think @Moongazer?

Moongazer commented 8 years ago

That sounds like a simple and smart solution, I will try it tomorrow, thank you! I was asking myself anyway if there is maybe a complete different and better solution from the architectural perspective how to implement something like this.

danizord commented 8 years ago

Yeah, there are the PSR-7 middlewares, they allow you to implement it easily with ServerRequest attributes :)

So I'm closing here, let me know if it works for you.