35
35
use Symfony \Component \Routing \Generator \UrlGeneratorInterface ;
36
36
use Symfony \Component \Routing \RouterInterface ;
37
37
use Symfony \Component \Security \Core \Authentication \Token \Storage \TokenStorageInterface ;
38
+ use Symfony \Component \Security \Core \Authorization \AccessDecision ;
38
39
use Symfony \Component \Security \Core \Authorization \AuthorizationCheckerInterface ;
40
+ use Symfony \Component \Security \Core \Authorization \Voter \VoterInterface ;
39
41
use Symfony \Component \Security \Core \Exception \AccessDeniedException ;
40
42
use Symfony \Component \Security \Core \User \UserInterface ;
41
43
use Symfony \Component \Security \Csrf \CsrfToken ;
@@ -202,6 +204,20 @@ protected function isGranted(mixed $attribute, mixed $subject = null): bool
202
204
return $ this ->container ->get ('security.authorization_checker ' )->isGranted ($ attribute , $ subject );
203
205
}
204
206
207
+ /**
208
+ * Checks decision of the attribute against the current authentication token and optionally supplied subject.
209
+ *
210
+ * @throws \LogicException
211
+ */
212
+ protected function getDecision (mixed $ attribute , mixed $ subject = null ): AccessDecision
213
+ {
214
+ if (!$ this ->container ->has ('security.authorization_checker ' )) {
215
+ throw new \LogicException ('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle". ' );
216
+ }
217
+
218
+ return $ this ->container ->get ('security.authorization_checker ' )->getDecision ($ attribute , $ subject );
219
+ }
220
+
205
221
/**
206
222
* Throws an exception unless the attribute is granted against the current authentication token and optionally
207
223
* supplied subject.
@@ -210,10 +226,22 @@ protected function isGranted(mixed $attribute, mixed $subject = null): bool
210
226
*/
211
227
protected function denyAccessUnlessGranted (mixed $ attribute , mixed $ subject = null , string $ message = 'Access Denied. ' ): void
212
228
{
213
- if (!$ this ->isGranted ($ attribute , $ subject )) {
229
+ if (!$ this ->container ->has ('security.authorization_checker ' )) {
230
+ throw new \LogicException ('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle". ' );
231
+ }
232
+
233
+ $ checker = $ this ->container ->get ('security.authorization_checker ' );
234
+ if (method_exists ($ checker , 'getDecision ' )) {
235
+ $ decision = $ checker ->getDecision ($ attribute , $ subject );
236
+ } else {
237
+ $ decision = new AccessDecision ($ checker ->isGranted ($ attribute , $ subject ) ? VoterInterface::ACCESS_GRANTED : VoterInterface::ACCESS_DENIED );
238
+ }
239
+
240
+ if (!$ decision ->isGranted ()) {
214
241
$ exception = $ this ->createAccessDeniedException ($ message );
215
242
$ exception ->setAttributes ([$ attribute ]);
216
243
$ exception ->setSubject ($ subject );
244
+ $ exception ->setAccessDecision ($ decision );
217
245
218
246
throw $ exception ;
219
247
}
0 commit comments