首页 > 解决方案 > Axon 中的命令授权

问题描述

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

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

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

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

标签: event-sourcingaxon

解决方案


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

您已经指出您已经在使用 aCommandHandlerInterceptor来填充 Spring SecurityContext,因此我假设您在发送命令时正在使用 aCommandDispatchInterceptor来填充命令的MetaData信息。这确实是拦截器逻辑的一个很好的用途,所以我会保留它。然而,这集是信息,它不验证它。

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

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

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

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

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

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


推荐阅读