12

Tôi đang xem xét tạo một ứng dụng với DDD + CQRS + EventSourcing và tôi gặp một số sự cố khi tìm hiểu cách thực hiện xác thực người dùng.Xác thực người dùng trong các ứng dụng EventSourcing

Người dùng thực chất là một phần của miền của tôi, vì họ chịu trách nhiệm cho khách hàng. Tôi đang sử dụng ASP.NET MVC 4, và tôi đã tìm cách chỉ sử dụng SimpleMembership. Kể từ khi đăng nhập và cho phép người dùng là một hoạt động đồng bộ, làm thế nào điều này được giải quyết trong một kiến ​​trúc cuối cùng nhất quán?

Tôi có phải cuộn hệ thống xác thực của riêng mình nơi tôi giữ các bảng auth được chuẩn hóa ở phía bên đọc không? Làm thế nào để xử lý bảo mật này? Tôi sẽ kết thúc lưu trữ các băm mật khẩu trong cả cửa hàng sự kiện của tôi và các bảng xem của tôi?

Rất nhiều câu hỏi, nếu có ai có thể làm sáng tỏ, tôi sẽ rất biết ơn :)

tldr; Làm thế nào để bạn thực hiện xác thực người dùng trong các ứng dụng EventSource?

+0

Giống như cách bạn thực hiện trong các hệ thống dựa trên tin nhắn, AFAIK. Bạn dường như kết hợp ủy quyền và xác thực. Bạn đang cố gắng bảo mật cái gì? –

+0

Tôi không trộn chúng, tôi hỏi về cả hai, thực sự :) Có vẻ vấn đề chính của tôi sau đó là tôi không biết làm thế nào nó được thực hiện trong các hệ thống dựa trên tin nhắn;) – tuxbear

Trả lời

9

Không phải mọi "Miền" hoặc thành phần kinh doanh đều phải sử dụng DDD hoặc CQRS. Trong hầu hết các trường hợp, thông tin người dùng thực sự là hoạt động lộn xộn, vì vậy bạn thường không thể sử dụng DDD cho điều đó. Các miền khác không thực sự phụ thuộc vào người dùng thực tế. Thường có một id tương quan (UserId) được chia sẻ bởi các tên miền khác nhau.

Nếu sử dụng nhắn tin trong hệ thống, một tùy chọn là đăng ký và quản lý người dùng không có CQRS, sau đó gửi lệnh (RegisterUser {UserId}). Điều này sẽ xuất bản một sự kiện Người dùng đã đăng ký. Các miền khác có thể nghe sự kiện này để khởi động bất kỳ luồng công việc hoặc AR nào cần thiết.

+2

+1 Tôi thứ hai .. nó không phải tất cả CQRS hoặc không có gì .. chọn và chọn nơi có ý nghĩa. đối với chúng tôi, chúng tôi xác thực người dùng và cấp mã thông báo, sau đó chúng tôi có thể gán cho tiêu đề của từng lệnh để đảm bảo người dùng có cấp truy cập và thông tin xác thực chính xác để thực hiện các hoạt động nhất định trong ngữ cảnh của lệnh. – Sarmaad

+2

Cảm ơn bạn! Tôi nghĩ đây thực sự là câu trả lời tôi đang tìm kiếm. Tôi đã suy nghĩ về giải pháp này, nhưng nó có vẻ kinda bẩn để có một số dữ liệu trong các cửa hàng sự kiện, và một số dữ liệu trong db-bảng. Tôi cũng lo lắng về khả năng phát lại sự kiện để khôi phục lại trạng thái, vì lợi ích của EventSouring là lý do duy nhất khiến tôi khám phá nó. Nó cũng liên quan đến tôi rằng có một số chi phí nhận thức của việc có hai kiến ​​trúc cạnh nhau như thế. – tuxbear

0

Bạn nên xem xét việc tạo các thực thể riêng biệt như: khách truy cập (chỉ cần truy cập vào trang web của bạn), người dùng (đã đăng ký), khách hàng (đã mua thứ gì đó), v.v. Hãy thử chia hệ thống theo cách này, ngay cả khi nó gây ra một chút dữ liệu dự phòng. Không gian đĩa không phải là vấn đề nhưng khả năng sửa đổi các thành phần khác nhau của hệ thống một cách độc lập thường rất quan trọng.

Mọi người tạo các bảng auth được chuẩn hóa chỉ nhằm mục đích mở rộng quy mô và chỉ khi bên đọc auth của bạn là một nút cổ chai hiệu suất. Nếu không - hình thức bình thường thứ 3 bình thường là một cách để đi.

Trong kịch bản đơn giảnMô hình tất cả các bảng được tạo bởi SimpleMembership có thể được xem dưới dạng ảnh chụp nhanh tổng hợp "người dùng". Và có, họ sẽ sao chép một số dữ liệu trong cửa hàng sự kiện của bạn. Bạn có thể có các sự kiện như: UserCreated, UserUpdated, UserAssignedToRole, v.v.

