Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to permit backend only to administrators? #442

Open
robsch opened this issue Oct 20, 2021 · 5 comments
Open

How to permit backend only to administrators? #442

robsch opened this issue Oct 20, 2021 · 5 comments

Comments

@robsch
Copy link

robsch commented Oct 20, 2021

Using the yii2-app-advanced application template, I'd like to allow the whole backend only to administrators. I have secured the backend now, so that only the login is possible (no password reset, no registration, ...). For that I'm using the this application configuration (backend/config/main.php), so I don't have to declare the rules in each controller:

    'as globalAccessController' => [
        'class' => AccessControl::class,
        'rules' => [
            // the only callable action for not logged-in users
            [
                'allow' => true,
                'roles' => ['?'],
                'actions' => ['login'],
                'controllers' => ['user/security'],
            ],
            // error page should be possible anyway
            [
                'allow' => true,
                'actions' => ['error'],
                'controllers' => ['site'],
            ],
            // yii debug toolbar should always be accessible (if activated)
            [
                'allow' => true,
                'controllers' => ['debug/*'],
            ],
            // all other actions can only be called by logged-in users
            [
                'allow' => true,
                'roles' => ['@'], // 'roles' => ['administrator'] ???
            ],
        ],
    ],

Changing the last rule to 'roles' => ['administrator'] should do it. However, other users are still able to to log in though, but each page shows a 403 error page.

How can I do it the right way, so that only administrators can log in. Is it necessary to override the default SecurityController? Is there a better approach than the global access control configuration?

@EndErr
Copy link

EndErr commented Oct 21, 2021

What I've done to have the same:

  • Created a Role "WebAdmins" and assign it to users that need to have access to backend
  • in backend/config/main.php i've added the following in 'modules' part
    'controllerMap' => [ 'security' => [ 'class' => \Da\User\Controller\SecurityController::class, 'on ' . \Da\User\Event\FormEvent::EVENT_AFTER_LOGIN => function (\Da\User\Event\FormEvent $event) { $roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId()); foreach($roles as $k => $role){ if($k === "WebAdmins"){ \Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl('')); \Yii::$app->end(); } } \Yii::$app->user->logout(true); \Yii::$app->controller->redirect(Yii::$app->urlManagerFrontend->createUrl('/user/security/login')); \Yii::$app->end(); } ], ],
  • Also here in main.php in 'components' part I've added the following
    'urlManagerFrontend' => [ 'class' => 'yii\web\urlManager', 'baseUrl' => '@web/../', 'enablePrettyUrl' => true, 'showScriptName' => false, ],
    After user logs in the system automatically logs him out and redirects to login page on front side.

Maybe there is a better approach and will be glad to see another solutions.

P.S. the code does not formats well, but you could figure out.

@robsch
Copy link
Author

robsch commented Nov 4, 2021

Thank you @EndErr for that. Seems to work. Just the urlManagerFronend is confusing me a bit, since I don't have a @web. Now I just use the default urlManager, so that the user gets redirected to the login page of the backend.

Little optimization that hopefully is the same as your suggestion:

'controllerMap' => [
    'security' => [
        'class' => SecurityController::class,
        'on ' . FormEvent::EVENT_AFTER_LOGIN => function (FormEvent $event) {
            $roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
            if (array_key_exists(Yii::$app->modules['user']->administratorPermissionName, $roles)) {
                Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl(''));
                Yii::$app->end();
            }
            Yii::$app->user->logout(true);
            Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl('/user/security/login'));
            Yii::$app->end();
        }
    ],
],

btw: In order to format code, using syntax highlighting for php, use this in your postings (first and last line are essential):

```php
'controllerMap' => [
    'security' => [
        'class' => SecurityController::class,
        'on ' . FormEvent::EVENT_AFTER_LOGIN => function (FormEvent $event) {
            $roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
            if (array_key_exists(Yii::$app->modules['user']->administratorPermissionName, $roles)) {
                Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl(''));
                Yii::$app->end();
            }
            Yii::$app->user->logout(true);
            Yii::$app->controller->redirect(Yii::$app->urlManager->createUrl('/user/security/login'));
            Yii::$app->end();
        }
    ],
],
```

@EndErr
Copy link

EndErr commented Feb 26, 2022

for some days after a update $roles = Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId()); returns a empty array

any thoughts?

@maxxer
Copy link
Collaborator

maxxer commented Feb 26, 2022

What update? Is it related to this bug?

@EndErr
Copy link

EndErr commented Feb 26, 2022

not sure, just did a composer update and after that couldn't login to backend
digging found that Yii::$app->user->getId() in above code returns nothing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants