I have 2 applications: frontend and backend.
Users on frontend have role "client".
How do I disable access to the application backend users with "client" role. All other roles are allowed access. site/login on backend allow for all users.
I wrote the following code in my main.phpfile:
'as beforeRequest' => [
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'allow' => true,
'controllers' => ['site'],
'actions' => ['login'],
'roles' => ['?'],
],
[
'allow' => false,
'roles' => ['client'],
],
],
'denyCallback' => function () {
return Yii::$app->response->redirect(['site/login']);
},
],
I have error: ERR_TOO_MANY_REDIRECTS in chrome.
From the guide 'roles' => ['?']:
matches a guest user (not authenticated yet)
Since the user is logged in they are stuck in a redirect loop caused by the second rule and the denyCallback i.e.
User is logged in but is of role client and is therefore not allowed.
Since user has been denied access, redirect to site/login.
See 1.
This can be fixed by omitting the roles element in your first rule:
If [role] is not set or empty, it means this rule applies to all roles.
HOWEVER THIS IS THE WRONG APPROACH
Users who are logged in but are of role client should be denied access to the backend. Sending them to login will not help since they are already logged in. The proper course of action is to send them to the frontend's error page.
Related
I’m having a problem, when I logout from either frontend or backend, the other one remains log in. I have been searching online for the solutions but did not find anything like this. What should I change so that when I logout from frontend or backend, the other one must logout.
Log in is working fine for both:
public function actionLogout()
{
Yii::$app->user->logout();
return $this->goHome();
}
Please update your frontend and backend main.php as below
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-auth', 'httpOnly' => true],
],
'session' => [
// this is the name of the session cookie used for login on the frontend
'name' => 'AuthSession',
],
once the identityCookie and sessions are identical, then you can manage your session from both frontend and backend.
I'm facing a problem where I've configured RBAC in Yii 2.0 but it does not work - meaning it dooes not prevent any of the pages from being loaded - even as guest.
This is in my web.php config (also in my console.php):
'authManager' => [
'class' => 'yii\rbac\DbManager',
],
The migrations have completed successfully.
This is how behaviors() look like at the moment, but I tried many different ways.
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['error'],
'allow' => true,
//'roles' => ["?"],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
If I implement the behaviors() function in my controller, the framework starts doing some access-handling, but the goal of using a DB as I understand should be that the RBAC system takes over this responsibility - meaning I don't have to enable/disable every single action I write for every single role.
I have added a Role "Admin" and assigned a few of the available routes (actions) to it.
Then I assigned this role to my User name. In theory this should enable my login to access those specific routes but nothing else - instead, I can traverse the site however I please, no 403s whatsoever. (This is why I'm saying RBAC acts like it's non-existing.)
Any hints or tips are appreciated.
Thanks.
where is your authManager configuration located?
According to [yii2 guide]
If you are using yii2-basic-app template, there is a config/console.php configuration file where the authManager needs to be declared additionally to config/web.php. In case of yii2-advanced-app the authManager should be declared only once in common/config/main.php.
Update to this question, I just tried do rbac manually
My result
We must do conditional in every action like
...
public function actionAbout()
{
if (Yii::$app->user->can('ViewAbout')) {
echo "you may see view about";
} else {
echo "view about is prohibited";
}
// return $this->render('about');
}
...
If you want assign it in common way, you better use extension/module that handle authmanager (like yii2-admin, yii2-mimin, etc)
Hope this answer help
I have used this tutorial to create a login screen for my application. But I want to protect with the same login form another inner page. So a user can login and use the application but if he/she wishes to open a specific page in the application he/she has to reenter the password for security reasons. How I can achieve that?
This is my initialize function in AppController.php:
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
]
]);
You could always use the AuthComponent::identify() method to check a login form even in a already authenticated enviroment. See Identifying Users and Logging Them In in the CakePHP docs and AuthComponent::identify in the API docs.
Step-by-step:
Create controller action and template for password recheck and include form for a User entity with controls for email and password.
Prefill email field if you like, a hidden field is also possible.
Add a $this->request->is('post') block, just the way you would do in the standard login and check for valid crendential within using $user = $this->Auth->identify();.
If a valid user is returned store some flag or timestamp for timeout in your Session and then redirect to protected pages.
On any protected controller check for existence of the flag or valid timestamp in the Controller::beforeFilter callback method and throw UnauthorizedException or ForbiddenException if not.
We are working on a project where are 4 roles. But in cakephp 3.x Auth component holds authenticate user data in session with Auth.User indexing using
$this->Auth->setUser($user);
Due to this we are not able to access front-end user account from admin panel for some purpose, because of when we login to front-end user from admin panel, front-end login action performs and over write of session value.
So if there is any process to handle this please suggest us.
Thank you in advance.
As well I have understood that you are not using prefix to manage back-end and front-end user then may be you worked with separate folder structure for back-end, May I right?
You are right that $this->Auth->setUser($user); always holds session with Auth.User indexing. So you need to write different session indexing for back-end, and you can do it as follow :
For back-end user authentication :
**
$this->loadComponent('Auth', [
'authorize' => ['Controller'], // Added this line
'loginRedirect' => [
'controller' => 'Users',
'action' => 'dashboard',
'prefix' => 'admin_panel'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login',
'prefix' => 'admin_panel'
],
'storage' => [
'className' => 'Session',
'key' => 'Auth.Admin',
]
]);
**
Here you can pass your desired index in 'storage' array key value.
I think it'll works for you.
Check out the section Authentication and Authorization in this curated list of CakePHP Plugins.
You could, for example, use dereuromarks TinyAuth Plugin to authorize your users and configure what they are able to see.
This way you can use the same authentication (be aware of the differences between Authentication and Authorization) and the same users table, which will prevent the Session conflict you mentioned.
The Auth component overwrite the previous session because it store the session in Auth.users all the time so we have to change the session key for different role.
If you are using URL prefix for the different roles to access then you can do like this.
AppController.php
public function beforeFilter(Event $event)
{
if($this->request->params['prefix']){
$this->Auth->config('storage', [
'key'=>'Auth.'.$this->request->params['prefix'],
'className'=>'Session'
]);
}
return parent::beforeFilter($event); // TODO: Change the autogenerated stub
}
This will create different roles in Auth as you required.
The session will be like this
[
'Auth'=>[
'User'=>['id'=>''],
'Admin'=>['id'=>''],
]
]
Tested it, working great for me.
I worked with RBAC in my project which worked fine in overall my project wherever I checked if particular user can perform specified action.
But the actions that I didnt went thorugh RBAC in site controller are not being rendered from any users.
My code that I used to access to the function in site controller:
My function that needs to be accessed in site controller.
Add additional access rule to your behavior in SiteController:
[
'allow' => true,
'actions' => [
'hofview'
],
'roles' => ['?'], // it means user not logged in can access this action
],