1. ホーム
  2. security

ドメイン駆動型設計におけるアクセス制御

2023-10-12 21:41:04

質問

DDDとアクセス制御について読んだのですが、以下の2つの意見に矛盾があるように感じました。

  • セキュリティに関する懸念は、ドメインの外部で処理されるべきである。
  • "アクセス制御の要件はドメイン固有である"

これについてのベストプラクティスを探しています。つまり、ドメイン駆動設計によるアクセス制御ロジックをどこに配置し、どのように実装すればよいのでしょうか。

(具体的にはDDD + CQRS + ESで。)

ビジネスロジックに近いところにすべきだと思います。例えば、ユーザーストーリーはこんな感じでしょうか。

ユーザーは、ユーザー名、趣味のリスト、履歴書などを送信することで、プロフィールを編集することができます...。

ユーザーストーリーに基づき、例えばドメインモデルやサービスを実装します。

UserService
    editProfile(EditUserProfileCommand command)
        User user = userRepository.getOneById(command.id)
        user.changeName(command.name)
        user.changeHobbies(command.hobbies)
        user.changeCV(command.cv)

UserRepository
    User getOneById(id)

User
    changeName(String name)
    changeHobbies(String[] hobbies)
    changeCV(String cv)

これはこれでいいのですが、どこが HIS profile の部分はどうなっているのでしょうか?

これは明らかに属性ベースのアクセス制御で、次のようなルールを書けばよいからです。

deny all, but if subject.id = resource.owner.id then grant access

しかし、このルールはどこで、どのように実行すればよいのでしょうか?

どのように解決するのか?

<ブロッククオート

では、アクセス制御のロジックはどこに置けばいいのでしょうか?

これによると https://softwareengineering.stackexchange.com/a/71883/65755 の呼び出しの直前が、ポリシーの実施点であるべきです。 UserService.editProfile() .

私は同じ結論に達しました: 複数のUIによってコードの繰り返しが発生するため、UIにあることはできません。ドメイン イベントは、システムですでに何かを行ったことを示すので、ドメイン イベントを作成する前にあるべきでしょう。そのため、ドメインオブジェクトやそのドメインオブジェクトを使用するサービスへのアクセスを制限することができる。CQRSでは、リードモデルによるドメインオブジェクトは必要なく、サービスだけなので、一般的なソリューションを望むなら、サービスへのアクセスを制限しなければならない。アクセスに関する決定をすべてのサービス操作の最初に置くこともできるが、それは grant all, deny x セキュリティのアンチパターンになります。

どのように実装すればよいのでしょうか?

これは、どのアクセス制御モデルがドメインに適合するかに依存するので、ユーザーストーリーに依存することになります。アクセス決定によって、私たちは通常、アクセス要求を送信し、返事の許可を待ちます。アクセス要求は通常、主体、資源、操作、環境という部分から構成される。つまり、主体は、環境内のリソースに対して操作を実行する許可を必要とする。まず、主体を特定し、認証を行い、その後にアクセス要求がアクセスポリシーに適合しているかどうかを確認する認可が行われる。どのアクセス制御モデルも似たような仕組みになっています。もちろん、これらのステップのいくつかが欠けていることもありますが、それは問題ではありません...。

私はアクセス制御モデルの短いリストを作成しました。私はルール、ポリシーをアノテーションに置きましたが、通常、私たちがよくメンテナンス可能なシステムを持ちたいなら、おそらくXACML形式でそれらをデータベースに格納すべきです...。

  • IDベースのアクセス制御 (IBAC) によって、私たちは ID - 権限のストレージ (アクセス制御リスト、能力リスト、アクセス制御マトリックス) を持っています。例えば、アクセス制御リストによって、権限を持つことができるユーザまたはグループのリストを保存します。

    UserService
        @AccessControlList[inf3rno]
        editProfile(EditUserProfileCommand command)
    
    
  • LBAC(Lattice Based Access Control)では、対象がクリアランスレベルを持ち、リソースが要求されるクリアランスレベルを持ち、どちらのレベルが高いかをチェックする...。

    @posseses[level=5]
    inf3rno
    
    UserService
        @requires(level>=3)
        editProfile(EditUserProfileCommand command)
    
    
  • ロールベースアクセス制御(RBAC)では、被験者の役割を定義し、その役割を担う被験者に権限を付与します。

    @roles[admin]
    inf3rno
    
    UserService
        @requires(role=admin)
        editProfile(EditUserProfileCommand command)
    
    
  • 属性ベースのアクセス制御(ABAC)では、サブジェクト、リソース、環境の属性を定義し、それらに基づいてポリシーを記述します。

    @attributes[roles=[admin]]
    inf3rno
    
    UserService
        @policy(subject.role=admin or resource.owner.id = subject.id)
        editProfile(EditUserProfileCommand command)
        @attribute(owner)
        Subject getOwner(EditUserProfileCommand command)
    
    
  • ポリシーベースアクセスコントロール(PBAC)により、ポリシーを何かに割り当てるのではなく、スタンドアローンである。

    @attributes[roles=[admin]]
    inf3rno
    
    UserService
        editProfile(EditUserProfileCommand command)
        deleteProfile(DeleteUserProfileCommand command)
        @attribute(owner)
        Subject getOwner(EditUserProfileCommand command)
    
    @permission(UserService.editProfile, UserService.deleteProfile)
    @criteria(subject.role=admin or resource.owner.id = subject.id)
    WriteUserServicePolicy
    
    
  • リスク適応型アクセス制御(RAdAC)では、対象者の相対的なリスクプロファイルと操作のリスクレベルに基づいて判断します。これはルールで記述することはできないと思います。実装は不明ですが、もしかしたらstackoverflowがポイントシステムで使っているのはこれかもしれません。

  • 認可ベースのアクセス制御(ZBAC)では、識別と認証は行わず、代わりに識別要素に権限を割り当てます。たとえば、誰かがトークンを送ったら、その人はサービスにアクセスできるようになります。それ以外は、これまでのソリューションと同様です。例えばABACのように。

    @attributes[roles=[editor]]
    token:2683fraicfv8a2zuisbkcaac
    
    ArticleService
        @policy(subject.role=editor)
        editArticle(EditArticleCommand command)
    
    

    を知っている人は、みんな 2683fraicfv8a2zuisbkcaac トークンを知っている人なら誰でもサービスを利用することができます。

などなど...

他にも様々なモデルがあり、最適なものは常に顧客のニーズによって異なります。

つまり、要約すると

- "security concerns should be handled outside the domain"
- "access control requirements are domain specific"

セキュリティはドメインモデルの一部ではなく、その実装はドメインモデルとアプリケーションロジックに依存するため、両方が正しい可能性があります。

2年後に編集 2016-09-05

DDD初心者の自分の質問に答えてしまったので、読ませていただきました。 ドメイン駆動設計の実装 Vaughn Vernonの本です。これは、このトピックに関する興味深い本でした。以下はその引用です。

これは新しいBounded Context - Identity and Access - を構成しています。 コンテキストを構成し、標準的なDDD統合技術によって他のBounded Contextsによって使用されます。 DDD統合技術によって他のバウンデッドコンテキストに使用されます。消費するコンテキストにとって、Identity and Access Contextは一般的なサブコンテキストである。 Access ContextはGeneric Subdomainである。製品名は IdOvationと名付けられます。

Vernonによると、おそらくアクセス制御を一般的なサブドメインに移動するのが最良の解決策です。