1

I'm securing my Application with expression based Spring Security 3.x. I have the following service interface:

@PreAuthorize("hasRole('ROLE_ADMIN') or hasPermission(#employeeId, 'employee', 'isOwner')")
EmployeeData getById(Integer employeeId);

@PreAuthorize("hasRole('ROLE_ADMIN') or hasPermission(#employeeId, 'employee', 'isOwner')")
void update(Integer employeeId, EmployeeData employeedata);

My PermissionEvaluator looks as follows:

@Component
public class CustomPermissionEvaluator implements PermissionEvaluator {
    private Map<String, Permission> permissionMap = new HashMap<String, Permission>();

    public CustomPermissionEvaluator(Map<String, Permission> permissionMap) {
        this.permissionMap = permissionMap;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        throw new PermissionNotDefinedException("Permission not supported for loaded domain object by " + this.getClass().toString());
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        verifyPermissionIsDefined((String) permission);
        return permissionMap.get(permission).isAllowed(authentication, (Integer) targetId);
    }

    private void verifyPermissionIsDefined(String permissionKey) {
        if (!permissionMap.containsKey(permissionKey)) {
            throw new PermissionNotDefinedException("No permission with key '" + permissionKey + "' is defined in" + this.getClass().toString());
        }
    }
}

For the first service method (getById) this works as it's supposed to:

  • If the user has the ROLE_ADMIN, then he's allowed to get the data.
  • If the user wants to look up his own profile, he's allowed as well

But, for the second method, the update method, the application doesn't work. The targetId is always null, when it invokes the method hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission).

I can't figure out why. Any help would be appreciated.

jokr
  • 242
  • 3
  • 13

2 Answers2

3

Please check that parameter names match both in the service and in the implementation.

You can also check how MethodSecurityEvaluationContext.lookupVariable method is working with the debugger.

See similar question: spring security : Why can't we access Hibernate entitiy parameters in @PreAuthorize?

Community
  • 1
  • 1
Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91
  • That pointed me to the right direction. It was a typo in the implementation of the Service. Thanks a lot! – jokr Sep 07 '12 at 12:06
0

I had similar issue: targetDomainObject was null each hasPermission invocation.

The problem for me was that I had interface A with all auth annotations set (like @PreAuthorize and @PostAuthorize). It was implemented by abstract class B. And concrete class C was the actual service.

public class C extends B

This did not work.

public class C extends B implements A

But this worked fine.

From code logic those declarations were absolutely same. But Spring security confused the first
and worked normally with the second one.

Andrii Karaivanskyi
  • 1,942
  • 3
  • 19
  • 23