Yii2: AccessControl and CompositeAuth

Created on 2 Aug 2014  路  14Comments  路  Source: yiisoft/yii2

Hi,

How can use CompositeAuth with AccessControl?
I want create Rest app, and set access rules for actions.

Example:
/api/users.get?id=112233 - allow for all
/api/users.set?access-token=[TOKEN]&status=online - allow for only auth users, and auth only access-token.

Thanks!

Most helpful comment

@cebe Yes, Authentication and Authorization are two different things. But, from my experience, 2 configs often lead to errors that are hard to debug, plus, if Authorization (AccessControl) can take care of giving or not giving permission to execute an action, I really don't care what happened in Authentication (CompositeAuth). Plus it is a good practice to separate responsibilities. Authenticator only logs in the user (if possible), and Authorization takes care of all the access permissions.

All 14 comments

Please read the guide about how to use filters (and how to apply them to specific actions only) in general: https://github.com/yiisoft/yii2/blob/master/docs/guide/structure-filters.md#using-filters-

You should list the auth filter before the access control filter.

Closed as this is not a bug report.

This is don't work.

If use:

 public function behaviors()
    {
        $behaviors =  parent::behaviors();

       $behaviors['authenticator'] = [
            'class' => CompositeAuth::className(),
            'authMethods' => [
                QueryParamAuth::className(),
            ],
        ];

        $behaviors['access'] = [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => ['signup','get'],    // allow all
                        'roles' => ['?'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['set'],          // only auth users by access-token
                        'roles' => ['@'],
                    ],
                ],
        ];
        return $behaviors;
    }

All actions return response:

<response>
   <type>yii\web\UnauthorizedHttpException</type>
   <name>Unauthorized</name>
   <message>You are requesting with an invalid access token.</message>
   <code>0</code>
   <status>401</status>
</response>

if use:

 public function behaviors()
    {
        $behaviors =  parent::behaviors();
        $behaviors['access'] = [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'actions' => ['signup','get'],    // allow all
                        'roles' => ['?'],
                    ],
                    [
                        'allow' => true,
                        'actions' => ['set'],          // only auth users by access-token
                        'roles' => ['@'],
                    ],
                ],
        ];

       $behaviors['authenticator'] = [
            'class' => CompositeAuth::className(),
            'authMethods' => [
                QueryParamAuth::className(),
            ],
        ];

        return $behaviors;
    }

actions "get" and "signup" return response:

<response>
   <type>yii\web\UnauthorizedHttpException</type>
   <name>Unauthorized</name>
   <message>You are requesting with an invalid access token.</message>
   <code>0</code>
   <status>401</status>
</response>

action "set" return redirect on page login(call denyAccess);

Thank You!

Did you read the tutorial? You didn't set the only or except option to limit the auth filter to certain actions.

Sorry
I understand English a little.
Yes, i read tutorial and can not understand how work behaviors.

my behavior

$behaviors['authenticator']

works on all actions :( and ignores rules AccessControl
How enable Auth only some actions?
Could you show an example?

Thank You

Yes!! Than You!
I think I got it!

$behaviors['authenticator'] = [
            'class' => CompositeAuth::className(),
            'except' => ['signup','get'],  // set actions for disable access!
            'authMethods' => [
                QueryParamAuth::className(),
            ],
        ];

It works! Thank You!

@qiangxue Can you tell me whether the following approach is acceptable or not:

Custom CompositeAuth class suppresses authentication errors, so that all the checks happen in AccessControl and the 403 Forbidden will be thrown from there.

Custom CompositeAuth class:

namespace some\namespace;
class CompositeAuth extends \yii\filters\auth\CompositeAuth
{

    public function beforeAction($action){
        parent::beforeAction($action);
        return true; // always return true even if identity was not found
    }

    // probably challenge method should be stubbed as well

    public function handleFailure($response)
    {
        // do nothing
    }

}

I find this a bit hacky, but still better than to specify auth-free actions in two places: in except option of authenticator and then in access control.

Unfortunately, the exception is 403 Forbidden but not 401 Unauthorized in this case, but I don't think it is a big deal.

@kirill-konshin what is the problem you are trying to solve? may be better to open a new issue and describe your problem in more detail. Solution does not look right to me but you have not given much info.

@cebe The problem was that CompositeAuth filter was interfering with AccessControl filter and if there were no access tokens supplied to CompositeAuth, then AccessControl becomes useless since CompositeAuth throws an exception.

In this issues there was a proposal to set up except option for authenticator, so that it does not run for auth-free actions. My proposal is to omit any errors in authenticator and let access control to do what it has to. So my question is whether this approach is legit?

yeah, if you do not need to authenticate a user in a specific action you can skip the authenticator using except.

@cebe True. But in this case I'll have to specify auth-free actions twice:

  1. In except for authenticator
  2. In rules->actions of AccessControl

Bypassing authenticator errors allows to specify all AccessControl rules in one filter.

Authentication and Authorization are two different things so I think it is okay if both have their own configuration...

@cebe Yes, Authentication and Authorization are two different things. But, from my experience, 2 configs often lead to errors that are hard to debug, plus, if Authorization (AccessControl) can take care of giving or not giving permission to execute an action, I really don't care what happened in Authentication (CompositeAuth). Plus it is a good practice to separate responsibilities. Authenticator only logs in the user (if possible), and Authorization takes care of all the access permissions.

I was looking at this and use it the way described but would like it if in the ActionFilter where the except and only option check for unique ID insted of id as it will give me more control.

@kirill-konshin I think the 'optional' parameter will solve the issue you mentioned.
http://www.yiiframework.com/doc-2.0/yii-filters-auth-authmethod.html#$optional-detail

Was this page helpful?
0 / 5 - 0 ratings