Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix the supports() method argument type of the security voter#37325

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
francoispluchino wants to merge0 commits intosymfony:5.0fromfrancoispluchino:fix-security-voter-supports-type-hint
Closed

Fix the supports() method argument type of the security voter#37325

francoispluchino wants to merge0 commits intosymfony:5.0fromfrancoispluchino:fix-security-voter-supports-type-hint

Conversation

@francoispluchino
Copy link
Contributor

QA
Branch?5.0 and 5.1
Bug fix?yes
New feature?no
Deprecations?no
Tickets~
LicenseMIT
Doc PR~

Since adding types to method arguments in the version 5.0 (and therefore also 5.1), there is a type mismatch on the first argument of thesupports() method of the abstract classSymfony\Component\Security\Core\Authorization\Voter\Voter.

Indeed, thesupports() method had in previous versions (4.x), the phpdoc indicating that the argument$attribute must be astring, but this one is not compatible with theisGranted() method of the interfaceSymfony\Component\Security\Core\AuthorizationAuthorizationCheckerInterface whose the$attribute argument is of typemixed.

The problem arises when you have voters extending the abstract classVoter positioned before a vote with an attribute of a type other thanstring.

Apart from Voters created by third parties, there is the voterExpressionVoter which waits in attribute, an instance of the classSymfony\Component\ExpressionLanguage\Expression (you can see thedoc for an example). Just add a voter extending the abstract classVoter with a higher priority than the voterExpressionVoter to get the error:

Argument 1 passed to FooVoter::supports() must be of the type string, object given

To avoid removing the type of the$attribute argument from the methodSymfony\Component\Security\Core\Authorization\Voter\Voter::supports(string $attribute, $subject), which can break the backward compatibility, you just have to test in thevote() method if the attribute is not astring and continue before calling thesupports() method.

@GrahamCampbell
Copy link
Contributor

* @param array $attributes An array of attributes associated with the method being invoked

Should this doc be changed tostring[] in Symfony 6?

jvasseur reacted with thumbs down emoji

@francoispluchino
Copy link
ContributorAuthor

francoispluchino commentedJun 18, 2020
edited
Loading

As I said, if we force typing on astring[], we will break the backward compatibility of some voters including the voterSymfony\Component\Security\Core\Authorization\Voter\ExpressionVoter that wait for an instance of the classSymfony\Component\ExpressionLanguage\Expression.

Only the helperVoter has this problem, because it is the only voter who expects astring to validate its use in thesupports method. Either thesupports method returnsfalse if$attribute is not a string, either you must do the verification just before calling thesupports method.

jvasseur reacted with thumbs up emoji

@derrabus
Copy link
Member

This change should be covered by a test. Also, your change might break some (probably rare) scenarios that would work right now:

  • $attribute could be a stringable object.
  • A voter could have removed thestring type declaration from thesupports() method signature.

@francoispluchino
Copy link
ContributorAuthor

@derrabus

Of course, I'm going to add a test :-)

$attribute could be a stringable object.

Indeed, we can very well have a stringable object, however, as has never been indicated in the documentation or the phpdoc, some voters are therefore not stringable.

A voter could have removed the string type declaration from the supports() method signature.

It was my first intention, however, we will break the Backward Compatibility if some voters override thesupports() method.. It is for this reason that I preferred to opt for a 'pre-test' of verification of the attribute.

@derrabus
Copy link
Member

Indeed, we can very well have a stringable object, however, as has never been indicated in the documentation or the phpdoc, some voters are therefore not stringable.

All voters that extend the abstractVoter class are. You are breaking that case:https://3v4l.org/2N1Hp

we will break the Backward Compatibility if some voters override thesupports() method.

I'm not suggesting to change thesupports() method. This is the case you might break:https://3v4l.org/MrcDq

@francoispluchino
Copy link
ContributorAuthor

Not all tests are passed in php 7.3, but these are tests for the Cache component. There was no error in the previous commit of this PR, so maybe just restart the tests for php 7.3 will remove the errorError: Call to undefined method Doctrine\DBAL\Driver\PDOSqlite\Driver::getName() (problem with a dependency version of Doctrine DBAL?).

@francoispluchino
Copy link
ContributorAuthor

francoispluchino commentedJun 18, 2020
edited
Loading

