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

Not authorized to reorder structure entries #2772

Open
ghost opened this issue Apr 19, 2018 · 39 comments
Open

Not authorized to reorder structure entries #2772

ghost opened this issue Apr 19, 2018 · 39 comments

Comments

@ghost
Copy link

ghost commented Apr 19, 2018

Description

Somehow I can't reorder structure entries on our staging server. In the red bar a message appears with an unknow error occured. Seems like a bug. I am logged in as a administrator/super user.

Stack trace

2018-04-18 17:24:16 [217.100.226.36][1][1rprs6qtr941te0urqodf1tqgc][error][yii\web\HttpException:403] yii\web\ForbiddenHttpException: User is not authorized to perform this action in /var/www/vhosts/site.com/httpdocs/vendor/craftcms/cms/src/web/Controller.php:187
Stack trace:
#0 /var/www/vhosts/site.com/httpdocs/vendor/craftcms/cms/src/controllers/StructuresController.php(67): craft\web\Controller->requireAuthorization('editStructure:3')
#1 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/base/BaseObject.php(109): craft\controllers\StructuresController->init()
#2 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/base/Controller.php(86): yii\base\BaseObject->__construct(Array)
#3 [internal function]: yii\base\Controller->__construct('structures', Object(craft\web\Application), Array)
#4 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/di/Container.php(375): ReflectionClass->newInstanceArgs(Array)
#5 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/di/Container.php(156): yii\di\Container->build('craft\\controlle...', Array, Array)
#6 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/BaseYii.php(345): yii\di\Container->get('craft\\controlle...', Array)
#7 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/base/Module.php(642): yii\BaseYii::createObject('craft\\controlle...', Array)
#8 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/base/Module.php(596): yii\base\Module->createControllerByID('structures')
#9 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/base/Module.php(522): yii\base\Module->createController('move-element')
#10 /var/www/vhosts/site.com/httpdocs/vendor/craftcms/cms/src/web/Application.php(267): yii\base\Module->runAction('structures/move...', Array)
#11 /var/www/vhosts/site.com/httpdocs/vendor/craftcms/cms/src/web/Application.php(515): craft\web\Application->runAction('structures/move...', Array)
#12 /var/www/vhosts/site.com/httpdocs/vendor/craftcms/cms/src/web/Application.php(251): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#13 /var/www/vhosts/site.com/httpdocs/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#14 /var/www/vhosts/site.com/httpdocs/web/index.php(21): yii\base\Application->run()
#15 {main}

Additional info

  • Craft version: 3.0.3.1
  • PHP version: 7.1.16
  • Database driver & version: MySQL 5.5.5
  • Plugins & versions:
@brandonkelly
Copy link
Member

Weird. Is it working on any other environments for you? Do you have any config settings in config/general.php that are unique to the staging environment?

@ghost
Copy link
Author

ghost commented May 22, 2018

Sorry for my late reaction. I hoped that an update would solve the problem.. but no luck. The config settings are identical. I guess something to do with the database? (I was developing this website on a RC version)

For example: as an admin I can create a new user, but i can't link a new user to a user-group. An error message appears "Only administrators are authorized"..?

@brandonkelly
Copy link
Member

Any chance we can get access to the server? If so you can send credentials to support@craftcms.com.

@ghost
Copy link
Author

ghost commented May 23, 2018

Thanks, mail has been sent.

@Emkaytoo
Copy link

Emkaytoo commented Jun 5, 2018

I referenced a similar error in #2958 (I searched like 5 or 6 different queries to find duplicates but didn't see any that matched my queries. Sorry.)

@askogrand
Copy link

I am experiencing the same error. Almost identical setup on staging, where we can re-order, but cannot reorder on production.

@jasonandres
Copy link

I have the same issue, the stack trace is the same.

2018-06-07 15:38:46 [205.250.0.226][1][-][error][yii\web\HttpException:403] yii\web\ForbiddenHttpException: User is not authorized to perform this action in /usr/share/craftsites/wildhorse/vendor/craftcms/cms/src/web/Controller.php:214

Application Info

  • PHP version 7.1.15
  • Database driver & version MySQL 5.7.12
  • Image driver & version Imagick 3.4.3 (ImageMagick 6.7.8-9)
  • Craft edition & version Craft Solo 3.0.10.2
  • Yii version 2.0.15.1
  • Twig version 2.4.8
  • Guzzle version 6.3.3
  • Imagine version 0.7-dev

@brandonkelly
Copy link
Member

@beeldr @Emkaytoo @askogrand @jasonandres Are your production environments load-balanced? Are you aware of whether each of the servers storing session data in the same place, regardless of web server?

