php-casbin/laravel-authz

Middleware usage?

h-guerrero opened this issue · 6 comments

Hi, I can't find how to access the authenticated users when applying Enforcer middleware.

For example I have the following route:

Route::get('/only-admin', function () { return "You are admin"; })->middleware('enforcer:admin');

When entering I got an 403 which is ok, but whom is enforcer validating? I don't find a way to relate the User model with Enforcer. Probably I am doing it wrong, how can I do this? Thanks!

Hi, @h-guerrero !
Laravel-authz only authorizes, does not perform authentication, authenticates before authorization, and obtains authorized users by Auth :: user () by default.
For authentication, you can refer to the official website document: Authentication

About enforcer middleware:

public function handle($request, Closure $next, ...$args)
{
if (Auth::guest()) {
throw new UnauthorizedException();
// return $next($request);
}
$user = Auth::user();
$identifier = $user->getAuthIdentifier();
if (method_exists($user, 'getAuthzIdentifier')) {
$identifier = $user->getAuthzIdentifier();
}
if (!Enforcer::enforce($identifier, ...$args)) {
throw new UnauthorizedException();
}
return $next($request);
}

Ok, let's say Laravel authentication is active. How Enforcer links an user with the rules table? I can't see any user_id on the table rules.

The User Model obtained through Auth::user() can implement getAuthzIdentifier (), otherwise use getAuthzIdentifier() as the user identifier.

Thanks for the response, as provided in the test folder I just define the method on the model as suggested:

public function getAuthzIdentifier() { return $this->name; }

Yes that's it.

For anyone else interest, I created a basic role middleware so I can also apply validation trough roles and not only by policies. Here is the handler for my AuthorizeMiddleware Middleware:

 public function handle($request, Closure $next, ...$args)
   {
    if (Auth::guest()) {
        throw new UnauthorizedException();
        // return $next($request);
    }

    $user = Auth::user();
    $identifier = $user->getAuthIdentifier();

    if (!Enforcer::hasRoleForUser($identifier, ...$args)) {
        return response()->json('This action is unauthorized', 403); // Ajax usage
    }

    return $next($request);
}

And you can use it as this:

Route::group(['middleware' => ['authorize:admin']], function () {
    Route::get('admin', function () {
        return "HTTP_MIDDLEWARE_PASSED";
    });
});

Once you have defined it on Kernel.php

protected $routeMiddleware = [
    ...
    'enforcer' => EnforcerMiddleware::class,
    'authorize' => AuthorizeMiddleware::class,
];

Happy coding :)