5

大きな木が人がいる複雑なシステムがあるとします。単純な考えは従業員/マネージャーの関係であり、多くの従業員が1人のマネージャーに報告します。現在、マネージャーに加えて、マネージャーに代わって行動することができるサポートスタッフがマネージャーの従業員を操作することができます。

CQRSシステムでは、アクションの呼び出し元がサポートスタッフである、「従業員の編集」という架空のアクションのメッセージをどのようにモデル化しますか。このアクションは、マネージャーのセキュリティ関係に従ってスタッフが自分の領域の従業員に作用している場合にのみ成功します。

これのセキュリティを検証するには、データベースにクエリを実行して、変更される人物が実際にそのマネージャーの従業員チェーン内にいることを検証する必要があります。

このクエリはどこで発生しますか?「従業員の編集」メッセージを発信する前に?

メッセージを発信する前にデータが事前に検証されている場合、結果整合性のあるシステムでは、「従業員の編集」メッセージが処理される前に、「従業員の編集」アクションを完了するためのユーザーの権限を削除する別のアクションが発生したと想定します。 。コマンドハンドラーがそのメッセージのセキュリティ上の懸念を検証しない場合、ユーザーがメッセージを実行する権限を失っても、メッセージは引き続き成功します。

これは、UI検証やサーバー側検証と同様に、両面検証が最善の行動であることを意味しているように思われます。ただし、その検証を完了する方法は、CQRSの主要な信条に違反しているように見えます。

CQRSを使用するときに、これらおよび他の同様の横断的関心事に対処する必要がある場合、どのアプローチが最適ですか?

4

2 に答える 2

5

まず、一般的な答えはないという@Yahiaのコメントに同意します。そうは言っても、これが私がそれにアプローチする方法です。

そもそも、私はおそらく二重の検証を行うでしょう-リクエストが最初に受信されたときにコントローラーで1回、コマンドを処理しているときにドメインで後で。一部の人はそれに同意しないかもしれませんが、コマンドが発行されないようにし、コマンドを実行してエラー通知を警告するために結果整合性に依存するのではなく、コマンドを実行する権限がないことをユーザーにすぐに知らせたいと思いますアクションを実行できなかったという事実の後のユーザー。

したがって、擬似コードの観点から、従業員を編集するための私のアプローチは次のとおりです。

コントローラ

[HttpPost]
ActionResult Edit(Employee emp){

  //get employee org information from _employeeRepository
  //validate if _loggedInUserID is able to edit emp.ID

  if(isValid) {
    //construct command
    _commandService.EnqueueCommand(new EditEmployee(emp.ID, emp.Name, emp.Salary));
  } else {
    return View("PermissionError");
  }

  return Redirect("EmployeeProperties");
}

したがって、ここでコマンドサービスがコマンドを取得し、ドメイン内の適切なAR(Employee)にルーティングします。

従業員ドメイン

protected void EditEmployee(userID, employeeID, employeeName, salary){
  //get employee org information from _employeeRepository
  //validate if userID is able to edit employeeID

  if(isValid) {
    //apply event
    ApplyEvent(new EmployeeEdited(userID, employeeID, employeeName, salary));
  }
}

したがって、コントローラーとドメインの両方に同じセキュリティチェックを適用します。私はこれをおそらくカプセル化されたメソッドとして持っているでしょう(まあ、おそらく私がリポジトリに渡すカプセル化された基準クラス)。

したがって、これがこのシナリオへのアプローチに役立つことを願っています。質問があれば教えてください。答えを詳しく説明します。

これがお役に立てば幸いです。幸運を!

于 2012-01-26T01:50:37.400 に答える
4

おそらく、このドメインでは CQRS を完全にスキップして、Web 層が DB 層と直接通信するようにします (メッセージングなし)。単純なオプティミスティック コンカレンシーは、発生するいくつかの競合を処理する必要があります。

于 2012-01-26T11:59:10.650 に答える