应用程序中应在何处处理辅助数据(例如授权/身份)

时间:2009-03-24 10:32:25

标签: architecture

创建网站时,我的模式通常如下:

  1. 控制器(应用程序服务)
  2. 服务(域名服务,基础设施服务)
  3. 存储库
  4. 控制器与域服务或基础结构服务进行通信,域服务可能与存储库通信,基础结构服务将包含smtp等内容。

    目前我将身份作为基础设施服务处理,如果基础设施服务或域服务需要找出“调用者是谁”,它将在构建时请求身份服务,身份服务将具有识别身份的方法/属性调用者,这样我就有了一个HttpIdentityService,它通过会话/ cookie数据来确定身份。

    但是我对如何处理服务调用的结果感到有点困惑,例如..我可能有一个服务'ArticleService',它有一个方法'CreateComment',只需要一个字符串注释文本和一个标识符对于目标文章。

    我的应用程序服务(控制器),可能会这样调用此服务:

    public ActionResult AddComment(int articleId)
    {
      string commentText = ...;
      articleService.CreateComment(articleId, commentText);
      ...
    }
    

    但是,如果当前身份未获得授权,或者未通过ArticleService检查的策略(例如可能每30秒发表一次评论),抛出并捕获来自此类服务调用的异常,则此方法可能会失败似乎非常错误,因为我的调用代码无法检查它是否可以成功地实际调用此操作(bar致命应用程序异常)..

    所以最初我开始让服务返回'结果',结果将是唯一可识别的,因此调用者会知道评论是否确实发出(另外我会在结果中返回注释实体),结果还会识别“无法发布,因为用户未经过身份验证”,或“无法发布指定的冷却期间未被尊重”等事情(我实际上并没有返回字符串,但您明白了)。

    我的理由是应用程序服务不应该控制是否应该调用一个动作,想象一下,我将所有用户身份检查和所有内容都移出域服务并进入应用程序服务,我d拥有大量复制代码,并使应用程序服务完全胜过可能发生的事情。

    我想我的问题基本上是,鉴于域名,基础设施服务将执行额外的政策,通知调用代码的最佳方式是行动成功与否,以及原因。

    先谢谢,史蒂夫。

2 个答案:

答案 0 :(得分:0)

在类似的情况下,我使用方面来检查方法调用是否被授权,如果不是,则抛出AuthorizationException。截取方法调用,从会话中检索用户信息,检查角色/权限集并最终抛出异常。这样,callig代码可以处理异常,为用户提供有意义的反馈,记录事件等等。

答案 1 :(得分:0)

使用面向方面编程来检查权限。如果这些失败引发异常。

在实际调用Action之前,请检查是否有必要的权限。如果不取消行动。

如果某个Action有一些需要特殊权限的可选任务,请在执行可选任务之前检查必要的权限,并按照您的业务规则的要求做出反应。如果您忘记进行检查,您的aop代码将执行检查并抛出异常,这是可以的,因为它确实应该永远不会出现。

编辑:关于如何传达不允许操作的原因的评论中提出的问题:我使用对象。如果可能的原因集在编译时是固定的,请使用枚举。如果不只是创建一个小类,它可以包含所有相关的值。