Home > database >  Access Denied Error Symfony with custom roles
Access Denied Error Symfony with custom roles

Time:11-20

Good morning, I am configuring my symfony 5.4 api and I am having problems with the is_granted function of symfony. My connected user has all the roles in the token (classic roles custom roles). Custom roles are linked to the company and each user of a company inherits the roles of the company.

I add all the roles in the token however when I put an is_granted on a rest class, I get an access denied. Could you tell me if I forgot something please?

My REST class with the is_granted function :

/**
 * TrainingSession controller.
 * @RouteResource("Training")
 * @Security("is_granted('MODULE_TRAINING')")
 */
class TrainingSessionRESTController extends BaseRESTController
{

My token with the corresponding role :

[▼
  "ROLE_HR"
  "ROLE_DEBUG"
  "ROLE_PANEL"
  "ROLE_USER"
  "ROLE_MANAGER"
  "MODULE_LIBRARY"
  "MODULE_EXPENSE_REPORT"
  "MODULE_TRAINING"
  "MODULE_ANNUAL_REVIEW"
  "MODULE_PRO_REVIEW"
  "MODULE_COMPANY_CHART"
  "MODULE_COMPANY_CONTACT"
  "MODULE_COMPANY_DOCUMENT"
  "MODULE_CALENDAR"
  "MODULE_FOLDER"
  "MODULE_TIME_MANAGEMENT"
  "MODULE_EMPLOYEE_MEDICAL"
  "MODULE_REPORT"
]

Here is the vendor security method of the class ExpressionLanguage.php which returns false instead of True. $expression contains: "is_granted('MODULE_TRAINING')". and $values ​​does contain the MODULE_TRAINING role.

/**
 * Evaluate an expression.
 *
 * @param Expression|string $expression The expression to compile
 *
 * @return mixed
 */
public function evaluate($expression, array $values = [])
{
    return $this->parse($expression, array_keys($values))->getNodes()->evaluate($this->functions, $values);
}

CodePudding user response:

Can you try to do the same with a role that starts with ROLE_ ?

Symfony RoleVoter do not work with roles that are not prefixed with ROLE_

public function __construct(string $prefix = 'ROLE_')
    {
        $this->prefix = $prefix;
    }

public function vote(TokenInterface $token, mixed $subject, array $attributes): int
    {
        //...
        foreach ($attributes as $attribute) {
            if (!\is_string($attribute) || !str_starts_with($attribute, $this->prefix)) {
                continue;
            }
            //...
        }

        return $result;
    }

Because of this, when isGranted or is_granted is called and your role doesn't start with ROLE_, the default voter will abstain.

So to fix your issue you could prefix your MODULE role with ROLE_, or create a custom voter to be more flexible on role names.

  • Related