You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

领域驱动设计(DDD)中超级用户权限的实现方案探讨

在DDD领域模型中加入超级用户权限的方案探讨

我正尝试在领域驱动设计(DDD)场景中应用安全机制,以Vernon著作中的moderatePost方法为例,该方法规定仅对应论坛的版主(Moderator)可审核该论坛内的帖子:

public void moderatePost(
        Post aPost,
        Moderator aModerator,
        String aSubject,
        String aBodyText) {

    this.assertStateFalse(this.isClosed(), "Forum is closed.");
    this.assertArgumentNotNull(aPost, "Post may not be null.");
    this.assertArgumentEquals(aPost.forumId(), this.forumId(), "Not a post of this forum.");
    this.assertArgumentTrue(this.isModeratedBy(aModerator), "Not the moderator of this forum.");

    aPost.alterPostContent(aSubject, aBodyText);
}

问题

部分系统中存在可执行所有操作的超级用户(admin),如何在该领域模型中加入超级用户权限?我能想到的方案是重载moderatePost方法以绕过isModeratedBy断言,但担心应用层会误用该重载方法。


可行方案

1. 扩展原方法的权限校验逻辑

直接在原方法的断言中加入超级用户的判断,无需新增方法,从根源避免应用层误用:

public void moderatePost(
        Post aPost,
        Moderator aModerator,
        String aSubject,
        String aBodyText) {

    this.assertStateFalse(this.isClosed(), "Forum is closed.");
    this.assertArgumentNotNull(aPost, "Post may not be null.");
    this.assertArgumentEquals(aPost.forumId(), this.forumId(), "Not a post of this forum.");
    // 新增超级用户判断逻辑
    this.assertArgumentTrue(this.isModeratedBy(aModerator) || aModerator.isSuperAdmin(), "无权限审核该帖子");

    aPost.alterPostContent(aSubject, aBodyText);
}

前提是Moderator模型需要添加isSuperAdmin()方法或标识属性。如果超级用户是独立于Moderator的身份模型,可以将参数调整为更通用的User类型,再判断用户是版主还是超级管理员。

2. 引入权限上下文封装判断逻辑

新增包含权限判断逻辑的AuthorizationContext对象,将权限校验从实体中解耦,同时保持实体接口的简洁性:

public void moderatePost(
        Post aPost,
        User aUser,
        String aSubject,
        String aBodyText,
        AuthorizationContext authContext) {

    this.assertStateFalse(this.isClosed(), "Forum is closed.");
    this.assertArgumentNotNull(aPost, "Post may not be null.");
    this.assertArgumentEquals(aPost.forumId(), this.forumId(), "Not a post of this forum.");
    // 委托权限上下文完成判断
    this.assertArgumentTrue(authContext.canModerateForum(this, aUser), "无权限审核该帖子");

    aPost.alterPostContent(aSubject, aBodyText);
}

AuthorizationContext内部封装版主校验、超级用户校验等逻辑,领域层只依赖其提供的权限判断结果,无需关心具体规则细节。

3. 用领域服务统一处理权限

将权限校验逻辑抽离到专门的领域服务中,实体仅负责核心业务操作,避免职责过载:

public class PostModerationService {
    public void moderatePost(Forum forum, Post post, User user, String subject, String bodyText) {
        forum.assertNotClosed();
        forum.assertPostBelongsToForum(post);
        
        if (!forum.isModeratedBy(user) && !user.isSuperAdmin()) {
            throw new IllegalArgumentException("无权限审核该帖子");
        }
        
        post.alterPostContent(subject, bodyText);
    }
}

此时可以简化Forum实体的方法,把原来的断言逻辑拆分为独立的assertNotClosed()、assertPostBelongsToForum()方法,让实体专注于自身状态校验,权限判断交由领域服务统一处理。


为什么不推荐重载方法

重载方法会增加实体接口的复杂度,应用层容易因参数匹配错误误调用超级用户专属方法,直接导致权限控制失效。同时重载不符合单一职责原则,会让实体承担过多权限判断的细节,不利于领域模型的长期维护。

内容的提问来源于stack exchange,提问作者swch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:39:50