【问题标题】:Design Patterns: evaluating security across multiple modules设计模式:跨多个模块评估安全性
【发布时间】:2012-01-25 07:18:01
【问题描述】:

这个问题更多的是关于设计模式、依赖注入而不是 Spring Security 本身,我希望没有特定 Spring Security 知识的人能够理解这个问题。

Introduction to Spring Security 3/3.1 中,为了验证当前用户是否有权对目标对象执行操作,Mike Wiesner 实现了PermissionEvaluator。在对目标对象执行操作之前,此 bean 与安全配置相关联并在方法注释上被调用。

目的是检查用户是否被授权对特定对象执行特定操作。他展示了以下代码(为了简洁,我想没有空检查):

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");
    }

}

他提到这种实现方式,只适用于小型应用程序,但在实践中,它应该拆分为多个方法或类。这正是我的想法:

  • 在多模块应用程序中,多个模块可能不知道彼此
  • 我们应该应用开闭原则(添加新模块时)

我的问题是,您将如何解决这个问题?

我的想法是为每个目标对象类设置一个全局权限评估器和一个权限评估器。

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");
    }

}

评估者列表,将在 Spring XML 配置中定义。你怎么看?是一个好方法还是你有更好的想法?我错过了一些更合适的设计模式吗?

【问题讨论】:

    标签: spring design-patterns dependency-injection spring-security


    【解决方案1】:

    首先,对 Class 使用 instanceof 存在问题。您真的想在这种情况下使用 Class#isAssignableFrom (不是双关语)。但是,这并不是您问题的核心。

    对于您最初的问题,我真的很喜欢使用像 Google Guava 的 Predicate 这样的结构。它包含一个方法 likes(T),其中 T 是泛型类型,并返回一个布尔值。

    新建一个界面如

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

    然后,您可以对每个外观查询 likes(T),如果是,则调用嵌套的 hasPermission() 调用。

    【讨论】:

      【解决方案2】:

      我认为您提出的设计非常好,并且很好地集成到了 Spring Security 的设计中。毕竟,至少还有另外两个地方是这样做的:

      • 默认的AfterInvocationManager 代表AfterInvocationProviders
      • 默认的AccessDecisionManager 代表AccessDecisionVoters

      在这两种情况下,委托对象的接口都反映了委托者的接口。虽然实现起来很容易,但这让我想知道为什么他们没有为PermissionEvaluator 实现类似的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        相关资源
        最近更新 更多