@askogrand
Copy link

Yes, they are load balanced. They are storing session data in their respective projects memcached cloud servers. They do not share the same one.

@brandonkelly
Copy link
Member

I think that’s your issue. Permission to modify structures is stored in the PHP session. So when this happens, it’s probably because the Ajax request to modify the structure is hitting a different web server than the one that initially authorized the action.

If you’re going to use load-balanced web servers, you need to make sure that they share the same PHP session, by pointing them to the same Redis/Memcached server.

@askogrand
Copy link

Production and staging are different sites. Different memcaches. Their respective dynos all use the same memcache server. I apologize if my answer was confusing.

@jasonandres
Copy link

@brandonkelly Our sites are running on a single instance, and we are not utilizing Redis/Memcached.

@brandonkelly
Copy link
Member

If any of you can give us an admin account + FTP access to your server where this is happening, that would be super helpful. We’re not able to reproduce.

@askogrand
Copy link

@brandonkelly has anyone provided anything to you yet? Id give you access to our admin, but we are running on heroku, so no FTP. We do have a bugsnag accout, however.

@brandonkelly
Copy link
Member

Not yet. Having access to the environment will be critical. Could be SSH instead if FTP isn’t an option.

@askogrand
Copy link

@jasonandres Any chance you can get your creds to Brandon? Ive tried with our environment, but Im afraid the heroku/load balancing is obfuscating the issue. @beeldr, maybe you can share creds as well?

@jasonandres
Copy link

@brandonkelly We moved our staging environment from a single instance to load balanced instances running on Amazon ECS, with EFS for client assets and Aurora MySQL using the same Dockerfile for the build and now we don't have this issue, we can re-order entries just fine.

Unfortunately we torn down the other staging environment so we no longer have access to that.

@jasonschock
Copy link

jasonschock commented Oct 11, 2018

Same issue today on Fortrabbit's Pro tier. Works locally.

Anyone resolve this?

It seems to be specific to the POST <DOMAIN>/index.php?p=admin/actions/structures/move-element call. I see tons of other ajax requests happening with a 200 response, but when I try to reorder, I get a 403.

If I force-clear the cache in Chrome, reorder succeeds on the first try. All subsequent trie then fail with a 403.

@pr1ntr
Copy link

pr1ntr commented Nov 16, 2018

I get this error from a single docker container. No load balancer. I am using a bridge network driver for the docker-compose setup

@kristoferblack
Copy link

I'm having the same issue on on Fortrabbit Pro tier that @jasonschock is having. Reorder attempts results in a 403.

@jasonschock
Copy link

FWIW, I solved my issue with this Craft plugin: https://github.com/fortrabbit/yii-memcached. FortRabbit Pro stack is multi-node. You need to use memcache for shared session storage; by default, you get PHP's file session store.

@arifje
Copy link

arifje commented May 8, 2019

Also having this problem right now, but; it happens in Chrome (OSX) only, and it's working in Firefox and other browsers.

The difference with Chrome is that we have multiple (development) sites opened in tabs, with different domains. Maybe that has something to do with it.

Craft CMS 3.1.25
PHP 7.2
No loadbalancing, single server / domain / ip.

Logs;

Screenshot 2019-05-08 at 11 26 22

@ryanpcmcquen
Copy link

We are affected by this issue on Craft 3.3.20.1.

@brandonkelly
Copy link
Member

We have seen this happen as a result of the defaultCookieDomain config setting getting changed. In that case, clearing browser caches will solve it.

@emblematiq
Copy link

Getting the same error on a multiple dyno setup in Heroku. Moving to a single dyno solves it.
Does anyone have an example on how to set up redis or memcached on Heroku? Thanks in advance.

@brandonkelly
Copy link
Member

@emblematiq Connecting Craft to Redis is a matter of swapping out the cache and session components with those provided by the yii2-redis library. You can find examples on https://docs.craftcms.com/v3/config/app.html.

@VitaliiTsilnyk
Copy link

Happened to me as well, indeed after changing the defaultCookieDomain setting.
Clearing browser local storage and cookies resolved the issue.

If this helps, this is what I discovered during my debugging:
Traced it back to this line in StructuresController.php. Which then calls this function. Where $this->owner->get($this->authAccessParam) returns null.
Tried to change this line to $this->requirePermission('editStructure:' . $structureId); just to see what happens and it started to work as expected.

@JonGoldmanPlaybill
Copy link

JonGoldmanPlaybill commented Jan 30, 2022