@derrabus We do indeed agree on the 2 points. However, send a non-stringable attribute to a voter extending the abstract class `Voter', and you will get the error:

Argument 1 passed to FooVoter::supports() must be of the type string, object given

Given that theAccessDecisionManager and theAuthorizationChecker classes accept attributes of any type (mixed), the problem with the attributes not stringable (see the test in this PR).

@GrahamCampbell
Copy link
Contributor

As I said, if we force typing on a string[], we will break the backward compatibility

I know, This is why I said v6.

@derrabus
Copy link
Member

However, send a non-stringable attribute to a voter extending the abstract class `Voter', and you will get the error:

Not necessarily, please see the second 3v4l link I posted.

@francoispluchino
Copy link
ContributorAuthor

Why limit arbitrarily the type to an array of strings? It is only the aid class to build the Voter that has become blocking.

In addition, if we just change the phpdoc tostring[] for the$attributes argument ofSymfony\Component\Security\Core\Authorization\Voter\VoterInterface::vote(), we will also need to change the phpdoc forSymfony/Component/Security/Core/Authorization/AuthorizationCheckerInterface::isGranted() andSymfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface::decide().

The principle of thesupports() method is precisely to validate if the subject and attributes are supported by the voter.

@francoispluchino
Copy link
ContributorAuthor

Not necessarily, please see the second 3v4l link I posted.

Remove my modification in the classVoter and run the test of this PR, and you get the error.

@derrabus
Copy link
Member

Not necessarily, please see the second 3v4l link I posted.

Remove my modification in the classVoter and run the test of this PR, and you get the error.

Again, please see the second 3v4l link I posted above. It shows you a voter that passes.

@francoispluchino
Copy link
ContributorAuthor

Sorry, but I will repeat myself :-), but the test passes with my modification, but without my modification you get:

1) Symfony\Component\Security\Core\Tests\Authorization\Voter\VoterTest::testVote with data set #9 (array(stdClass Object ()), 0, stdClass Object (), 'ACCESS_ABSTAIN if attributes ...trings')TypeError: Argument 1 passed to Symfony\Component\Security\Core\Tests\Authorization\Voter\VoterTest_Voter::supports() must be of the type string, object given, called in E:\Git\php\symfony\symfony\src\Symfony\Component\Security\Core\Authorization\Voter\Voter.php on line 33E:\Git\php\symfony\symfony\src\Symfony\Component\Security\Core\Tests\Authorization\Voter\VoterTest.php:70E:\Git\php\symfony\symfony\src\Symfony\Component\Security\Core\Authorization\Voter\Voter.php:33E:\Git\php\symfony\symfony\src\Symfony\Component\Security\Core\Tests\Authorization\Voter\VoterTest.php:59

@derrabus
Copy link
Member

All right, I give up. 🤷🏻‍♂️

@ro0NL
Copy link
Contributor

ro0NL commentedJun 18, 2020
edited
Loading

@francoispluchino try a testcase with a custom voter that removes the string type here;

protectedfunctionsupports(string$attribute,$object):bool

we could simply remove the string types in core:

abstractprotectedfunctionsupports(string$attribute,$subject);
/**
* Perform a single access check operation on a given attribute, subject and token.
* It is safe to assume that $attribute and $subject already passed the "supports()" method check.
*
* @param mixed $subject
*
* @return bool
*/
abstractprotectedfunctionvoteOnAttribute(string$attribute,$subject,TokenInterface$token);
as this contradicts with the actual type of $attributes (array, not string[]).

@francoispluchino
Copy link
ContributorAuthor

Yes, I had misunderstood the meaning of your answer, I am in the process of making the modification for this case.

@francoispluchino
Copy link
ContributorAuthor

@ro0NL If we delete the typestring, we break the voters implementing the methodsupports(string $attribute, $subject) :

PHP Fatal error:Declaration of Symfony\Component\Security\Core\Tests\Authorization\Voter\VoterTest_Voter::supports(string$attribute,$object): bool must be compatible withSymfony\Component\Security\Core\Authorization\Voter\Voter::supports($attribute,$subject) in E:\Git\php\symfony\symfony\src\Symfony\Component\Security\Core\Tests\Authorization\Voter\VoterTest.php on line72

