SOA / microservice: Làm thế nào để xử lý ủy quyền trong liên lạc giữa các dịch vụ?


18

Vấn đề xung quanh

Chúng tôi đang chuyển từ một nền tảng nguyên khối sang Kiến trúc hướng dịch vụ hơn. Chúng tôi đang áp dụng các nguyên tắc DDD rất cơ bản và phân tách miền của chúng tôi qua các bối cảnh bị ràng buộc khác nhau. Mỗi tên miền được phân phối và hiển thị một dịch vụ thông qua API web (REST).

Do tính chất kinh doanh của chúng tôi, chúng tôi có các dịch vụ như Đặt chỗ , Dịch vụ , Khách hàng , Sản phẩm , v.v.

Chúng tôi cũng đã thiết lập Máy chủ Nhận dạng (dựa trên Máy chủ Nhận dạng 3 của Thinktecture) với vai trò chính là:

  • Tập trung xác thực (thông tin xác thực mà nó phát hành mã thông báo)
  • Thêm khiếu nại vào các mã thông báo, chẳng hạn như: phạm vi của khách hàng (theo khách hàng, ý tôi là ứng dụng thực hiện yêu cầu), định danh khách hàng (theo khách hàng tôi có nghĩa là người sử dụng ứng dụng)

Chúng tôi cũng giới thiệu vai trò của API Gateway tập trung quyền truy cập bên ngoài vào các dịch vụ của chúng tôi. API Gateway cung cấp các chức năng không yêu cầu kiến ​​thức sâu về các miền nội bộ, chẳng hạn như:

  • Reverse proxy: định tuyến các yêu cầu đến vào dịch vụ nội bộ phù hợp
  • Phiên bản: phiên bản của API Gateway ánh xạ tới các phiên bản khác nhau của dịch vụ nội bộ
  • Xác thực: các yêu cầu của khách hàng bao gồm mã thông báo do Máy chủ Nhận dạng và Cổng API xác thực mã thông báo (đảm bảo người dùng là người nói rằng cô ấy)
  • Throttling: giới hạn số lượng yêu cầu cho mỗi khách hàng

Ủy quyền

Những gì liên quan đến ủy quyền, điều này không được quản lý trong API Gateway mà trong chính các dịch vụ nội bộ. Chúng tôi hiện đang thực hiện 2 loại ủy quyền chính:

  • Ủy quyền dựa trên phạm vi khách hàng. Ví dụ: một khách hàng (ứng dụng bên ngoài sử dụng API của chúng tôi) yêu cầu phạm vi "đặt chỗ" để truy cập vào điểm cuối API dịch vụ Đặt chỗ
  • Ủy quyền dựa trên khách hàng. Ví dụ: chỉ khi khách hàng (người thực tế sử dụng ứng dụng) là người tham gia đặt phòng mới có thể truy cập điểm cuối GET / đặt trước từ dịch vụ Đặt chỗ

Để có thể xử lý ủy quyền trong các dịch vụ nội bộ, API Gateway chỉ cần chuyển tiếp mã thông báo (khi định tuyến yêu cầu đến dịch vụ nội bộ) bao gồm cả thông tin về máy khách (ứng dụng thực hiện yêu cầu) và khách hàng dưới dạng khiếu nại (trong những trường hợp một người được đăng nhập vào ứng dụng khách).

Mô tả vấn đề

Cho đến nay rất tốt cho đến khi chúng tôi giới thiệu liên lạc giữa các dịch vụ (một số dịch vụ có thể giao tiếp với các dịch vụ khác để có được một số dữ liệu).

Câu hỏi

Làm thế nào chúng ta nên tiếp cận ủy quyền trong truyền thông liên dịch vụ?

Tùy chọn được xem xét

