@@ -7,25 +7,31 @@ How to Use Voters to Check User Permissions
7
7
In Symfony2 you can check the permission to access data by using the
8
8
:doc: `ACL module </cookbook/security/acl >`, which is a bit overwhelming
9
9
for many applications. A much easier solution is to work with custom voters,
10
- which are like simple conditional statements. Voters can also be used to
11
- check for permission to a part or even of the whole application:
12
- ":doc: `/cookbook/security/voters `".
10
+ which are like simple conditional statements.
11
+
12
+ .. seealso ::
13
+
14
+ Voters can also be used in other ways, like, for example, blacklisting IP
15
+ addresses from the entire application: ":doc: `/cookbook/security/voters `".
13
16
14
17
.. tip ::
15
18
16
- Have a look at the
19
+ Take a look at the
17
20
:doc: `authorization </components/security/authorization >`
18
- chapter for a better understanding on voters.
21
+ chapter for an even deeper understanding on voters.
19
22
20
23
How Symfony Uses Voters
21
24
-----------------------
22
25
23
26
In order to use voters, you have to understand how Symfony works with them.
24
- In general, all registered custom voters will be called every time you ask
25
- Symfony about permissions (ACL). You can use one of three different
26
- approaches on how to handle the feedback from all voters: affirmative,
27
- consensus and unanimous. For more information have a look at
28
- ":ref: `the section about access decision managers <components-security-access-decision-manager >`".
27
+ All voters are called each time you use the ``isGranted() `` method on Symfony's
28
+ security context (i.e. the ``security.context `` service). Each decides if
29
+ the current user should have access to some resource.
30
+
31
+ Ultimately, Symfony uses one of three different approaches on what to do
32
+ with the feedback from all voters: affirmative, consensus and unanimous.
33
+
34
+ For more information take a look at ":ref: `the section about access decision managers <components-security-access-decision-manager >`".
29
35
30
36
The Voter Interface
31
37
-------------------
@@ -36,7 +42,7 @@ which has this structure:
36
42
37
43
.. include :: /cookbook/security/voter_interface.rst.inc
38
44
39
- In this example, it'll check if the user will have access to a specific
45
+ In this example, the voter will check if the user has access to a specific
40
46
object according to your custom conditions (e.g. they must be the owner of
41
47
the object). If the condition fails, you'll return
42
48
``VoterInterface::ACCESS_DENIED ``, otherwise you'll return
@@ -46,7 +52,8 @@ does not belong to this voter, it will return ``VoterInterface::ACCESS_ABSTAIN``
46
52
Creating the Custom Voter
47
53
-------------------------
48
54
49
- You could implement your Voter to check permission for the view and edit action like the following::
55
+ The goal is to create a voter that checks to see if a user has access to
56
+ view or edit a particular object. Here's an example implementation:
50
57
51
58
// src/Acme/DemoBundle/Security/Authorization/Voter/PostVoter.php
52
59
namespace Acme\D emoBundle\S ecurity\A uthorization\V oter;
@@ -87,7 +94,8 @@ You could implement your Voter to check permission for the view and edit action
87
94
}
88
95
89
96
// check if voter is used correct, only allow one attribute for a check
90
- if(1 !== count($attributes) || !is_string($attributes[0])) {
97
+ // this isn't a requirement, it's just the way we want our voter to work
98
+ if(1 !== count($attributes)) {
91
99
throw new InvalidArgumentException(
92
100
'Only one attribute is allowed for VIEW or EDIT'
93
101
);
@@ -104,14 +112,14 @@ You could implement your Voter to check permission for the view and edit action
104
112
return VoterInterface::ACCESS_ABSTAIN;
105
113
}
106
114
107
- // check if given user is instance of user interface
115
+ // make sure there is a user object (i.e. that the user is logged in)
108
116
if (!$user instanceof UserInterface) {
109
117
return VoterInterface::ACCESS_DENIED;
110
118
}
111
119
112
120
switch($attribute) {
113
121
case 'view':
114
- // the data object could have for e.g. a method isPrivate()
122
+ // the data object could have for example a method isPrivate()
115
123
// which checks the Boolean attribute $private
116
124
if (!$post->isPrivate()) {
117
125
return VoterInterface::ACCESS_GRANTED;
@@ -126,7 +134,6 @@ You could implement your Voter to check permission for the view and edit action
126
134
}
127
135
break;
128
136
}
129
-
130
137
}
131
138
}
132
139
@@ -137,7 +144,7 @@ Declaring the Voter as a Service
137
144
--------------------------------
138
145
139
146
To inject the voter into the security layer, you must declare it as a service
140
- and tag it as a ``security.voter ``:
147
+ and tag it with ``security.voter ``:
141
148
142
149
.. configuration-block ::
143
150
@@ -212,3 +219,5 @@ from the security context is called.
212
219
return new Response('<h1 >'.$post->getName().'</h1 >');
213
220
}
214
221
}
222
+
223
+ It's that easy!
0 commit comments