Yii2 restricting access to RBAC Module itself - yii2

How I can restrict access to RBAC Module itself?
I'm using yii\rbac\DbManager and I have created a module(Authorization) in backend for permission assignment,create auth items, now I want to make sure only admin can access this module!
In controller I have used something this and it's working fine.
use yii\filters\AccessControl;
class MyController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['index', 'view', 'create', 'update', 'delete'], //only be applied to
'rules' => [
[
'allow' => true,
'actions' => ['index', 'view', 'create', 'update','delete'],
'roles' => ['admin'],
],
],
],
.........
I have put this in Authorization.php init function but nothing happen, all auth controllers are accessable.
public function init()
{
if(\Yii::$app->user->can('admin'))
parent::init();
// custom initialization code goes here
}
Update
backend/config/main.php
'modules' => [
'authorization' => [
'class' => 'backend\modules\authorization\Authorization',
],
],

In your module class you can add this method
public function beforeAction($action)
{
if (!parent::beforeAction($action)) {
return false;
}
if (!\Yii::$app->user->can('admin')) {
throw new \yii\web\ForbiddenHttpException('You are not allowed to access this page.');
}
return true;
}

Related

Logout automatically use after session expire in yii2

How and where can i write code to redirect to login page after the session expires in Yii2.0 ?
// if (!Yii::$app->controller->id == 'site') {
// $session = Yii::$app->session;
// if (!$session->isActive) {
// $model = new LoginForm();
// return $this->goHome();
// }
// }
i tried to do this in the base controller.
you never know when user session is expire , but you can force users to login before using some actions :
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['youraction'],
'allow' => true,
'roles' => ['#'], // you can use matchCallback to create more powerful check
],
],
],
];
}
dont forget to add use yii\filters\AccessControl;

Yii2 all controllers and actions require login, need to add some exceptions. How can I do it?

I've found a lot of answers on how to create Access Control that requires login to all controllers and actions.
The following post shows how I did all controllers require login:
Yii2 require all Controller and Action to login
I've used the code below under my components:
'as beforeRequest' => [
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'allow' => true,
'actions' => ['login', 'error'],
],
[
'allow' => true,
'roles' => ['#'],
],
]
],
But, I want to add some exceptions to it. Some controllers need to have some actions visible to Guest.
I've tried to use this code inside my behaviors on ReportsController:
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['share'],
'roles' => ['?'],
],
],
]
Still get redirected to login.
I'm trying to to make actionShare($param) {} public to guests.
What am I missing?
Thanks for all your help!
First execute
yii migrate --migrationPath=#yii/rbac/migrations
from command prompt to create RBAC table in data base.
Then create RbacController in component folder
namespace app\components;
use yii;
use yii\web\Controller;
use yii\filters\AccessControl;
class RbacController extends Controller
{
public function RbacRule($modules = false)
{
$rules = false;
if ($modules){
$rules = [
'allow' => true,
'roles' => ['#'],
'matchCallback' => function ($rule, $action) {
$module = Yii::$app->controller->module->id;
$action = Yii::$app->controller->action->id;
$controller = Yii::$app->controller->id;
$route = "/$module/$controller/$action";
$post = Yii::$app->request->post();
if (\Yii::$app->user->can($route)) {
return true;
}
}
];
}else{
$rules = [
'allow' => true,
'roles' => ['#'],
'matchCallback' => function ($rule, $action) {
//$module = Yii::$app->controller->module->id;
$action = Yii::$app->controller->action->id;
$controller = Yii::$app->controller->id;
$route = "/$controller/$action";
$post = Yii::$app->request->post();
if (\Yii::$app->user->can($route)) {
return true;
}
}
];
}
return $rules;
// return true;
}
}
then extend to your controller using this RbacController instead of controller.
use app\components\RbacController;
class AdminController extends RbacController
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
// [
// 'actions' => ['login', 'logout'],
// 'allow' => true,
// 'roles' => ['?'],
// ],
parent::RbacRule(),
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
'bulk-delete' => ['post'],
],
],
];
}
.......
}
If your controller is inside Modules folder then you have to use
parent::RbacRule(TRUE) instead of parent::RbacRule(),

