EventSourcing应用程序中的用户身份验证

时间:2013-03-26 15:47:56

标签: authentication authorization cqrs event-sourcing event-store

我正在研究如何使用DDD + CQRS + EventSourcing制作应用程序,我在查找如何进行用户身份验证方面遇到了一些麻烦。

用户本质上是我的域名的一部分,因为他们负责客户。我正在使用ASP.NET MVC 4,我希望只使用SimpleMembership。由于登录和授权用户是同步操作,如何在最终一致的架构中解决这个问题?

我是否必须滚动自己的auth系统,在读取端保留非规范化的auth表?如何处理这个的安全性?我最终会在我的事件存储区和视图表中存储密码哈希值吗?

这么多问题,如果有人能说清楚,我会非常感激:)

tldr;你如何在EventSource应用程序中进行用户身份验证?

3 个答案:

答案 0 :(得分:11)

并非每个“域”或业务组件都必须使用DDD或CQRS。在大多数情况下,用户信息非常肮脏,因此您通常不能使用DDD。其他域并不真正依赖于实际用户。通常会有各种域共享的相关ID(UserId)。

如果在您的系统中使用消息传递,一种选择是注册和管理没有CQRS的用户,然后发送命令(RegisterUser {UserId})。这将发布用户注册的事件。其他域可以收听此事件以启动所需的任何工作流程或AR。

答案 1 :(得分:10)

对于我们的MVC CQRS应用程序,我们最初开始在域中保留所有用户相关信息,并且像有人提到的那样,有一个RegisterUserCommand和一个UserRegisteredEvent。在域中存储用户信息之后,该事件在读取端被发布和拾取,这也创建了用户并生成了所有密码哈希等。然后我们在读取端完成了身份验证:控制器将创建一个呼叫“读取模型身份验证服务”以进行身份​​验证。

后来,我们最终彻底重构了这一点。事实证明,我们需要访问用户相关信息以建立安全性来授权我们的命令,这是我们在命令处理方面完成的(我们的应用程序是一个分布式应用程序,它将'fire and forget'异步命令发送到队列,另一方面是一个自主的倾听者。然后,安全组件需要引用我们的域来获取用户配置文件,这导致了繁琐的引用问题。

我们决定将用户安全资料放入一个单独的数据库中,我们认为它更像是一个核心组件,而不是属于域或读取模型。我们仍在域中维护用户个人资料相关信息并阅读模型(例如职位,推特帐户URL等),但所有与安全相关的内容(如密码哈希)都存储在此中央数据库中。然后可以使用服务访问,MVC和命令授权者都可以使用该服务。

我们实际上不必为此重构更改UI中的任何内容,因为我们只是调用服务来从register user命令处理程序注册用户。如果你打算这样做,你需要在这里小心,使你的用户服务相关的操作是幂等的。这样您就可以在没有副作用的情况下为命令提供重试的机会,因为您正在更新2个信息源(ES和用户数据库)。

最后,您当然可以使用此核心组件的成员资格提供程序,但可以使用pitfalls。我们最后只是编写自己的 - 这很简单。该文章链接到this,它提供了如何实现它的一个很好的例子。

答案 2 :(得分:0)

您应该考虑创建单独的实体,例如:访问者(刚访问过您的网站),用户(已注册),客户(购买的东西)等。尝试以这种方式拆分您的系统,即使它会导致一点点数据冗余。磁盘空间不是问题,但是独立修改系统的不同组件的能力通常非常关键。

人们只为了缩放而创建非规范化的auth表,并且只有当你的auth读取方是性能瓶颈时才会这样做。如果不是 - 通常的第3种正常形式是一种方法。

在SimpleMembership场景中,SimpleMembership创建的所有表都可以被视为" user"骨料。是的,他们会在您的活动商店中复制一些数据。 您可能会遇到以下事件:UserCreated,UserUpdated,UserAssignedToRole等。

不要被会员提供者的名字欺骗。它不是那么简单,通常有许多你可以轻易存活的东西(取决于你的域名)。所以,也许你可以使用这样的东西:https://gist.github.com/Kayli/fe73769f19fdff40c3a7