Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CGuy's avatar
Level 5

Laravel 5.11 Authorization doesn't read Policies

Hi,

I was excited to try out the new authorisation feature in Laravel and it works fine if I define the abilities directly in the AuthServiceProvider. But when I tried to create a policy and register it, it just throws an Unauthorised error without even reading the policy.

Whatever I write in the protected $policies array, it is not taken into account.

<?php

namespace App\Providers;

use App\Article;
use App\Policies\ArticlePolicy;

use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
  /**
  * The policy mappings for the application.
  *
  * @var array
  */
  protected $policies = [
    Article::class => ArticlePolicy::class,
  ];

  /**
  * Register any application authentication / authorization services.
  *
  * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
  * @return void
  */
  public function boot(GateContract $gate)
  {
    parent::registerPolicies($gate);
  }
}

Anybody facing similar problems?

BTW, is there a way to call authorise() in the controller without any arguments like so?

public function update(Request $request)
    {
        $this->authorize();
    
    //...
}

As the method can be resolved automatically, there must be a way to check only for a user attribute without needing an object.

Thanks

0 likes
19 replies
CGuy's avatar
Level 5

@thomaskim

It is a test that I forgot to correct (I did now). It doesn't have any influence on the result. I tried to put typos in the protected $policies too but it just doesn't read it.

1 like
cloud4bpm's avatar

Hi @gchaumont I think the problem is related with this line:

use App\Artic;

Try changing with:

use App\Article;

If you see the code colour is different in the Article::class.

CGuy's avatar
Level 5

@cloud4bpm hi, this was just a test to see if it tries to load the class. I use App\Article now and it doesn't change the behaviour.

thomaskim's avatar

@gchaumont How exactly are you validating it? Are you using form requests? Is it in the controller?

CGuy's avatar
Level 5

It is in the controller

$this->authorize('update')

CGuy's avatar
Level 5

According to the documentation you don't have to pass through an object. You should be able just to give a method.

Anyway, it doesn't even get to the ArticlePolicy.

thomaskim's avatar

Hm...where exactly are you reading that in the documentation? Because I'm not seeing that. Only the user object is optional for certain methods since it assumes that the user is logged in.

CGuy's avatar
Level 5

Even if I pass an object, it doesn't trigger the policy

taijuten's avatar

Having the same issue.

Here's my code (example only):

Controller

use Gate;
use App\Event;
class EventController extends ApiController {

    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function store(Request $request) {
        if(Gate::allows('create-event')) {
            dd('passed');
        }
        dd('failed');
    }
}

Auth Service Provider

<?php

namespace App\Providers;

use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Auth;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];

    /**
     * Register any application authentication / authorization services.
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function boot(GateContract $gate)
    {
        parent::registerPolicies($gate);

        // events
        $gate->define('create-event', function($user) {
            // just return true, to test policy
            return true;
        });
        
    }
}

This always returns failed.

Edit: If it's any help, this is a Laravel installation upgraded to include the Authorization module. I've created the Facade link in the app config, however.

3 likes
CGuy's avatar
Level 5

Haha thanks but I followed the upgrade guide. I just realised that, by passing an object corresponding to the class of the policy, it gets triggered correctly.

Nonetheless, when you need to check if a user is able to create a resource, you don't have an object to pass to the method. So my way around it now is as follows,

public function create()
{
      $this->authorize(new Post);
    //....
}

But I'm convinced there must be a better way to accomplish this...

kadnan's avatar

@gchaumont I did following but can't trigger Policy Class:

use App\Policies\PostPolicy;
use App\Post;
class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        \App\Post::class => PostPolicy::class
    ];

    /**
     * Register any application authentication / authorization services.
     *
     * @param  \Illuminate\Contracts\Auth\Access\Gate  $gate
     * @return void
     */
    public function boot(GateContract $gate)
    {
        parent::registerPolicies($gate);
    }
}
ehtasham's avatar

In 5.1.11 have some updates Try this:

protected $policies = [
        'App\Post' => 'App\Policies\PostPolicy',
    ];  

Instead of:

protected $policies = [
        \App\Post::class => PostPolicy::class
    ];
EHLOVader's avatar
Level 2

@gchaumont there is a better way to do it...

public function create()
{
      $this->authorize('create', Post::class);
    //....
}

Should trigger the policy based on the class name.

1 like
yansern's avatar

What isn't clear in the upgrade guide is that you should add this line under the config\app.php file under the providers array.

App\Providers\AuthServiceProvider::class,
1 like
janokary's avatar

I had the same problem. I realised that I had a typo in the model class where class name began with a small letter instead of a Capital. Capitalising the first letter in the model class solved the problem

Please or to participate in this conversation.