Để thảo luận về các tùy chọn khác nhau, tôi sẽ sử dụng kịch bản mẫu sau:

  • Chúng tôi có một ứng dụng bên ngoài có tên là InternalApp truy cập API của chúng tôi ( Có thể xem bên ngoàiứng dụng khách ) để xây dựng luồng đặt phòng
  • Ứng dụng bên ngoài cần quyền truy cập vào dịch vụ Đặt chỗ , do đó chúng tôi cấp cho Ứng dụng bên ngoài phạm vi "đặt chỗ"
  • Bên trong (đây là điều hoàn toàn minh bạch đối với Ứng dụng bên ngoài ), dịch vụ Đặt chỗ chấp nhận dịch vụ Dịch vụ để có được các dịch vụ mặc định của đặt chỗ như các chuyến bay, bảo hiểm hoặc thuê xe

Khi thảo luận về vấn đề này trong nội bộ, một số tùy chọn đã xuất hiện, nhưng chúng tôi không chắc chắn tùy chọn nào là tốt nhất:

  1. Khi Đặt chỗ giao tiếp với Dịch vụ , chỉ cần chuyển tiếp mã thông báo gốc mà anh ta nhận được từ Cổng API (cho biết khách hàng là Ứng dụng bên ngoài )
    • Ý nghĩa: Chúng tôi có thể cần phải cấp phạm vi cho Ứng dụng bên ngoài không nên được cấp. Ví dụ: InternalApp có thể cần có cả phạm vi "đặt chỗ" và "dịch vụ" trong khi chỉ phạm vi "đặt chỗ" mới có thể có hiệu lực
  2. Khi Đặt chỗ giao tiếp với Dịch vụ , nó sẽ chuyển tiếp mã thông báo cho biết khách hàng hiện đã trở thành Đặt chỗ (thay vì Ứng dụng bên ngoài ) + nó thêm một xác nhận cho biết Đặt chỗ đang mạo danh ứng dụng khách bên ngoài
    • Ngoài ra, bao gồm thông tin rằng ứng dụng khách gốc là Ứng dụng bên ngoài , dịch vụ Dịch vụ cũng có thể thực hiện logic như lọc ra một số dịch vụ tùy thuộc vào người gọi ban đầu (ví dụ: đối với các ứng dụng nội bộ, chúng tôi sẽ trả lại tất cả các trận đấu, chỉ cho một số ứng dụng bên ngoài)
  3. Các dịch vụ không nên liên lạc với nhau (vì vậy chúng tôi thậm chí không nên đối mặt với câu hỏi này)

Cám ơn trước cho đầu vào cửa bạn.


1
Làm thế nào bạn giải quyết vấn đề này? Chúng tôi đang ở trong một tình huống tương tự.
Varun Mehta

+1: Tôi quan tâm đến cách cuối cùng bạn giải quyết vấn đề của mình.
Dypso

Để thực hiện điểm 3 - các dịch vụ không liên lạc với nhau, bạn cần có giao diện người dùng tổng hợp. Xem particular.net/blog/secret-of-better-ui-composition
stevie_c

Câu trả lời:


3

Tôi khuyên bạn nên có một kênh liên lạc nội bộ giữa các dịch vụ siêu nhỏ.

Ví dụ: để sử dụng một số nhà môi giới tin nhắn như RabbitMQ trong nội bộ để gửi / nhận hoặc xuất bản / đăng ký tin nhắn giữa các dịch vụ.

Sau đó, người dùng cuối phải đối mặt với dịch vụ "trong ví dụ của bạn là dịch vụ Đặt chỗ" sẽ chịu trách nhiệm xác thực mã thông báo và ủy quyền cho khách hàng thực hiện thao tác cụ thể này có thể bằng cách liên lạc với IdentityServer.

Sau đó, nó sẽ liên lạc với dịch vụ Dịch vụ thông qua người môi giới Tin nhắn và trong trường hợp đó, không cần phải xác thực mã thông báo nữa.

Tôi đoán mô hình này sẽ đơn giản hơn và cung cấp cho bạn hiệu suất tốt hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.