Reputation: 383
I am using Spring Security (version 4.0.3.RELEASE) with ACL's-level permissions - I am trying to apply PreAuthorize ACL's permissions to a delete method in my CrudRepository interface using the @PreAuthorize annotation with a call to the SPEL method "hasPermission" (see below). The hasPermission is referencing the input argument using the hash notation that I've seen in several forums, tutorials, and reference docs, but the input argument (the object that I want to delete) is not being picked up by the SPEL parser or supporting framework. So, in other words, I want to delete the object named "apiKey" which is the input argument below. I reference it in the SPEL annotation using "#apiKey" but when I put a breakpoint in the method org.springframework.security.acls.AclPermissionEvaluator.hasPermission(...) the "domainObject" input argument is NULL.
I'm pretty new to Spring and ACL's so I must be doing something fundamentally wrong. I've tried putting breakpoints in the Spring SPEL Parser and walking through during runtime, but I can't find the piece of the code that resolves the reflective arguments based on the SPEL token. I think it's "hidden" in a native method or something.
I've also tried fiddling with the SPEL reference syntax. Nothing else seems to parse correctly, so I think the "#argument_name" is the correct syntax - it's just that SPEL fails to dereference the argument object.
My CrudRepository code w/ the object reference ("#apiKey") that isn't working:
public interface ApiKeyRepository extends CrudRepository<ApiKey, Long> {
@Override
@PreAuthorize("hasPermission(#apiKey, 'DELETE')")
void delete(ApiKey apiKey);
}
Spring Security code which should be receiving my apiKey object, but instead is getting a NULL value for the domainObject:
public class AclPermissionEvaluator implements PermissionEvaluator {
...
public boolean hasPermission(Authentication authentication, Object domainObject, Object permission) {
if (domainObject == null) {
return false; //<== This is where I'm getting access denied from
}
...
Any ideas as to why SPEL is unable to properly reference by apiKey input argument? Thanks in advance.
Upvotes: 0
Views: 1080
Reputation: 383
I figured out my problem thanks to THIS POST which referenced THIS DOC:
Apparently you can't make object references to method arguments in an interface without using the @Param annotation on the arg. So, here is my updated code that fixes the issue:
public interface ApiKeyRepository extends CrudRepository<ApiKey, Long> {
@Override
@PreAuthorize("hasPermission(#apiKey, 'DELETE')")
void delete(@Param("apiKey") ApiKey apiKey);
}
Upvotes: 0