13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
15
*/
16
+
16
17
package org .springframework .security .acls ;
17
18
18
19
import java .lang .reflect .InvocationTargetException ;
24
25
import org .aopalliance .intercept .MethodInvocation ;
25
26
import org .apache .commons .logging .Log ;
26
27
import org .apache .commons .logging .LogFactory ;
28
+
27
29
import org .springframework .security .access .AuthorizationServiceException ;
28
30
import org .springframework .security .access .ConfigAttribute ;
29
31
import org .springframework .security .access .vote .AbstractAclVoter ;
39
41
import org .springframework .security .acls .model .SidRetrievalStrategy ;
40
42
import org .springframework .security .core .Authentication ;
41
43
import org .springframework .util .Assert ;
44
+ import org .springframework .util .ObjectUtils ;
42
45
import org .springframework .util .StringUtils ;
43
46
44
47
/**
92
95
* <p>
93
96
* All comparisons and prefixes are case sensitive.
94
97
*
95
- *
96
98
* @author Ben Alex
97
99
*/
98
100
public class AclEntryVoter extends AbstractAclVoter {
99
- // ~ Static fields/initializers
100
- // =====================================================================================
101
101
102
102
private static final Log logger = LogFactory .getLog (AclEntryVoter .class );
103
103
104
- // ~ Instance fields
105
- // ================================================================================================
104
+ private final AclService aclService ;
105
+
106
+ private final String processConfigAttribute ;
107
+
108
+ private final List <Permission > requirePermission ;
106
109
107
- private AclService aclService ;
108
110
private ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy = new ObjectIdentityRetrievalStrategyImpl ();
111
+
109
112
private SidRetrievalStrategy sidRetrievalStrategy = new SidRetrievalStrategyImpl ();
110
- private String internalMethod ;
111
- private String processConfigAttribute ;
112
- private List <Permission > requirePermission ;
113
113
114
- // ~ Constructors
115
- // ===================================================================================================
114
+ private String internalMethod ;
116
115
117
- public AclEntryVoter (AclService aclService , String processConfigAttribute ,
118
- Permission [] requirePermission ) {
116
+ public AclEntryVoter (AclService aclService , String processConfigAttribute , Permission [] requirePermission ) {
119
117
Assert .notNull (processConfigAttribute , "A processConfigAttribute is mandatory" );
120
118
Assert .notNull (aclService , "An AclService is mandatory" );
121
-
122
- if ((requirePermission == null ) || (requirePermission .length == 0 )) {
123
- throw new IllegalArgumentException (
124
- "One or more requirePermission entries is mandatory" );
125
- }
126
-
119
+ Assert .isTrue (!ObjectUtils .isEmpty (requirePermission ), "One or more requirePermission entries is mandatory" );
127
120
this .aclService = aclService ;
128
121
this .processConfigAttribute = processConfigAttribute ;
129
122
this .requirePermission = Arrays .asList (requirePermission );
130
123
}
131
124
132
- // ~ Methods
133
- // ========================================================================================================
134
-
135
125
/**
136
126
* Optionally specifies a method of the domain object that will be used to obtain a
137
127
* contained domain object. That contained domain object will be used for the ACL
138
128
* evaluation. This is useful if a domain object contains a parent that an ACL
139
129
* evaluation should be targeted for, instead of the child domain object (which
140
130
* perhaps is being created and as such does not yet have any ACL permissions)
141
- *
142
131
* @return <code>null</code> to use the domain object, or the name of a method (that
143
132
* requires no arguments) that should be invoked to obtain an <code>Object</code>
144
133
* which will be the domain object used for ACL evaluation
145
134
*/
146
135
protected String getInternalMethod () {
147
- return internalMethod ;
136
+ return this . internalMethod ;
148
137
}
149
138
150
139
public void setInternalMethod (String internalMethod ) {
151
140
this .internalMethod = internalMethod ;
152
141
}
153
142
154
143
protected String getProcessConfigAttribute () {
155
- return processConfigAttribute ;
144
+ return this . processConfigAttribute ;
156
145
}
157
146
158
- public void setObjectIdentityRetrievalStrategy (
159
- ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy ) {
160
- Assert .notNull (objectIdentityRetrievalStrategy ,
161
- "ObjectIdentityRetrievalStrategy required" );
147
+ public void setObjectIdentityRetrievalStrategy (ObjectIdentityRetrievalStrategy objectIdentityRetrievalStrategy ) {
148
+ Assert .notNull (objectIdentityRetrievalStrategy , "ObjectIdentityRetrievalStrategy required" );
162
149
this .objectIdentityRetrievalStrategy = objectIdentityRetrievalStrategy ;
163
150
}
164
151
@@ -167,108 +154,88 @@ public void setSidRetrievalStrategy(SidRetrievalStrategy sidRetrievalStrategy) {
167
154
this .sidRetrievalStrategy = sidRetrievalStrategy ;
168
155
}
169
156
157
+ @ Override
170
158
public boolean supports (ConfigAttribute attribute ) {
171
- return (attribute .getAttribute () != null )
172
- && attribute .getAttribute ().equals (getProcessConfigAttribute ());
159
+ return (attribute .getAttribute () != null ) && attribute .getAttribute ().equals (getProcessConfigAttribute ());
173
160
}
174
161
175
- public int vote (Authentication authentication , MethodInvocation object ,
176
- Collection <ConfigAttribute > attributes ) {
177
-
162
+ @ Override
163
+ public int vote (Authentication authentication , MethodInvocation object , Collection <ConfigAttribute > attributes ) {
178
164
for (ConfigAttribute attr : attributes ) {
179
-
180
- if (!this .supports (attr )) {
165
+ if (!supports (attr )) {
181
166
continue ;
182
167
}
168
+
183
169
// Need to make an access decision on this invocation
184
170
// Attempt to locate the domain object instance to process
185
171
Object domainObject = getDomainObjectInstance (object );
186
172
187
173
// If domain object is null, vote to abstain
188
174
if (domainObject == null ) {
189
- if (logger .isDebugEnabled ()) {
190
- logger .debug ("Voting to abstain - domainObject is null" );
191
- }
192
-
175
+ logger .debug ("Voting to abstain - domainObject is null" );
193
176
return ACCESS_ABSTAIN ;
194
177
}
195
178
196
179
// Evaluate if we are required to use an inner domain object
197
- if (StringUtils .hasText (internalMethod )) {
198
- try {
199
- Class <?> clazz = domainObject .getClass ();
200
- Method method = clazz .getMethod (internalMethod , new Class [0 ]);
201
- domainObject = method .invoke (domainObject );
202
- }
203
- catch (NoSuchMethodException nsme ) {
204
- throw new AuthorizationServiceException ("Object of class '"
205
- + domainObject .getClass ()
206
- + "' does not provide the requested internalMethod: "
207
- + internalMethod );
208
- }
209
- catch (IllegalAccessException iae ) {
210
- logger .debug ("IllegalAccessException" , iae );
211
-
212
- throw new AuthorizationServiceException (
213
- "Problem invoking internalMethod: " + internalMethod
214
- + " for object: " + domainObject );
215
- }
216
- catch (InvocationTargetException ite ) {
217
- logger .debug ("InvocationTargetException" , ite );
218
-
219
- throw new AuthorizationServiceException (
220
- "Problem invoking internalMethod: " + internalMethod
221
- + " for object: " + domainObject );
222
- }
180
+ if (StringUtils .hasText (this .internalMethod )) {
181
+ domainObject = invokeInternalMethod (domainObject );
223
182
}
224
183
225
184
// Obtain the OID applicable to the domain object
226
- ObjectIdentity objectIdentity = objectIdentityRetrievalStrategy
227
- .getObjectIdentity (domainObject );
185
+ ObjectIdentity objectIdentity = this .objectIdentityRetrievalStrategy .getObjectIdentity (domainObject );
228
186
229
187
// Obtain the SIDs applicable to the principal
230
- List <Sid > sids = sidRetrievalStrategy .getSids (authentication );
188
+ List <Sid > sids = this . sidRetrievalStrategy .getSids (authentication );
231
189
232
190
Acl acl ;
233
191
234
192
try {
235
193
// Lookup only ACLs for SIDs we're interested in
236
- acl = aclService .readAclById (objectIdentity , sids );
194
+ acl = this . aclService .readAclById (objectIdentity , sids );
237
195
}
238
- catch (NotFoundException nfe ) {
239
- if (logger .isDebugEnabled ()) {
240
- logger .debug ("Voting to deny access - no ACLs apply for this principal" );
241
- }
242
-
196
+ catch (NotFoundException ex ) {
197
+ logger .debug ("Voting to deny access - no ACLs apply for this principal" );
243
198
return ACCESS_DENIED ;
244
199
}
245
200
246
201
try {
247
- if (acl .isGranted (requirePermission , sids , false )) {
248
- if (logger .isDebugEnabled ()) {
249
- logger .debug ("Voting to grant access" );
250
- }
251
-
202
+ if (acl .isGranted (this .requirePermission , sids , false )) {
203
+ logger .debug ("Voting to grant access" );
252
204
return ACCESS_GRANTED ;
253
205
}
254
- else {
255
- if (logger .isDebugEnabled ()) {
256
- logger .debug ("Voting to deny access - ACLs returned, but insufficient permissions for this principal" );
257
- }
258
-
259
- return ACCESS_DENIED ;
260
- }
206
+ logger .debug ("Voting to deny access - ACLs returned, but insufficient permissions for this principal" );
207
+ return ACCESS_DENIED ;
261
208
}
262
- catch (NotFoundException nfe ) {
263
- if (logger .isDebugEnabled ()) {
264
- logger .debug ("Voting to deny access - no ACLs apply for this principal" );
265
- }
266
-
209
+ catch (NotFoundException ex ) {
210
+ logger .debug ("Voting to deny access - no ACLs apply for this principal" );
267
211
return ACCESS_DENIED ;
268
212
}
269
213
}
270
214
271
215
// No configuration attribute matched, so abstain
272
216
return ACCESS_ABSTAIN ;
273
217
}
218
+
219
+ private Object invokeInternalMethod (Object domainObject ) {
220
+ try {
221
+ Class <?> domainObjectType = domainObject .getClass ();
222
+ Method method = domainObjectType .getMethod (this .internalMethod , new Class [0 ]);
223
+ return method .invoke (domainObject );
224
+ }
225
+ catch (NoSuchMethodException ex ) {
226
+ throw new AuthorizationServiceException ("Object of class '" + domainObject .getClass ()
227
+ + "' does not provide the requested internalMethod: " + this .internalMethod );
228
+ }
229
+ catch (IllegalAccessException ex ) {
230
+ logger .debug ("IllegalAccessException" , ex );
231
+ throw new AuthorizationServiceException (
232
+ "Problem invoking internalMethod: " + this .internalMethod + " for object: " + domainObject );
233
+ }
234
+ catch (InvocationTargetException ex ) {
235
+ logger .debug ("InvocationTargetException" , ex );
236
+ throw new AuthorizationServiceException (
237
+ "Problem invoking internalMethod: " + this .internalMethod + " for object: " + domainObject );
238
+ }
239
+ }
240
+
274
241
}
0 commit comments