Search code examples
javaspringsecurityspring-securityspring-security-acl

How to interpret hasPermission in spring security?


I am new to spring security. How do I interpret this?

 @PreAuthorize("hasPermission(null, 'opetussuunnitelma', 'LUONTI')")
     OpetussuunnitelmaDto addOpetussuunnitelma(OpetussuunnitelmaDto opetussuunnitelmaDto);

Which method from the permission evaluator would get called? I think the one with three parameters would get called in this case. It is checking if the current user has the 'LUONTI' permission on the target of type - 'opetussuunnitelma' . Am I right? Can't we just not include "null" and pass only two parameters. I read that the first argument ( the Authentication object) is not supplied.

+public class PermissionEvaluator implements org.springframework.security.access.PermissionEvaluator {
+
+    @Override
+    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
+        LOG.error(" *** ei toteutettu *** ");
+        return true;
+    }
+
+    @Override
+    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
+        LOG.error(" *** ei toteutettu *** ");
+        return true;
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(PermissionEvaluator.class);
+}

Solution

  • Which method from the permission evaluator would get called?

    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) 
    

    Would get called.

    I read that the first argument ( the Authentication object) is not supplied.

    It's not explicitly supplied in your annotation, but implicitly supplied by Spring. Your annotation should just read

    @PreAuthorize("hasPermission(#opetussuunnitelmaDto, 'LUONTI')")
    

    Ideally I would check if they're even authenticated before performing the authorization.

    @PreAuthorize("isAuthenticated() and hasPermission(#opetussuunnitelmaDto, 'LUONTI')")
    

    Update to your comment

    Basically you can either call the PermissionEvaluator with either:

    hasPermission('#targetDomainObject', 'permission')    // method1
    hasPermission('targetId', 'targetType', 'permission') // method2
    

    Authentication will always be supplied by Spring. In your case, you are calling hasPermission the following way

    hasPermission(null, 'opetussuunnitelma', 'LUONTI')")

    which would match method2, but passing in a null id doesn't make sense, what entity are you going to target the permission check on? Based on your method that you're applying the @PreAuthorize on,

    OpetussuunnitelmaDto addOpetussuunnitelma(OpetussuunnitelmaDto opetussuunnitelmaDto);

    it may make more sense to call method1 since you seem to have something that resembles an target domain object.