I am using access control to allow the access to only authenticated users.
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['display'],
'rules' => [
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
'matchCallback' => function ($rule, $action) {
return $this->redirect(Yii::$app->request->baseUrl.'/site/login');
}],
],
],
];
}
public function actionDisplay()
{
echo "display";
}
When i try to access the display action while not logging in i am redirected to login page. But when i try to access the display action even with logged in it is redirecting to index page. what am i doing wrong?
add 'actions' => [ 'display'],
like below
'rules' => [
// allow authenticated users
[
'actions' => [ 'display'],
'allow' => true,
'roles' => ['#'],
'matchCallback' => function ($rule, $action) {
return $this->redirect(Yii::$app->request->baseUrl.'/site/login');
}],
],
normally it work for me
Nothing was wrong with the code. just 'matchCallback' which is called to the authenticated user and redirected to login which eventually redirects to index if logged in.
Removing the 'matchCallback' solved it.
'rules' => [
[
'allow' => true,
'roles' => ['#'],
],
],
Related
i have a problem verifying the permissions that a user has on the actions (Exm: index, create, update, etc.) within the controller, I use the following code to verify the permissions that the user has:
My Controller:
backend/modules/content/controllers/ArticleController.php
$behaviors['access'] = [
'class' => AccessControl::className(),
'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;
}
}
]
]
];
With this code I get the route (Exm:content/article/index) which will be validated to know if you have the permission.
Updating
I have noticed that the problem is generated in 'as globalAccess' (backend/config/web.php), when I deactivate the global access it can validate the permissions, but when I have global access all users have full access, but disabling it brings other problems .
'as globalAccess' => [
'class' => common\behaviors\GlobalAccessBehavior::class,
'rules' => [
[
'controllers' => ['sign-in'],
'allow' => true,
'roles' => ['?'],
'actions' => ['login'],
],
[
'controllers' => ['sign-in'],
'allow' => true,
'roles' => ['#'],
'actions' => ['logout'],
],
[
'controllers' => ['site'],
'allow' => true,
'roles' => ['?', '#'],
'actions' => ['error'],
],
[
'controllers' => ['debug/default'],
'allow' => true,
'roles' => ['#'],
],
[
'allow' => true,
'roles' => ['#'],
],
],
],
the problem is that validation does not work, the only way it works is to add a rule in global access that allows me to grant permissions to roles, but it would be default:
[
'controllers' => ['article'],
'allow' => true,
'roles' => ['administrator'],
],
[
'controllers' => ['article'],
'allow' => false,
],
or go adding the function in each action Yii::$app->user->can(..) in each action
if (\Yii::$app->user->can('content/article/index')) {
.. code index ..
} else {
throw new ForbiddenHttpException
}
In the ideal case, you don't have to be adding the function Yii::$app->user->can(..) to each action or add a default rule in global access.I hope can support me
I want to call some actions only when user is logged in.
How to do it without checking the user login status every time?
You will need to add a behaviors() method to your controller such as :
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['login', 'logout', 'signup'],
'rules' => [
[
'allow' => true,
'actions' => ['login', 'signup'],
'roles' => ['?'],
],
[
'allow' => true,
'actions' => ['logout'],
'roles' => ['#'],
],
],
],
];
}
The roles defined above are # for all users that are logged in and ? for all users that aren't logged in. In your case you will be interrested in setting the role to #.
You can of course replace these with any rbac roles/permissions.
Here's more information on authorization from the Yii2 guide
I've tried to add menu map in backend-side. I use yii2-advanced. This is my “controller” code:
public function actionMap()
{
return $this->render('map');
}
But, when I try to access it with this url http://localhost/yii2advanced/backend/web/index.php?r=site/map, I've got error message Forbidden (#403) - You are not allowed to perform this action. I don't understand why I got this error message, can anybody help me to fix this problem?
It's caused by AccessControl. Most likely the action map is blocked according to access rules. Example of allowing it for all authenticated users:
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'access' => [
'class' => \yii\filters\AccessControl::className(),
'only' => ['create', 'update'],
'rules' => [
// allow authenticated users
[
'allow' => true,
'roles' => ['#'],
],
// everything else is denied
],
],
];
}
Alternatively you can adjust access according to some RBAC roles.
In addition to the arogachev's answer:
Paste it in your site controller:
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['#'],
],
[
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
Currently I have the problem that not logged in users can access the website if they enter a specific URL.
My site controller looks like this:
class SiteController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['logout'],
'rules' => [
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['#'],
],
[
'actions' => ['login'],
'allow' => true,
'roles' => ['?'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
[...]
}
That does not work, users can still access the website.
Another caveat: The login page is a different URL https://login.mywebsite.com whereas my website is http://anotherwebsite.com
For actionIndex it works:
public function actionIndex()
{
if (!Yii::$app->user->isGuest) {
return $this->render('index');
}
else {
//$this->callback();
$this->redirect('https://login.mywebsite.com');
}
}
I want this to be the default if not logged in.
Try to remove 'only' => ['logout'], from public function behaviors() or add 'index'
docs about only:
#var array list of action IDs that this filter should apply to. If this property is not set,
then the filter applies to all actions, unless they are listed in [[except]].
In Yii2 advanced template, they have the signup components for new users in the frontend.
I want to put that signup process into the /backend so that only admin users can create other new users.
So in moving SignupForm, signup view, adding the Signup action to the backend/SiteController, I'm getting 403 error "You are not allowed to perform this action".
Has anyone been able to put the signup process into the backend of the advanced template in Yii2 ?
What I want to do is have admin users create the new user and give the login details to the external party. The external party would then be advised to run the Password Reset, in order to set their own password. But effectively, its locking down the registration/signup process.
Its nothing that should stop you from making this work. But will need to change a few things along the way.
First off, I guess your error message comes from the AccessControl that the backend SiteController has:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
Change this to:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['login', 'error'],
'allow' => true,
],
[
'actions' => ['logout', 'index', 'signup'],
'allow' => true,
'roles' => ['#'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
Orelse this will result in the error message:
Forbidden (#403)
You are not allowed to perform this action.
Remember that the signup function is made for guests registering, and that it automatically out-of-the box log the user in when the account is created.
You have to remove this feature, and you might encounter some other bugs along the way.
Good Luck.