Design Patterns: Security Assessment for Multiple Modules

This question is more about design patterns, dependency injection, than Spring. Security itself, I expect people without special Spring Security knowledge to understand this question.

In Introduction to Spring Security 3 / 3.1 , to check if the current user is allowed to perform an action on the target, Mike Wiesner implements a PermissionEvaluator . This bean is connected to the security configuration and is called in the method annotation before the action on the target continues.

The goal is to check whether the user is allowed or not to take any action for a particular object. It shows the following code (without explicit checks, for brevity, I suppose):

 public class MyPermissionEvaluator implements PermissionEvaluator { @Override public boolean hasPermission(Authentication auth, Object target, Object perm) { if (target instanceof MyRequest) { //first class of target object... MyRequest req = (MyRequest) target; if (perm.equals("cancel")) { //action we wish to perform on the object return auth.getName().equals(req.getEmployee()); } else if (perm.equals("list")) { //another action return !hr.getEmployee().equals("rod") || auth.getName.equals("rod"); } } else if (target instanceof ...) { //second class of target object... ... } throw new UnsupportedOperationException("hasPermission not supported"); } } 

He mentions that this implementation method is only suitable for small applications, but in practice it should be divided into several methods or classes. That was exactly what I was thinking:

  • in a multi-module application, several modules may not know about each other
  • we must apply the Open-Close principle (when adding a new module)

My question is: how would you solve the problem?

My job would be to have a global permissions evaluator and one permissions evaluator for each class of the target.

 public interface TargetPermissionEvaluator extends PermissionEvaluator { Class getTargetClass(); //so we know for which target class we can use it } public class MyGlobalPermissionEvaluator implements PermissionEvaluator { @Autowired private List<TargetPermissionEvaluator> evaluators; @Override public boolean hasPermission(Authentication auth, Object target, Object perm) { for (MyEvaluator evaluator : evaluators) { if (target instanceof evaluator.getTargetClass()) { return evaluator.hasPermission(auth, target, perm); } } throw new UnsupportedOperationException("hasPermission not supported"); } } 

The list of evaluators will be defined in the Spring XML configuration. What do you think? Is this a good way or do you have any ideas? Am I missing another suitable design template?

+4
source share
2 answers

Firstly, there is a problem with using instanceof versus class. You really want to use Class # isAssignableFrom in this case (no pun intended). However, this does not really matter for your question.

In your initial question, I really like using structures like Google Guava Predicate . It contains one likes method (T), where T is a generic type and returns a boolean value.

Create a new interface, for example

 interface PollablePermissionEvaulator<T> extends PermissionEvaluator, Predicate<T> {} 

Then you can get your view request (T) on each, and if so, call the nested hasPermission () call.

0
source

I think your proposed design is good and well integrated into Spring's security design. After all, there are at least two other places where this is done as follows:

  • default AfterInvocationProvider delegate AfterInvocationProvider s
  • AccessDecisionManager default AccessDecisionVoter s

In both cases, the delegated object interface reflects the delegate interface. Although this is easy to implement, it makes me wonder why they did not implement something similar for the PermissionEvaluator .

0
source

Source: https://habr.com/ru/post/1387384/


All Articles