AccessControl : Require login to open a controller in yii2 :

I am working with a lot of module in yii2 like this.
yii_basic
-- modules
-- admin
-- it
-- members
I have a scenario which is the user (members) need an approval sign via email that sending by app.
For example, this is the link : dzil.local/it/request/update?id=940 , which is this link is actually an update controller with ID.
I need user to force login when it's accessed.
But My problem is, after login is success, it 's not redirect to the controller that I mean: dzil.local/it/request/update?id=940 but to actionIndex of module.
This is the class RequestController :
class RequestController extends Controller {
public function behaviors() {
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
'bulk-delete' => ['post'],
],
],
'access' => [
'class' => \yii\filters\AccessControl::className(),
'rules' => [
[
'actions' => ['create', 'update', 'delete', 'get-item-detail', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'], // add all actions to take guest to login page
'allow' => true,
'roles' => ['#'],
],
],
],
];
}
I think the failed it comes from this :
public function actionLogin()
{
if (!Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
if (Yii::$app->user->can('Administrator')) {
return $this->redirect(['/admin']);
} else if (Yii::$app->user->can('IT')) { // the user is on IT
return $this->redirect(['/it']);
} else { //defaultnya user common
return $this->redirect(['/members']); // the user is member
}
}
return $this->render('login', [
'model' => $model,
]);
}
Please advise me to get a best practice.
If you need a go back routing after login you should add where needed return $this->goBack(); eg:
if ($model->load(Yii::$app->getRequest()->post()) && $model->login()) {
return $this->goBack();
}

Yii2 enablePrettyUrl fail and frontend post request fail

i was trying to make
this url
http://localhost/advanced/frontend/web/index.php?r=test
into
htttp://localhost/advanced/frontend/web/tests in yii2
also to receive post request
this in my codding in common/config/main.php
<?php
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'urlManager' => [
],
'urlManagerFrontEnd' => [
'enablePrettyUrl' => true,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['test'],
'only' => ['index', 'create'],
],
],
'showScriptName' => false,
],
],
];
this in my frontend testController
namespace frontend\controllers;
use Yii;
use yii\rest\ActiveController;
use common\models\Test;
use yii\data\ActiveDataProvider;
class TestController extends ActiveController {
public $modelClass = 'common\models\Test';
public function actions(){
$actions = parent::actions();
unset($actions['create']);
return $actions;
}
public function actionCreate(){
$model = new Test();
$model->load(Yii::$app->request->post(),'');
$model->save();
return $model;
}
}
i have a problem in the post request when i tried
Postman result jpg
so i have 2 problem the first is the prettyUrl and the post request
if u have a solution please make it easy because i just learn php yii2 html css etc for 1 month

Redirecting unauthorized users to another controller action

I have this controller code for login:
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->redirect(Yii::$app->request->baseUrl.'/telephone/index');
}
$model = new LoginForm();
if ($model->load(Yii::$app->request->post()) && $model->login()) {
return $this->redirect(Yii::$app->request->baseUrl.'/telephone/index');
}
return $this->render('login', [
'model' => $model,
]);
}
And for preventing the add and delete action for unauthorized users i used:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['add','delete'],
'rules' => [
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied by default
],
],
];
}
But if unauthorized users clik add or delete, it is redirected to site/login. How can i change that controller and action?
There are different approaches to changing that route depending on the scope. They all involve changing the loginUrl property of the yii\web\User class.
Global
Edit config file.
'components' => [
'user' => [
'loginUrl' => ["controller/action"],
],
],
Controller/Action
Edit beforeAction method of the controller.
public function beforeAction($action)
{
// action-specific
if(in_array($action->id,['not', 'allowed', 'actions']))
Yii::$app->user->loginUrl = ["controller/action"];
// controller-wide
Yii::$app->user->loginUrl = ["controller/action"];
if (!parent::beforeAction($action)) {
return false;
}
return true;
}
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['add','delete'],
'rules' => [
'allow' => true,
'actions' => ['add','delete'],
'roles' => ['#'],
'denyCallback' => function ($rule, $action) {
return $this->redirect('index.php?r=site/login');
}
],
],
];
}