I have a controller which has different access requirements per action, i.e. some actions can be called as a guest user and some actions need a logged in user. Until now, I’ve implemented a custom AuthMethod:
class CustomAuth extends AuthMethod {
public function authenticate($user, $request, $response) {
$authKey = $request->getHeaders()->get('AuthKey');
if (isset($authKey)) {
return $user->loginByAccessToken($authKey); // Returns null only for invalid authKey
} else {
return $user->logout(); // Returns non-null = guest user
}
}
}
Is this the right way to support logged in users and guests? I cannot return "null" for guest users in authenticate, because this would prevent the action to be executed, so I have to make the authentication "optional".
Take a look at the authorization documentation. I think the documentation is still under development, but there is enough there that explains what you are trying to do.
Specifically you will want to use behaviors to define rules for the actions that can be accessed by guests and actions that can be accessed by authenticated users.
If I understand the documentation correctly, the authentication is performed BEFORE any actions are executed, so access rules (or RBAC) are evaluated AFTER the authentication takes place. If that is correct, the authentication step does not depend on any action rules.
public function behaviors() {
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CustomAuth::className(),
];
return $behaviors;
}
I am not sure if I follow your comment, but it sounds like you said the authentication is independent of actions. I believe you can do things so that you authenticate generally for all actions, but you can certainly authenticate on specific actions. The code below is taken from the documentation link, and it shows an example of limiting the actionLogout to authenticated users, and the login, signup to guests. So basically a logged in user can access all 3 actions, but if a guest (not logged in) tried to access the logout action, they would get a #403 (Forbidden) error.
I think you misunderstand me. I know how to perform authorization based on action rules/RBAC, I’m interested in authentication before authorization starts. The authorization step operates on already setup user data, while the authentication step setups the user data. And this is where I’m asking whether my posted solution is the right choice, because I need optional authentication. Imaging the following steps for guests:
[list=1]
[*]Guest sends request without any authentication information
[*]User object is set to "guest"
[*]Authorization rules now operate on a guest user
[/list]
And now for users:
[list=1]
[*]User sends request with authentication information
[*]User object is set to logged in user
[*]Authorization rules now operate on logged in user
[/list]
My question is, whether my implementation of the AuthMethod is the right one when supporting optional authentication?