Spring Security ACL - create permission

跟風遠走 提交于 2020-01-14 02:59:05

问题


I can use Spring Security ACL with permissions on entity but I'd like to know how to test if a user has access to the "create" (bit 2) permission on a class.

Something like :

aclPermissionEvaluator.hasPermission(auth, clazz, "create")

Could someone help me?

Thanks in advance


回答1:


You can use Spring's SpEL annotations, e.g. @PreAuthorize, and override the hasPermission method of the PermissionEvaluator interface. If you're using bitwise permission masks, and the user's permissions (as an int) evaluate to '15' (1111), and the required permissions for the object are '6' (0110), you can do something like the following:

public boolean hasPermission(Authentication auth, Object targetObject, Object requiredPermissions) {
    int permissionMask = MyUserClass.getMask();
    int permissionsRequired = Integer.valueOf(requiredPermissions.toString());
    return ((permissionMask | requiredPermissions) == permissionMask);
}

This will return true whenever the bits active in the object's permissions mask are active on the user's permissions. Then, you'd need to declare this custom permission evaluator in your security.xml file:

<security:global-method-security pre-post-annotations="enabled">
    <security:expression-handler ref="expressionHandler"/>
</security:global-method-security>

<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="permissionEvaluator" ref="permissionEvaluator"/>
</bean>

<bean id="permissionEvaluator" class="my.project.package.CustomPermissionEvaluator"/>

Now, whenever you call hasPermission(), your custom evaluator will handle the request. Obviously, you can use whatever logic you like to evaluate permissions -- just make sure the return type is boolean, and the parameters to be passed match what you're sending (or evaluating against; be careful of format exceptions).

Note that your custom parameter must be passed as an Object to override hasPermission(); you could also overload the method by changing the signature to handle whatever parameter type you prefer (e.g. String or int), and the compiler should select the most specific signature. Since you're implementing the PermissionEvaluator interface, however, you'll have to include the given signature (Authentication, Object, Object) anyway, so unless you have some specific need to write an overload method, you may as well just override.




回答2:


I have exactly the same problem, and sadly, there is no "out of the box" solutions.

One way to do it, if your domain model allow for it, is to add the create permission to the parent object you want to create

For example, imagine you want to create an user for a client. You can add the create permission to the client for the user allowed to create user for this specific client. That the path I choose.

If your domain object doesn't allow for that, the only way I found to do it is:

  • to create a new table acl_class_entry, wich list acl_entry equivalent but linked to an acl_class and not to an acl_object_identity
  • Then you create your own permission evaluator, surcharging the method boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) to check the permission against the acl_class_entry if target_id is null. This will allow you to check permission against a class by using the SPel expression hasPermission(nulll, 'className', 'permission')
  • Of course, you will also need to create your own version of AclService for creating such permission.


来源:https://stackoverflow.com/questions/16188277/spring-security-acl-create-permission

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!