This has been plaguing us in multiple environments. We get the 403 error in production and in our lower environments. All are using Redis for both cache and session. Production has multiple heads, lower env's do not. Lower Env's share a Redis server in AWS Elasticache, production is separate. Have tried all of the following solutions, only 1 works but is not sustainable in production:

  • Changed prefix in app.php so that cache & session are using a different key prefix (see these in a redis monitor, including the lookup for the current session and the Key matches the original login) - FAIL
  • Tried eliminating the line that set the Redis password to blank (from another error report) - FAIL
  • Cleared All Cookies and cache on browsers (Safari, Chrome, Firefox, Safari Technology Preview) - FAIL
  • Commented/Removed Session cache settings for Redis - SUCCESS, but unusable as multi-head needs a shared session storage

I have seen some mention of storing cache and session in separate databases (separating databases in Redis, according to the creator, is a bad idea). Is it possible to have a different Redis host for sessions and cache? Would this have any effect on the issue?

UPDATE: I tried @VitaliiTsilnyk solution above and it works now. Is this now a PR for Craft? I do not know if previously clearing my cookies had anything to do with this. But I do know that my team's CP url is a subdomain of the main url for the site (e.g., cms.[domain].com). The lower envs are not using a different cookie domain to my knowledge.

@angrybrad
Copy link
Member

angrybrad commented Jan 30, 2022

@JonGoldmanPlaybill you probably need to set https://craftcms.com/docs/3.x/config/config-settings.html#defaultcookiedomain to .domain.com (notice the preceding .)

@JonGoldmanPlaybill
Copy link

@angrybrad Unfortunately I tried setting to both dev.[domain].com and .[domain].com (cleared cookies and cache both times before trying). My redeploy via AWS Codepipeline restored the regular code that I had hacked from @VitaliiTsilnyk idea. Server Error 403 on both attempts to reorder categories.

A note that not only is this already using Redis with a unique prefix for sessions and cache, it also is not a multi-user head- the dev instance is a single instance, using a lower env Redis from AWS ElastiCache, and it's own RDS DB server.

@VitaliiTsilnyk
Copy link

Please note that my idea is just an idea, not an actual solution. I was just playing around trying to fix the bug before finding this issue. I have no idea why requireAuthorization is being used instead of requirePermission, but probably there are reasons for that.

@JonGoldmanPlaybill
Copy link

JonGoldmanPlaybill commented Jan 30, 2022

@VitaliiTsilnyk Thank you for that. I'm less concerned in this case, because in order to even get to the CP login in the first place in our environment, you have to get past a load balancer that requires SSO Authentication. So there are two layers of authentication protecting that avenue in. I would also note that your idea is the only method that has worked, besides resorting to non-KeyStore-based session caching.

@brandonkelly
Copy link
Member

brandonkelly commented Jan 31, 2022

There aren’t any permissions named editStructure:…. So changing that line to requirePermission() would only work if you are using an admin account, where all permissions are assumed to be granted.

We use session-based authorization here because the Structures service doesn’t know which specific permissions should be checked. So it just expects a prior controller to authorize it via the session.

@JonGoldmanPlaybill
Copy link

@brandonkelly Understood. Which explains why when I made that change it worked, because I am on an admin account. But I'm using the same account with the previous function call, which is what confuses me for the 403. I would understand if it was a perms issue, but with a full admin I shouldn't encounter 403s from Craft.

@JonGoldmanPlaybill
Copy link

@brandonkelly, also, as far as I can see, there is no controller in the way here, or any to give prior auth. This is not just any structure, but we are editing the order of categories, which we don't interfere with to my knowledge.

@brandonkelly
Copy link
Member

I would understand if it was a perms issue, but with a full admin I shouldn't encounter 403s from Craft.

Session-based authorization doesn’t care if you’re an admin, unlike user permissions. So that’s why switching it to a permission check fixed it for you, even though the permission doesn’t exist.

Ultimately this is either a cookie issue or an environmental issue, where your environment is not persisting PHP session data across requests.

@JonGoldmanPlaybill
Copy link

@brandonkelly Actually it turned out that this was due to a data validation failure in the category. There was an illegal value that had been migrated in to a Category class and the Category Entries could not be saved. Once the data issue was corrected, then the adding of a prefix that differed between the session and cache in Redis seems to have solved the issue.

@brandonkelly
Copy link
Member

Huh strange, but glad you got it sorted!

@JonGoldmanPlaybill
Copy link

@brandonkelly Just as a future FYI, the field was a "Color" field type and the illegal value was #black. We went into the table and replaced all the #black with #000000. Suddenly we could re-order. I figured this when I went into a category entry and tried to save it (to see if the index was maybe corrupted) and it popped an illegal value error.

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