AccessControl giving Forbidden 403 when using HTTPBearerAuth in Rest API

I am authenticating on my base controller using HTTPBearerAuth


public function behaviors()

{

    $behaviors['authenticator'] = [

        'class' => CompositeAuth::className(),

        'authMethods' => [

            HttpBearerAuth::className(),

        ],

    ];


    return $behaviors;

}

On my UserController extending base controller and using AccessControl to allow guest users to access login.


public function behaviors()

{

    $behaviors = parent::behaviors();


    $behaviors['access'] = [

        'class' => AccessControl::className(),

        'only' => ['login', 'logout', 'signup'],

        'rules' => [

            [

                'actions' => ['login'],

                'allow' => true,

                'roles' => ['?'],

            ],

            [

                'actions' => ['logout'],

                'allow' => true,

                'roles' => ['@'],

            ],

        ],

    ];


    $behaviors['verbs'] = [

        'class' => VerbFilter::className(),

        'actions' => [

            'logout' => ['post'],

        ],

    ];


    return $behaviors;

}

When I try to access login without authentication details, I get


{

  "name": "Unauthorized",

  "message": "You are requesting with an invalid credential.",

  "code": 0,

  "status": 401,

  "type": "yii\web\UnauthorizedHttpException"

}

Unauthorized 401. With authentication details, I get


{

  "name": "Forbidden",

  "message": "You are not allowed to perform this action.",

  "code": 0,

  "status": 403,

  "type": "yii\web\ForbiddenHttpException"

}

Why am I getting this? I also asked the question on StackOverflow.

Instead of use AccessControl, try to use $only and $except properties of CompositeAuth.




    public function behaviors()

    {

        $behaviors = parent::behaviors();


        // all actions with authentication except login

        $behaviors['authenticator']['except'][] = 'login';


        // OR only logout with authentication

        $behaviors['authenticator']['only'][] = 'logout';


        return $behaviors;

    }



I’m not sure but i think that AccessControl is only for session based authentication.

Should I set all actions in child classes on the $behaviors on base controller class? I tried what you recommended from individual classes but it does not work. How should I do it?

Here, i’m doing this way:

Base controller:




<?php


namespace app\controllers;


use yii\rest\Controller;


/**

 * Class RestController

 */

class RestController extends Controller

{

    /**

     * @inheritdoc

     */

    public function behaviors()

    {

        $behaviors = parent::behaviors();

        

        $behaviors['authenticator'] = [

            'class' => \yii\filters\auth\CompositeAuth::className(), 

            'authMethods' => [

                \yii\filters\auth\QueryParamAuth::className(),

                \yii\filters\auth\HttpBearerAuth::className(),

            ], 

            'except' => ['options'] // actionOption() in all child controllers doesn't need authentication

        ];

                

        return $behaviors;

    }

}



Child controller:




<?php


namespace app\controllers;


use Yii;


/**

 * Class UsersController

 */

class UsersController extends RestController

{

    /**

     * @inheritdoc

     */

    public function behaviors()

    {

        $behaviors = parent::behaviors();

        // actionCreate() on this controller doesn't need authentication

        $behaviors['authenticator']['except'][] = 'create';

        return $behaviors;

    }

}



You shouldn’t use CompositeAuth and AccessControl on the same Controller.

It works for me.

Thanks a lot, I will use this for now even though I am having a different problem.

If you use StackOverflow, you can answer my question titled "Yii2 AccessControl giving Forbidden 403 when using HTTPBearerAuth in Rest API" and I will accept it.