Và đừng bị lừa bởi tên của nhà cung cấp thành viên đó. Nó không đơn giản và thường có rất nhiều thứ mà bạn có thể dễ dàng sống mà không cần (phụ thuộc vào tên miền của bạn). Vì vậy, có thể bạn có thể sử dụng một cái gì đó như thế này: https://gist.github.com/Kayli/fe73769f19fdff40c3a7

9

Đối với ứng dụng MVC CQRS của chúng tôi, ban đầu chúng tôi bắt đầu giữ tất cả thông tin liên quan đến người dùng trong miền và, như ai đó đã đề cập, có RegisterUserCommand và UserRegisteredEvent. Sau khi lưu trữ thông tin người dùng trong miền, sự kiện đó đã được xuất bản và chọn ở bên đọc, cũng tạo ra một người dùng và tạo ra tất cả các băm mật khẩu, v.v. Sau đó chúng tôi đã thực hiện xác thực ở phía đọc: bộ điều khiển sẽ tạo gọi ra 'dịch vụ xác thực mô hình đã đọc' để xác thực.

Sau đó xuống đường, chúng tôi đã hoàn toàn hoàn nguyên việc này. Chúng tôi cần truy cập vào thông tin liên quan đến người dùng để xây dựng bảo mật cho phép các lệnh của chúng tôi thực hiện ở phía xử lý lệnh (ứng dụng của chúng tôi là ứng dụng được phân phối gửi lệnh 'không đồng bộ và' không đồng bộ đến hàng đợi) một người nghe tự trị ở phía bên kia). Các thành phần bảo mật sau đó cần một tham chiếu đến tên miền của chúng tôi để đi và nhận được hồ sơ người dùng, dẫn đến vấn đề tham khảo cồng kềnh.

Chúng tôi quyết định đưa công cụ bảo mật người dùng vào cơ sở dữ liệu riêng biệt mà chúng tôi cho là nhiều hơn một thành phần trung tâm, thay vì thuộc về miền hoặc đọc mô hình. Chúng tôi vẫn duy trì người dùng hồ sơ thông tin liên quan trong miền và đọc mô hình (ví dụ: tên công việc, URL tài khoản twitter, v.v.), nhưng tất cả nội dung liên quan đến bảo mật, như băm mật khẩu đều được lưu trữ trong cơ sở dữ liệu trung tâm này. Đó là sau đó có thể truy cập với một dịch vụ, đó là có sẵn cho cả hai MVC và tác giả lệnh.

Chúng tôi không thực sự phải thay đổi bất kỳ thứ gì trong giao diện người dùng cho trình tái cấu trúc này, vì chúng tôi vừa gọi dịch vụ để đăng ký người dùng từ trình xử lý lệnh người dùng đăng ký. Nếu bạn định thực hiện theo cách đó, bạn cần cẩn thận ở đây để làm cho các hoạt động liên quan đến dịch vụ người dùng của bạn không hoạt động. Điều này là để bạn có thể cung cấp cho các lệnh của bạn cơ hội được thử lại mà không có tác dụng phụ, bởi vì bạn đang cập nhật 2 nguồn thông tin (ES và cơ sở dữ liệu người dùng).

Cuối cùng, bạn có thể sử dụng các nhà cung cấp thành viên cho thành phần trung tâm này, nhưng có thể có pitfalls với điều đó. Chúng tôi đã kết thúc chỉ bằng văn bản của riêng mình - nó khá đơn giản để làm. Bài viết đó liên kết đến this, cung cấp ví dụ tốt về cách triển khai.

+0

Cảm ơn bạn! Tôi cũng đã đi xuống con đường này, tốt để có được một số lời khuyên từ những người có kinh nghiệm thực tế sử dụng các cấu trúc này. Bật lớn của tôi với ES là khả năng xây dựng các tính năng mới với thông tin cũ. Có lưu trữ dữ liệu miền như các sự kiện đã được chứng minh có giá trị đối với bạn không? – tuxbear

+1

Vâng, bởi vì nó có nghĩa là bạn có thể tái tạo các công cụ bảo mật bằng cách phát lại ES. – jacderida

+0

Những gì bạn mô tả chỉ đơn giản là sử dụng thêm [chiếu] (http://abdullin.com/event-sourcing/projections.html) để xử lý các sự kiện miền của bạn. Nó thực sự rất dễ dàng, cảm ơn! Vì vậy, sử dụng dữ liệu thời gian thực hoặc cũ chỉ phụ thuộc vào thời điểm bạn snychronize mô hình đọc của bạn với các sự kiện của bạn, không có gì khác ... – inf3rno

Các vấn đề liên quan