【问题标题】:Service layer design, where to check permissions, and how to handle UI layer服务层设计,在哪里检查权限,以及如何处理UI层
【发布时间】:2012-05-05 18:55:12
【问题描述】:
@RequestMapping(value = "/products/create", method = RequestMethod.POST)
public ModelAndView create(@Valid ProductForm productForm, BindingResult bindingResult,
                           HttpServletRequest request) {
    SessionContext sessionContext = (SessionContext) request.getAttribute("sessionContext");

    ModelAndView mav = new ModelAndView("products/new");
    mav.addObject("errors", bindingResult.getAllErrors());
    mav.addObject("productForm", productForm);

    int newProductId = -1;

    if (!bindingResult.hasErrors()) {

        List<Product> products = productService.find...(...);
        if (products != null...) {
            bindingResult.addError(new ObjectError("Products", "..."));
        }

        // only try and create if no errors so far
        if (!bindingResult.hasErrors()) {
            newProductId = productService.create(..., productForm);
            if (newProductId <= 0) {
                bindingResult.addError(new ObjectError("Products", "..."));
            }
        }
    }

    if (bindingResult.hasErrors()) {
        return mav;
    }


    return new ModelAndView("redirect:/products/show/" + newProductId);
}

所以上面描述了事物的 UI 方面(使用 Spring MVC)。

现在,我应该如何设计服务层,所以在这个例子中 ProductServiceImpl 有一个 create 方法,它将创建产品并将其保存在数据库中。

我必须根据用户角色等检查权限。

我可以在 UI 层首先检查用户是否有权创建产品:

if(permissionService.hasPermission(.....)) {
  newProductId = productService.create(....)
}

但这将这个逻辑与UI层联系在一起,我认为它应该在create方法本身中:

public class ProductServiceImpl implements ProductService {

  @Autowired
  PermissionService permissionService;

  ..

  @Override
  public int create(...., final ProductForm productForm) {

     boolean canCreateProduct = productService.hasPermissions(.....);

     if(canCreateProduct) {
       Product product = ..... (productForm);
       productDao.save(product);
       return product.getId();
     }   
  }
}

但我不明白的问题是,如果我把权限检查放在 ProductServiceImpl.create 方法中,我如何向 UI 层报告你没有权限这样做?

如果你说我应该抛出一个异常,那么我的 UI 层看起来很混乱,因为根据我需要执行的各种检查,我将有很多异常需要处理。

我应该在这里做什么?

【问题讨论】:

    标签: java oop spring-mvc soa


    【解决方案1】:

    这样的权限检查应该/可以通过 AOP 来完成,通过像 CDI's interceptors 这样的机制。 Spring 具有用于相同目的的方法拦截器(请参阅AOP in Spring)。在权限不足的情况下抛出异常是正确的做法。

    也就是说,我看到了您的问题,但常见的解决方案非常简单:您的 UI 在登录后接收其用户的权限(或通过一些 UserService 检索它们)。使用此信息,您可以调整在 UI 中公开的操作。在您的示例中,如果不允许用户创建新产品,则不会显示创建新产品的操作。

    您可能仍希望处理异常(假设同时在服务器端修改了用户权限)并在发生时显示错误。

    【讨论】:

    • 我不是很精通AOP,而且这个应用程序在这些检查方面相当轻,所以我宁愿把它放在服务层或UI等中。
    • 正如您在问题中所建议的那样,将检查放入 create 方法并在检查失败时抛出异常是 imo 的最佳选择。
    • 好的,这开始有意义了,我首先执行权限检查以防止页面加载,但是如果他们尝试绕过,如果我抛出异常就可以了,因为它将是更罕见的情况吧?
    • 是的,我就是这个意思!
    猜你喜欢
    • 2016-03-03
    • 2011-07-24
    • 2012-01-29
    • 1970-01-01
    • 2010-12-14
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    相关资源
    最近更新 更多