@@ -63,43 +63,72 @@ Setup: Checking for Access in a Controller
63
63
64
64
Suppose you have a ``Post `` object and you need to decide whether or not the current
65
65
user can *edit * or *view * the object. In your controller, you'll check access with
66
- code like this::
66
+ code like this:
67
67
68
- // src/Controller/PostCo
8000
ntroller.php
68
+ .. configuration-block ::
69
69
70
- // ...
71
- class PostController extends AbstractController
72
- {
73
- #[Route('/posts/{id}', name: 'post_show')]
74
- public function show($id): Response
75
- {
76
- // get a Post object - e.g. query for it
77
- $post = ...;
70
+ .. code-block :: php-attributes
78
71
72
+ // src/Controller/PostController.php
73
+
74
+ // ...
75
+ use Symfony\Component\Security\Http\Attribute\IsGranted;
76
+
77
+ class PostController extends AbstractController
78
+ {
79
+ #[Route('/posts/{id}', name: 'post_show')]
79
80
// check for "view" access: calls all voters
80
- $this->denyAccessUnlessGranted('view', $post);
81
+ #[IsGranted('show', 'post')]
82
+ public function show(Post $post): Response
83
+ {
84
+ // ...
85
+ }
81
86
82
- // ...
87
+ #[Route('/posts/{id}/edit', name: 'post_edit')]
88
+ // check for "edit" access: calls all voters
89
+ #[IsGranted('edit', 'post')]
90
+ public function edit(Post $post): Response
91
+ {
92
+ // ...
93
+ }
83
94
}
84
95
85
- #[Route('/posts/{id}/edit', name: 'post_edit')]
86
- public function edit($id): Response
96
+ .. code-block :: php
97
+
98
+ // src/Controller/PostController.php
99
+
100
+ // ...
101
+
102
+ class PostController extends AbstractController
87
103
{
88
- // get a Post object - e.g. query for it
89
- $post = ...;
104
+ #[Route('/posts/{id}', name: 'post_show')]
105
+ public function show(Post $post): Response
106
+ {
107
+ // check for "view" access: calls all voters
108
+ $this->denyAccessUnlessGranted('view', $post);
90
109
91
- // check for "edit" access: calls all voters
92
- $this->denyAccessUnlessGranted('edit', $post);
110
+ // ...
111
+ }
93
112
94
- // ...
113
+ #[Route('/posts/{id}/edit', name: 'post_edit')]
114
+ public function edit(Post $post): Response
115
+ {
116
+ // check for "edit" access: calls all voters
117
+ $this->denyAccessUnlessGranted('edit', $post);
118
+
119
+ // ...
120
+ }
95
121
}
96
- }
97
122
98
- The ``denyAccessUnlessGranted() `` method (and also the ``isGranted() `` method)
123
+ The ``#[IsGranted()] `` attribute or `` denyAccessUnlessGranted() `` method (and also the ``isGranted() `` method)
99
124
calls out to the "voter" system. Right now, no voters will vote on whether or not
100
125
the user can "view" or "edit" a ``Post ``. But you can create your *own * voter that
101
126
decides this using whatever logic you want.
102
127
128
+ .. versionadded :: 6.2
129
+
130
+ The ``#[IsGranted()] `` attribute was introduced in Symfony 6.2.
131
+
103
132
Creating the custom Voter
104
133
-------------------------
105
134
@@ -418,3 +447,35 @@ must implement the :class:`Symfony\\Component\\Security\\Core\\Authorization\\Ac
418
447
// ...
419
448
;
420
449
};
450
+
451
+ .. _security-voters-change-message-and-status-code :
452
+
453
+ Changing the message and status code returned
454
+ ---------------------------------------------
455
+
456
+ By default, the ``#[IsGranted] `` attribute will throw a
457
+ :class: `Symfony\\ Component\\ Security\\ Core\\ Exception\\ AccessDeniedException `
458
+ and return an http **403 ** status code with **Access Denied ** as message.
459
+
460
+ However, you can change this behavior by specifying the message and status code returned::
461
+
462
+ // src/Controller/PostController.php
463
+
464
+ // ...
465
+ use Symfony\Component\Security\Http\Attribute\IsGranted;
466
+
467
+ class PostController extends AbstractController
468
+ {
469
+ #[Route('/posts/{id}', name: 'post_show')]
470
+ #[IsGranted('show', 'post', 'Post not found', 404)]
471
+ public function show(Post $post): Response
472
+ {
473
+ // ...
67FD
474
+ }
475
+ }
476
+
477
+ .. tip ::
478
+
479
+ If the status code is different than 403, an
480
+ :class: `Symfony\\ Component\\ HttpKernel\\ Exception\\ HttpException `
481
+ will be thrown instead.
0 commit comments