Vin*_*ent 1 event-sourcing axon
到目前为止,我一直在处理 CommandHandlers 中的授权。
一个例子是我有一个包含经理列表的聚合“团队”(来自用户的聚合标识符)。团队聚合中的所有命令处理程序然后验证执行命令的用户是团队的经理。userId 作为元数据注入到基于 SecurityContext 的 CommandHandlerInterceptor 中。
我主要担心的是,当我使用 sagas 时,在针对不同聚合发出的命令中维护用户上下文会成为额外的开销。除此之外,管理器关联可能会在 saga 运行期间和随后的失败命令期间到期,导致不完整的状态,这也需要通过一些回滚功能进行处理。
是在我的控制器层中进行授权以避免额外的开销,还是应该将其视为让我的 CommandHandlers 决定命令对聚合是否有效的更好做法?
我认为授权执行某些操作/命令不是领域特定的逻辑。相反,它更像是一种横切关注的形式,您在整个应用程序中都需要它。因此,将它放在带@CommandHandler注释的方法中并不是我脑海中的理想位置。然而,把它放在附近很有意义。
您已经指出您已经在使用 aCommandHandlerInterceptor来填充 Spring SecurityContext,因此我假设您在发送命令时使用 aCommandDispatchInterceptor来填充命令的MetaData信息。这确实是拦截器逻辑的一个很好的用途,所以我会保留它。然而,这设置了信息,它不会验证它。
为此,您可以构建自己的Handler Enhancer,它可以验证命令的安全元数据。您甚至可以构建一个专用的注释,添加到@CommandHandler注释旁边,用于描述所需的角色。这样,该方法仍然描绘了给定命令所需的角色,但实际验证可以在此 Handler Enhancer 中为您完成。
现在,让我们回到你的问题:
是在我的控制器层中进行授权以避免额外的开销,还是应该将其视为让我的 CommandHandlers 决定命令对聚合是否有效的更好做法?
我认为总体上这样做很好,可能通过使用 Handler Enhancer 使其更干净。当谈到您对 Saga 的关注时,我认为您应该分开看待。Saga 处理事件,某些事情已经发生的事实。忽略这一事实,因为发起导致这一事实的操作的人没有权利并不能解决它仍然发生的问题。补充一下,你确实根本无法保证 Saga 的时间。也许您的 Saga 处理历史事件,这意味着它完全超出了范围。
如果可能在您的系统中,我会将Saga 想要发布的任何命令视为由“系统用户”发送。Saga 不是您的用户(具有特定角色)会直接影响的东西;这都是间接的。Saga 是系统内部的,因此它是描述执行操作意图的系统。
这是我对这种情况的两分钱,希望这能帮助你@Vincent!