@ro0NL
Copy link
Contributor

Ah true. We could reflect e.g.$attributeMustBeString, or just catch the type error.

@francoispluchino
Copy link
ContributorAuthor

I just added the test concerning the use case of attributes with a typeobject but stringable (in rapport withthis comment).

@francoispluchino
Copy link
ContributorAuthor

@derrabus

Not necessarily, please see the second 3v4l link I posted.

As I point out to@ro0NL, your example can break compatibility with Voters implementing the new signature (seethis comment).

However, thank you for your example concerning the fact that a stringable object can no longer be validated by a Voter when it was the case before my PR. I just add this use case.

@ro0NL
Copy link
Contributor

There's still the second case:https://3v4l.org/MrcDq, where attributes are just objects (non stringable), or maybe someone uses ints.array $attributes impliesmixed $attribute. It can be anything, depending on the voter removing the typehint yes/no.

@francoispluchino
Copy link
ContributorAuthor

@ro0NL Yes, but in this case, the Voter cannot extend the abstract classVoter, and so, the problem does not exist. Precisely the error arrives when you want to validate an attribute withobject type which is not stringable, and that a Voter extend the abstract classVoter. When this Voter tries to check out if the attribute is supported or not, the error occurs just before because the object cannot be converted to a string with the auto convertion by the type of the$attribute argument in thesupports() method.

@ro0NL
Copy link
Contributor

ro0NL commentedJun 18, 2020
edited
Loading

Im not sure i follow now 😕

https://3v4l.org/MrcDq bool(true)
with your patchhttps://3v4l.org/1Ef7n bool(false)

@francoispluchino
Copy link
ContributorAuthor

I don't think it is advisable to remove the typing from the methodVoter::supports() and to update the phpdoc to indicate that the$attribute argument is now of typemixed. As indicated, we risk breaking compatibility with the classes being the new signature ofVoter::supports(). It is a helper class, it should keep for the majority cases, namely the use of a string for the attribute. Personally, I have no preference as to whether or not to keep strong typing on the methodVoter::supports(), but I would like to know the opinion of each as well as the Core team, if possible.

@francoispluchino
Copy link
ContributorAuthor

francoispluchino commentedJun 18, 2020
edited
Loading

Im not sure i follow now 😕

https://3v4l.org/MrcDq bool(true)
with your patchhttps://3v4l.org/1Ef7n bool(false)

You remove the type of the$attribute argument on thesupports method. See my previous comment.

Note: However, your example is still valid, but if we remove the type in the abstract class, an error is thrown if the Voter use the new signature. It is for this reason that I chose to do a test before calling the methodsupports().

@derrabus
Copy link
Member

derrabus commentedJun 18, 2020
edited
Loading

if we remove the type in the abstract class

We cannot do this and nobody suggested to do this.

Yet, the type can be removed by userland code when implementing the voter. That is a valid thing to do in php and that is all that my second example shows. And since the type declaration wasn't there in Symfony 2/3/4, there are probably quite a few voter implementations out there that do not have the type declaration.

Expecting an object (or anything but a string) at this point might not be an execution path that was intended, but it's one that currently works and that will be broken by the change you're suggesting. But I don't really know how to deal with it. It might even be okay to break it.

markuspoerschke reacted with thumbs up emoji

@francoispluchino
Copy link
ContributorAuthor

Yes, I was looking for a solution when we delete the type. However, I don't see how to check whether the typing is present or not on the instantiated class.

@francoispluchino
Copy link
ContributorAuthor

The problem arises when we want to call the methodisGranted() with an attribute which is an instance of a non-stringable object, and it passes in all voters including voters extending the abstract classVoter.

@derrabus
Copy link
Member

However, I don't see how to check whether the typing is present or not on the instantiated class.

You you catch and parse theTypeError though. But we probably want to avoid that kind of dark magic if we can. 😎

@francoispluchino
Copy link
ContributorAuthor

It's not a problem to add the méthode__toString() on the class that is used for theattribute argument when it is own code, but it's a problem with third-party libraries. Givent that the methodisGranted() accepts attributes with a typemixed, we cannot just say that it is enough to break compatibility for the Symfony 5.x, alas.

You you catch and parse the TypeError though. But we probably want to avoid that kind of dark magic if we can. 😎

