Axon 中命令的授权

Authorization of commands in Axon

到目前为止,我一直在 CommandHandlers 中处理授权。

一个例子是我有一个聚合“团队”,其中包含一个经理列表(来自用户的聚合标识符)。团队聚合中的所有命令处理程序然后验证执行命令的用户是团队的经理。 userId 作为元数据注入到基于 SecurityContext 的 CommandHandlerInterceptor 中。

我主要担心的是,当我使用 sagas 时,跨针对不同聚合发出的命令维护用户上下文会成为额外的开销。除此之外,管理器关联可能会在 saga 运行 和后续失败命令期间过期,从而导致不完整的状态,这也需要通过一些回滚功能来处理。

在我的控制器层进行授权以避免额外的开销是否更好,还是我应该将其视为让我的 CommandHandlers 决定命令是否对聚合有效的更好做法?

执行某些 operations/commands 的授权是我认为不是域特定逻辑的东西。相反,它更像是一种横切关注点,您在整个应用程序中都需要它。因此,将它 放在 @CommandHandler 注释方法并不是我脑海中的理想位置。但是,将它放在附近很有意义。

您已经指出您已经在使用 CommandHandlerInterceptor 来填充 Spring SecurityContext,因此我假设您正在使用 CommandDispatchInterceptor 来填充命令的MetaData 发出命令时带有信息。这确实很好地使用了拦截器逻辑,所以我会保留它。然而,这是设置的信息,它不会验证它。

为此,您可以构建自己的 Handler Enhancer,它可以验证命令的安全元数据。您甚至可以构建一个专用注释,您将在 @CommandHandler 注释旁边添加该注释,它描述了所需的角色。这样,该方法仍然描绘了给定命令所需的角色,但可以在此 Handler Enhancer 中为您完成实际验证。

现在,让我们回到你的问题:

Is it better to do the authorization in my controller layer to avoid the additional overhead or should I see it more as good practice to let my CommandHandlers decide whether the command is valid for the aggregate?

我认为总体上这样做很好,有可能通过使用 Handler Enhancer 使其更清洁。当谈到你对 Saga 的关注时,好吧,我认为你应该分开看。 Saga 处理事件,facts 某些事情已经发生。因为发起导致这一事实的操作的人没有权利而忽略这一事实并不能解决它仍然发生的问题。补充一下,你确实完全不能保证 Saga 的时间。也许您的 Saga 涉及历史事件,这意味着它完全超出范围。

如果在您的系统中可能,我会将 Saga 想要发布的 任何 命令视为由“系统用户”发送。 Saga 不是您的用户(具有特定角色)会直接影响的东西;这都是间接的。 Saga 在您的系统内部,因此它是描述执行操作意图的系统。

这是我对这种情况的两分钱,希望这对你有帮助@Vincent!