【问题标题】:Is there a good design pattern for checking permissions when running a method?运行方法时检查权限是否有良好的设计模式?
【发布时间】:2013-12-07 15:30:09
【问题描述】:

我正在寻找一种设计模式或一种方法来整理我的代码。这是在给定主题的安全和检查权限的上下文中。 这是一个简化的例子:

public Pizza bakePizza() throws UnauthorizedException{
if (subject.isPermitted("BAKE_PIZZA")){
        return new Pizza();
    } else {
        throw new UnauthorizedException();
    }
}

有没有办法让它更干净一点,因为当我有很多不同类型的方法时,这会变得很混乱。

【问题讨论】:

  • 如果可以选择面向方面的编程,方面可能会清理代码。看看 Shiro。
  • @Sotirios 实际上,我正在使用 Shiro,并且主题是 Shiro 对象 :) 但是要使 Shiro 的注释起作用,您必须使用 AOP,我对 AOP 完全没有经验,这个项目不是尝试新的编程风格的权利。这就是为什么我正在寻找另一种做事方式的原因 :) 不过还是感谢您的建议!
  • 可以在JVM加载的时候通过修改类文件来添加校验码。 Javassist可以做到这一点

标签: java design-patterns permissions


【解决方案1】:

我认为使用decorator pattern 之类的东西来拆分安全约束和业务逻辑将是一个好的开始。

这样的事情怎么样:

// an interface defines the operations
public interface PizzaService {
  Pizza bakePizza();
}

// standard implementation that contains the business logic
public class PizzaServiceImpl implements PizzaService {
  @Override
  public Pizza bakePizza() {
    // implementation ..
  }
}

// implementation with security constraints that delegates to the real implementation
public class SecurePizzaService implements PizzaService {
  private PizzaService service;
  public SecurePizzaService(PizzaService service) {
    this.service = service;
  }

  @Override
  public Pizza bakePizza() {
    if (!subject.isPermitted("BAKE_PIZZA")){
      throw new UnauthorizedException();
    }
    service.bakePizza()
  }
}

// usage
PizzaService pizzaService = new SecurePizzaService(new PizzaServiceImpl());
...
Pizza pizza = pizzaService.bakePizza();

这样您就可以在不触及业务逻辑的情况下更改安全约束,反之亦然。

如果你有很多这样的情况,你应该看看 AOPAspectJ 这样的框架

【讨论】:

  • 将此标记为答案,因为我必须同意必须将安全约束和业务逻辑分开。有一天我可能不得不研究 AOP :)
【解决方案2】:

一种方法是将检查逻辑移动到一个方法中,该方法会抛出并提前结束调用方法的程序流程。

public Pizza bakePizza() throws UnauthorizedException{
    ensurePermission("BAKE_PIZZA");
    return new Pizza();
}

private void ensurePermission(String permission) throws UnauthorizedException {
    if (!subject.isPermitted(permission))
        throw new UnauthorizedException();
}

【讨论】:

  • 并使其成为运行时异常(如 shiro)。
  • 取决于您对该异常的意图。如果此类的客户端可以预期在以预期方式使用该类时没有异常,则可以将其设为运行时异常。如果权限可以无声地更改并且客户必须预料到他无法控制的事情会出错,我会将其保留为已检查异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 1970-01-01
  • 2014-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多