Totally agree with you, but I don't see any other more elegant solution.

@francoispluchino
Copy link
ContributorAuthor

I just modified the PR to use a try/catch for the TypeError, and added tests for the attributes of typeobject stringable andinteger (so that removes the type of the$attribute argument in the final class).

@wouterj
Copy link
Member

wouterj commentedJun 18, 2020
edited
Loading

Apart fromExpressionVoter, are there other bundles/projects using non-string attributes? I recently had a (private) talk aboutExpressionVoter and I'm convinced it's not necessarily correct, so we can/should change it. If there are no good use-cases for non-string attributes, I think it's good to consider deprecating non-string attributes.

derrabus, ro0NL, and xabbuh reacted with thumbs up emoji

@jvasseur
Copy link
Contributor

@wouterj how would you implement theExpressionVoter without allowing non-string attributes ?

I'm all in favor of restricting what we can use as attributes but I'm not sure it's a reasonable move.

Another thing to take into account is that PHP will probably add support for enums at some points and people will want to use enums as attributes.

@wouterj
Copy link
Member

Let's not take PHP enums into consideration. First of all, it'll take a while before it will be added (it's already discussed for many years). Secondly, as everyone is now migrating to strict typed code bases, they will need to provide compatibility with current day strict typing for enums (e.g. an enum of strings should be able to be passed to astring type check).

AboutExpressionVoter: I don't think it should be a voter. The only use-case is inaccess_control. In other cases, it's much better to just write plain PHP logic instead of using the expression language. Anyways, let's not hijack this ticket with proposed changes in something else - I'll create a PR once I have some time to work on it.

jvasseur, francoispluchino, and derrabus reacted with thumbs up emoji

@derrabus
Copy link
Member

Another thing to take into account is that PHP will probably add support for enums at some points and people will want to use enums as attributes.

That's a change we can hardly anticipate right now, can we? There are however libraries likemyclabs/php-enum that emulate enums in php. They should work already because the enum instances are stringable.

@francoispluchino
Copy link
ContributorAuthor

@wouterj. I aggree with you, but for the moment, it is necessary to fix the bug, and depreciate or not for version 5.2 and prohibit the use of a non-string attribute in version 6.0, if we decide to take this direction.

Personally I have a use case which led me to do it like votingExpressionVoter when I used a string attribute before.

Example 1:

In my case, I use several voters including one which allows to validate permissions according to the subject. This subject can very well be a string (name of the class), an instance of a class, or an instance of aFieldVote class containing the name of the field and the instance or name of the class. In any case, we do have an authorization attribute and a subject.

In attribute, I used a permission name in the same style as theRoleVoter, namely, the role name in uppercase prefixed withROLE_. This scenario is "natural" because the name of the role has always been formed with theROLE_ prefix. However, for myPermissionVoter, I must indicate the name of the permission as an attribute. This gave for theupdate andedit permissions:

// Check the authorization on the object$authorizationChecker->isGranted('perm_update',$entity);$authorizationChecker->isGranted('perm_update', PostInterface::class);// Check the authorization on the field of object$authorizationChecker->isGranted('perm_edit',newFieldVote($entity,'title'));$authorizationChecker->isGranted('perm_edit',newFieldVote(PostInterface::class,'title'));

As you can see, it is not "natural" for a user to have to do magic by prefixing the name of the permission with:permission_,perm_,permission:,perm:,PERMISSION_,PERM_,PERMISSION:,PERM:,permission/,permission@, etc... or any other symbol to separate.

Of course, I could use an array of the style['permission', 'update'] or any other style, but you see the problem, it's easy to make a mistake. Also, using simply the permission name as an attribute can behave unexpectedly with other Voters.

Using the example below is much more meaningful and logical, while being certain of the expected behavior:

// Check the authorization on the object$authorizationChecker->isGranted(newPermissionVote('update'),$entity);$authorizationChecker->isGranted(newPermissionVote('update'), PostInterface::class);// Check the authorization on the field of object$authorizationChecker->isGranted(newPermissionVote('edit'),newFieldVote($entity,'title'));$authorizationChecker->isGranted(newPermissionVote('edit'),newFieldVote(PostInterface::class,'title'));

You can see the old version of the component using the prefixperm_ as attribute inthis bundle (the new version is not yet open source).

The fact of define the permission in the attribute and leaving the subject to the$subject attribute that we want to validate, goes according to the logic initially planned by the Security component. However, we could have put an attribute of typestring like for examplepermission and created a configurable object to include the name of the permission and the subject. But you find that it becomes an unintuitive hack by doing in this way, while not making it easier to use.

Of course, it is possible to make the classPermissionVote stringable, which I just did to avoid the error with the current version of Symfony, but this is a workaround compared to the current documentation of the methodAuthorizationChecker::isGranted().

Example 2:

There is also another reason to use something other than an attribute string. This time, it's with a component validating Oauth2 scopes. The Voter waits in attribute for an instance of the classScopeVoter which can be configurable, and no subject, because subject, is always the authenticated user.

The classScopeVote can have a string or a list of string in its constructor which are the required Oauth2 scopes. It also has an option to validate if at least one scope is in the list or if all scopes are required for the subject tested.

You will therefore understand that there is still a possibility of unexpected behavior if we put in attribute, only the name of the scope without prefix likescope_, and it would also not be logical to put the "configuration" of the check with the subject tested in the$subject argument, that would be contrary to the original logic.

// Check if the current user is authorized to read a Post with a his Oauth2 scopes$authorizationChecker->isGranted(newScopeVote(['post','post.readonly'],false));// Check if the current user is authorized to manage a Post with a his Oauth2 scopes$authorizationChecker->isGranted(newScopeVote('post'));

Note:

  • post scope is to manage the Post entity (read, create, update, delete, etc)
  • post.readonly scope is to read only Post
  • The second argument of theScopeVote class is to check if all the scopes listed are required, by default, this value istrue

Another problem if we use a string instead of an instance of an object, it is likely easier that another Voter can validate the attribute and the subject when it was not intended for him. With an object, we can be certain that we reach the correct Voter which checks if the instance of the attribute is compatible, while making the code more readable and understandable. And as I said, put apermission string in attribute (orscope string in attribute), and in subject, an instance for the configuration and the subject does not correspond to the initial logic of the component. And using an array for the attribute will make the code more difficult to understand, in contrast to the class.

For example, it is more complicated to have:

$authorizationChecker->isGranted('permission',newPermissionVote('edit',newFieldVote(PostInterface::class,'title')));$authorizationChecker->isGranted('scope',newScopeVote('post'));

that:

$authorizationChecker->isGranted(newPermissionVote('edit'),newFieldVote(PostInterface::class,'title'));$authorizationChecker->isGranted(newScopeVote('post'));

Regarding strict typing, I agree with you, and it is also for this reason that I used classes as an attribute, knowing that the documentation of Symfony authorized it. Of course, we can very well decide to deprecate the use of non-string attribute, but I think it would be more appropriate to allow at least stringable objects.

This comment is very long, and I hope I have been understandable enough with my English and the wish to be as brief as possible, but it is ultimately quite difficult :-).

wouterj reacted with thumbs up emoji

@wouterj
Copy link
Member

@wouterj. I aggree with you, but for the moment, it is necessary to fix the bug, and depreciate or not for version 5.2 and prohibit the use of a non-string attribute in version 6.0, if we decide to take this direction.

Yes, agreed. But I think the bug can be fixed a bit more "hacky" if we know we can clean it up in 6.0 :)

Thanks for your interesting insights! I need some time to process all the information - I'll follow-up with an RFC issue. Let's finish this bug report - as I agree that a bug has been introduced.

francoispluchino reacted with thumbs up emoji

continue;
}
}catch (\TypeError$e) {
if (preg_match((sprintf('/Argument 1 passed to ([\w\\\]+)::supports\(\) must be of the type string, (\w+) given/')),$e->getMessage())) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
if (preg_match((sprintf('/Argument 1 passed to ([\w\\\]+)::supports\(\) must be of the type string, (\w+) given/')),$e->getMessage())) {
if (0 ===strpos($e->getMessage(),'Argument 1 passed to') &&false !==strpos($e->getMessage(),'::supports() must be of the type string')) {

Strpos seems to be about 50% quicker:https://3v4l.org/47iXF

This method is potentially called quite a lot (for every voter in access_control and all isGranted calls), so it's performance critical, so I think it's worth considering.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Indeed, this is to be considered. Your test is less strict but it is probably sufficient, but above all faster. I make the modification.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It is done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@wouterj Please keep in mind that the error message format changes with php 8. The error message does not begin withArgument anymore, but with the method name, IIRC.

wouterj and francoispluchino reacted with thumbs up emoji
Copy link
Member

@wouterjwouterjJun 18, 2020
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Travis agrees:

TypeError: Symfony\Component\Security\Core\Tests\Authorization\Voter\VoterTest_Voter::supports(): Argument #1 ($attribute) must be of type string, stdClass given, called in /home/travis/build/symfony/symfony/src/Symfony/Component/Security/Core/Authorization/Voter/Voter.php on line 34

So it probably should do something like:

if (\PHP_VERSION_ID <80000) {if (0 ===strpos($e->getMessage(),'Argument 1 passed to') &&false !==strpos($e->getMessage(),'::supports() must be of the type string')) {continue;    }}elseif (false !==strpos($e->getMessage(),'supports(): Argument #1')) {continue;}throw$e;

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@wouterj Thank you, I didn't have PHP 8 on hand right now. I take your code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think almost nobody has. Fortunately, the Symfony test suite runs on PHP 8. You can find its results in the "Travis" link below. The relevant failure ishttps://travis-ci.org/github/symfony/symfony/jobs/699831814#L4276 (you can ignore the other failures, lots of things are work-in-progress for PHP 8/external dependency support).

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It is done.

Copy link
Member

@wouterjwouterj left a comment
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks for your very quick responses! Looks good to me now (looks like all test failures are unrelated)

@fabpotfabpot changed the base branch frommaster to5.0June 25, 2020 09:01
@fabpot
Copy link
Member

Thank you@francoispluchino.

@fabpotfabpot closed thisJun 25, 2020
fabpot added a commit that referenced this pull requestJun 25, 2020
…ter (francoispluchino)This PR was submitted for the master branch but it was merged into the 5.0 branch instead.Discussion----------Fix the supports() method argument type of the security voter| Q             | A| ------------- | ---| Branch?       | 5.0 and 5.1| Bug fix?      | yes| New feature?  | no| Deprecations? | no| Tickets       | ~| License       | MIT| Doc PR        | ~Since adding types to method arguments in the version 5.0 (and therefore also 5.1), there is a type mismatch on the first argument of the `supports()` method of the abstract class `Symfony\Component\Security\Core\Authorization\Voter\Voter`.Indeed, the `supports()` method had in previous versions (4.x), the phpdoc indicating that the argument `$attribute` must be a `string`, but this one is not compatible with the `isGranted()` method of the interface `Symfony\Component\Security\Core\AuthorizationAuthorizationCheckerInterface` whose the `$attribute` argument is of type `mixed`.The problem arises when you have voters extending the abstract class `Voter` positioned before a vote with an attribute of a type other than `string`.Apart from Voters created by third parties, there is the voter `ExpressionVoter` which waits in attribute, an instance of the class `Symfony\Component\ExpressionLanguage\Expression` (you can see the [doc](https://symfony.com/doc/current/security/expressions.html) for an example). Just add a voter extending the abstract class `Voter` with a higher priority than the voter `ExpressionVoter` to get the error:```Argument 1 passed to FooVoter::supports() must be of the type string, object given```To avoid removing the type of the `$attribute` argument from the method `Symfony\Component\Security\Core\Authorization\Voter\Voter::supports(string $attribute, $subject)`, which can break the backward compatibility, you just have to test in the `vote()` method if the attribute is not a `string` and continue before calling the `supports()` method.Commits-------b8192ee Fix the 'supports' method argument type of the security voter
This was referencedJul 24, 2020
@Warxcell
Copy link
Contributor

This is very confusing, and still NOT fixed in Symfony 6.0 - the type there is STILL string, butisGranted still acceptsmixed

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@derrabusderrabusderrabus left review comments

@fabpotfabpotfabpot approved these changes

@wouterjwouterjwouterj approved these changes

Assignees

No one assigned

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

10 participants

@francoispluchino@GrahamCampbell@derrabus@ro0NL@wouterj@jvasseur@fabpot@Warxcell@xabbuh@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp