Hệ thống ủy quyền và xác thực cho microservice và người tiêu dùng


15

Chúng tôi dự định tái cấu trúc hệ thống công ty của chúng tôi thành một hệ thống dựa trên dịch vụ vi mô. Các dịch vụ vi mô này sẽ được sử dụng bởi các ứng dụng nội bộ của công ty chúng tôi và các đối tác bên thứ 3 nếu cần. Một cho đặt phòng, một cho các sản phẩm, vv

Chúng tôi không chắc chắn làm thế nào để xử lý vai trò và phạm vi. Ý tưởng là tạo ra 3 vai trò người dùng cơ bản như Quản trị viên, Đại lý và Người dùng cuối và để các ứng dụng khách hàng điều chỉnh phạm vi nếu cần.

  • Quản trị viên có thể tạo, cập nhật, đọc và xóa tất cả các tài nguyên theo mặc định (cho công ty của họ).
  • Đại lý có thể tạo, cập nhật và đọc dữ liệu cho công ty của họ.
  • Người dùng cuối có thể tạo, cập nhật, xóa và đọc dữ liệu, nhưng không thể truy cập các điểm cuối giống như các tác nhân hoặc quản trị viên. Họ cũng sẽ có thể tạo hoặc sửa đổi dữ liệu, chỉ không ở cùng cấp độ với các tác nhân hoặc quản trị viên. Ví dụ: người dùng cuối có thể cập nhật hoặc đọc thông tin tài khoản của họ, giống như đại lý sẽ có thể làm điều đó cho họ, nhưng họ không thể xem hoặc cập nhật ghi chú quản trị viên.

Giả sử các đại lý theo mặc định có thể tạo, đọc và cập nhật từng tài nguyên cho công ty của họ và đó là phạm vi tối đa có thể được yêu cầu cho mã thông báo / phiên của họ, nhưng các nhà phát triển ứng dụng khách (người tiêu dùng API) đã quyết định rằng một trong các đại lý của họ có thể chỉ đọc và tạo một số tài nguyên nhất định

Có phải là một cách thực hành tốt hơn để xử lý vấn đề này trong bảo mật nội bộ của chúng tôi và để họ viết dữ liệu đó trong cơ sở dữ liệu của chúng tôi hoặc để khách hàng xử lý nội bộ đó bằng cách yêu cầu mã thông báo với phạm vi nhỏ hơn và để họ viết đại lý nào sẽ có phạm vi trong cơ sở dữ liệu của họ ? Bằng cách này, chúng tôi sẽ chỉ phải theo dõi phạm vi mã thông báo.

Nhược điểm của điều này là nhóm của chúng tôi cũng sẽ cần tạo ra các cơ chế truy cập được tinh chỉnh trong các ứng dụng nội bộ của chúng tôi.

Với cách nghĩ này, các dịch vụ vi mô và hệ thống ủy quyền của họ không nên bị làm phiền với nhu cầu của khách hàng, vì họ chỉ là người tiêu dùng và không phải là một phần của hệ thống (mặc dù một số người tiêu dùng đó là ứng dụng nội bộ của chúng tôi)?

Đây có phải là một cách tiếp cận tốt?

Câu trả lời:


14

Xác thực và ủy quyền luôn là chủ đề tốt

Tôi sẽ cố gắng giải thích cho bạn cách chúng tôi xử lý các ủy quyền trong dịch vụ nhiều khách thuê hiện tại mà tôi đang làm việc. Việc xác thực và ủy quyền dựa trên mã thông báo, sử dụng tiêu chuẩn mở Mã thông báo Web JSON. Dịch vụ hiển thị API REST mà bất kỳ loại ứng dụng khách nào (web, thiết bị di động và ứng dụng máy tính để bàn) có thể truy cập. Khi người dùng được xác thực thành công, dịch vụ sẽ cung cấp mã thông báo truy cập phải được gửi theo từng yêu cầu đến máy chủ.

Vì vậy, hãy để tôi giới thiệu một số khái niệm chúng tôi sử dụng dựa trên cách chúng tôi nhận thức và xử lý dữ liệu trên ứng dụng máy chủ.

Tài nguyên : Đó là bất kỳ đơn vị hoặc nhóm dữ liệu nào mà khách hàng có thể truy cập thông qua dịch vụ. Đối với tất cả các tài nguyên mà chúng tôi muốn được kiểm soát, chúng tôi chỉ định một tên. Chẳng hạn, có các quy tắc điểm cuối tiếp theo, chúng ta có thể đặt tên cho chúng như sau:

product

/products
/products/:id

payment

/payments/
/payments/:id

order

/orders
/orders/:id
/orders/:id/products
/orders/:id/products/:id

Vì vậy, hãy nói rằng cho đến nay chúng tôi có ba tài nguyên trong dịch vụ của chúng tôi; product, paymentorder.

Hành động : Đây là một hoạt động có thể được thực hiện trên một tài nguyên, như, đọc, tạo, cập nhật, xóa, v.v. Không cần thiết chỉ là các hoạt động CRUD cổ điển follow, ví dụ, bạn có thể có một hành động được đặt tên muốn tiết lộ một dịch vụ truyền bá một số loại thông tin bằng WebSockets.

Khả năng : Khả năng thực hiện một actiontrên a resource. Ví dụ; đọc sản phẩm, tạo sản phẩm, v.v ... Về cơ bản nó chỉ là một cặp tài nguyên / hành động. Nhưng bạn có thể thêm một tên và mô tả cho nó quá.

Vai trò : Một tập hợp các khả năng mà người dùng có thể sở hữu. Ví dụ: một vai trò Cashiercó thể có các khả năng "đọc thanh toán", "tạo thanh toán" hoặc vai trò Sellercó thể có các khả năng "đọc sản phẩm", "đọc thứ tự", "cập nhật thứ tự", "xóa đơn hàng".

Cuối cùng, một người dùng có thể có nhiều vai trò khác nhau được giao cho anh ta.


Giải trình

Như tôi đã nói trước đây, chúng tôi sử dụng Mã thông báo Web JSON và các khả năng mà người dùng sở hữu được khai báo trong tải trọng của mã thông báo. Vì vậy, giả sử chúng ta có một người dùng với vai trò thu ngân và người bán cùng một lúc, cho một cửa hàng bán lẻ nhỏ. Tải trọng sẽ như thế này:

{
    "scopes": {
        "payment": ["read", "create"],
        "order": ["read", "create", "update", "delete"]
    }
}

Như bạn có thể thấy trong scopesyêu cầu bồi thường, chúng tôi không chỉ định tên của các vai trò (nhân viên thu ngân, người bán), thay vào đó, chỉ các tài nguyên và hành động liên quan được chỉ định. Khi khách hàng gửi yêu cầu đến điểm cuối, dịch vụ sẽ kiểm tra xem mã thông báo truy cập có chứa tài nguyên và hành động cần thiết hay không. Ví dụ: một GETyêu cầu đến điểm cuối /payments/88sẽ thành công, nhưng một DELETEyêu cầu đến cùng một điểm cuối phải thất bại.


  • Cách nhóm và đặt tên cho các tài nguyên cũng như cách xác định và đặt tên cho các hành độngkhả năng sẽ là một quyết định được đưa ra bởi các nhà phát triển.

  • Là những gì các vai trò và những gì khả năng sẽ có những vai trò, là quyết định của khách hàng.


Tất nhiên, bạn phải thêm các thuộc tính bổ sung vào tải trọng để xác định người dùng và khách hàng (người thuê) đã phát hành mã thông báo.

{
    "scopes": {
        ...
    },
    "tenant": "acme",
    "user":"coyote"
}

Với phương pháp này, bạn có thể tinh chỉnh quyền truy cập của bất kỳ tài khoản người dùng nào vào dịch vụ của bạn. Và điều quan trọng nhất, bạn không phải tạo các vai trò tĩnh và được xác định trước khác nhau, như Quản trị viên, Đại lý và Người dùng cuối khi bạn chỉ ra trong câu hỏi của mình. Một Super User sẽ là một người sử dụng sở hữu một rolevới tất cả các resourcesactionscác dịch vụ được gán cho nó.

Bây giờ, Điều gì sẽ xảy ra nếu có 100 tài nguyên và chúng tôi muốn có một vai trò cho phép truy cập vào tất cả hoặc gần như tất cả chúng?. Tải trọng mã thông báo của chúng tôi sẽ rất lớn. Điều đó được giải quyết bằng cách lồng các tài nguyên và chỉ cần thêm tài nguyên gốc trong phạm vi mã thông báo truy cập.


Ủy quyền là một chủ đề phức tạp phải được giải quyết tùy thuộc vào nhu cầu của từng ứng dụng.


cảm ơn bạn đã trả lời Điều này rất hữu ích. Tôi có một câu hỏi liên quan đến nhiều vai trò cho mỗi người dùng. Bạn có bao giờ có một trường hợp mà quyền hạn vai trò chồng chéo? Chẳng hạn như thu ngân có payment:[read], người bán có payment: [create]. Bạn có tổng hợp quyền trong trường hợp này?
Robert

Nếu bạn có vai trò với khả năng lặp đi lặp lại (resource/action), bạn phải hợp nhất chúng. Nếu các quyền chồng lấp, bạn phải tổng hợp chúng. Ý tưởng là chỉ xác định các tài nguyên và hành động được phép trong mã thông báo, để lại các vai trò giống như một sự trừu tượng được sử dụng để cung cấp cho khách hàng một cách ít phức tạp hơn để xử lý ủy quyền.
miso

1
Điều gì xảy ra nếu người dùng chỉ có thể thực hiện hành động đối với các tài nguyên mà họ SỞ HỮU. Ví dụ như tài khoản ngân hàng, chắc chắn "bank_account": ["đọc", "cập nhật"] không chỉ định điều đó. Ngoài ra, chính xác thì quá trình ủy quyền diễn ra trong hệ thống microservice ở đâu? Trên một máy chủ ủy quyền tập trung, hoặc mỗi dịch vụ có ủy quyền riêng không?
rocketspacer

@rocketspacer. Đó là lý do tại sao mã thông báo có usertài sản trong tải trọng của nó. Cách tôi khóa tài nguyên do người dùng sở hữu là bằng cách ánh xạ userxác nhận tới URL. Ví dụ: /users/coyote/back-accountsẽ chỉ có thể truy cập bằng mã thông báo có useryêu cầu bằng coyote. Tôi hy vọng sự giúp đỡ đó.
miso

3

Tôi nghĩ rằng không có vấn đề gì, bạn sẽ muốn các dịch vụ của mình chấp nhận mã thông báo xác thực được cung cấp bởi một dịch vụ xác thực mà bạn viết để xác thực người dùng. Đây là cách đơn giản / an toàn nhất để ngăn chặn việc lạm dụng các dịch vụ siêu nhỏ của bạn. Ngoài ra, nói chung, nếu bạn muốn khách hàng có trải nghiệm tốt, bạn nên tự mình thực hiện các tính năng quan trọng và kiểm tra kỹ lưỡng để đảm bảo rằng các tính năng bạn cung cấp được triển khai tốt.

Vì tất cả người gọi cần cung cấp bằng chứng microservice của bạn rằng họ đã được xác thực, bạn cũng có thể buộc các quyền đối với xác thực đó. Nếu bạn cung cấp khả năng ràng buộc người dùng với một nhóm truy cập tùy ý (hoặc các nhóm nếu bạn muốn có được sự ưa thích, mặc dù các quyền bổ sung so với trừ khó xử lý hơn ở đây.), Sẽ có ít câu hỏi hơn đến từ khách hàng của bạn về lý do người dùng của bạn x đã có thể thực hiện một hoạt động không mong muốn. Trong mọi trường hợp, ai đó phải thực hiện kiểm tra danh sách truy cập cho từng dịch vụ, vì vậy đó cũng có thể là bạn. Đó là thứ sẽ dễ dàng được mã hóa khi bắt đầu tất cả các dịch vụ (if ( !TokenAuthorized(this.ServiceName, this.token) { Raise error }) Rằng bạn cũng có thể làm điều đó và tự theo dõi các nhóm người dùng. Đúng là bạn sẽ phải có người quản lý nhóm quyền và đưa nó vào UI quản lý người dùng (sử dụng nhóm hiện có / tạo mới cho quyền người dùng) Liệt kê danh sách người dùng được liên kết với một nhóm khi bạn chỉnh sửa định nghĩa, để tránh nhầm lẫn . Nhưng, đó không phải là một công việc khó khăn. Chỉ cần có siêu dữ liệu cho tất cả các dịch vụ và liên kết tìm kiếm ánh xạ giữa nhóm và dịch vụ vào xử lý mã thông báo xác thực.

Ok, vì vậy có khá nhiều chi tiết, nhưng mỗi khách hàng của bạn muốn có chức năng này sẽ phải mã hóa điều này trong mọi trường hợp và nếu bạn hỗ trợ quyền của người dùng ba cấp, bạn cũng có thể mở rộng để có quyền truy cập cho mỗi người dùng các nhóm. Có lẽ một giao điểm hợp lý giữa các quyền của nhóm cơ sở và các quyền cụ thể của người dùng sẽ là tổng hợp đúng, nhưng nếu bạn muốn có thể thêm và lấy các quyền cơ sở, của các quyền cơ sở của Quản trị viên, Đại lý, Người dùng cuối, bạn sẽ phải làm cờ ba trạng thái hữu dụng trong các nhóm quyền: Thêm quyền, từ chối quyền, quyền mặc định và kết hợp các quyền một cách thích hợp.

. d đã bẻ khóa mật khẩu.)


Trong khi suy nghĩ về cơ sở hạ tầng và triển khai, tôi hoàn toàn quên mất trải nghiệm của khách hàng .. Tôi thích ý tưởng tạo ra bộ quy tắc sẽ phù hợp hơn với doanh nghiệp của chúng tôi. Quản trị viên, Đại lý và Người dùng cuối quá chung chung và chúng tôi dự định triển khai nhiều loại người dùng hơn, mang tính mô tả và gắn liền với ngôn ngữ kinh doanh và ngôn ngữ của chúng tôi.
Robert

Tôi đã không thể sửa lỗi đánh máy "anded" trong câu cuối cùng bởi vì tôi không thể tìm ra nó.
Tulains Córdova

Đây không phải là một lỗi đánh máy, nhưng tôi sẽ làm cho nó rõ ràng hơn ..
BenPen

1

Quan điểm của tôi là bạn có hai lựa chọn ở đây.

  • Nếu bạn chỉ cần có quyền truy cập có thể định cấu hình cho cùng một ứng dụng, thì hãy kiểm tra các quyền dịch vụ và cung cấp cho khách hàng của bạn một giao diện cho phép họ thay đổi các quyền được cấp cho từng vai trò. Điều này cho phép hầu hết người dùng sử dụng thiết lập vai trò mặc định mà khách hàng của 'vấn đề' có thể điều chỉnh vai trò hoặc tạo vai trò mới cho phù hợp với nhu cầu của họ.

  • Nếu khách hàng của bạn đang phát triển các ứng dụng của riêng họ, họ nên giới thiệu api trung gian của riêng họ. Kết nối với quản trị viên của bạn, nhưng kiểm tra yêu cầu đến đối với các yêu cầu xác thực tùy chỉnh của riêng họ trước khi gọi dịch vụ của bạn


1

Xem xét an ninh

Nếu tôi hiểu rõ thiết kế của bạn, bạn có ý định ủy thác một số cơ chế kiểm soát truy cập tài nguyên cho phía khách hàng, tức là một ứng dụng tiêu thụ sẽ giảm các mục mà người dùng có thể nhìn thấy. Giả định của bạn là:

dịch vụ vi mô và hệ thống ủy quyền của họ không nên bị làm phiền với nhu cầu của khách hàng, vì họ chỉ là người tiêu dùng và không phải là một phần của hệ thống

Tôi thấy ở đây có hai vấn đề nghiêm trọng đối với doanh nghiệp nghiêm trọng:

  • Điều gì sẽ xảy ra nếu một số người dùng lừa đảo ngoài đó (ví dụ như ở một trong các nhà máy của đối tác của bạn) đảo ngược các ứng dụng khách và tìm hiểu về API, tránh các hạn chế mà công ty của anh ta đã đưa ra cho khách hàng và sử dụng thông tin đó để gây hại cho công ty của bạn? Công ty của bạn sẽ yêu cầu bồi thường thiệt hại, nhưng công ty parnter sẽ lập luận rằng bạn không cung cấp phương tiện để bảo vệ dữ liệu của bạn đủ tốt.
  • Thông thường, vấn đề chỉ là thời gian mà dữ liệu nhạy cảm bị sử dụng sai (hoặc kiểm toán sẽ phát hiện ra rủi ro) và cuối cùng quản lý của bạn sẽ yêu cầu kiểm soát chặt chẽ hơn dữ liệu đó.

Đây là lý do tại sao tôi khuyên bạn nên dự đoán các sự kiện như vậy và quan tâm đến các yêu cầu ủy quyền. Bạn đang trong giai đoạn tái cấu trúc sớm và sẽ dễ dàng hơn nhiều khi tính đến những điều này trong kiến ​​trúc của bạn (ngay cả khi bạn không thực hiện tất cả) so với sau này.

Nếu bạn theo đuổi vị trí hiện tại của mình, hãy tham khảo ý kiến ​​ít nhất là nhân viên an ninh thông tin của bạn.

Làm thế nào để thực hiện nó

Bạn có mẹo:

Với cách này, chúng tôi sẽ chỉ phải theo dõi phạm vi mã thông báo.

Ok, bạn có ý định sử dụng một số mã thông báo chung do khách hàng chọn. Lại một điểm yếu trong mắt tôi, bởi vì một số khách hàng có thể nằm ngoài tầm kiểm soát của bạn.

Tôi không biết nếu bạn đã sử dụng JWT hoặc nếu bạn sử dụng một số kỹ thuật khác. Nhưng nếu bạn sử dụng JWT, bạn có thể có mã thông báo nhận dạng mang danh tính của người dùng (và thậm chí là mã thông báo thứ hai xác định an toàn ứng dụng gốc, có thể cho phép bạn phân biệt mức độ tin cậy giữa khách hàng nội bộ và khách hàng bên ngoài ).

Khi bạn định sử dụng kiến ​​trúc microservice, tôi muốn đề xuất cải thiện sự khác biệt giữa quy trình xác thực và quản lý người dùng (nên chạy như một dịch vụ chuyên dụng) và kiểm soát truy cập (dành riêng cho từng microservice và nên được xử lý cục bộ bởi mỗi người trong số họ). Tất nhiên một số khách hàng quản trị nên cung cấp một cái nhìn tổng quan toàn diện về một số dịch vụ, để dễ sử dụng).


1
Lời khuyên rất tốt ở đây. Tôi thích ý tưởng với mã thông báo thứ hai.
Robert

1

Ở đây, có một câu trả lời ngắn quá. Bạn nên tự mình thực hiện tất cả các tính năng cốt lõi mà bạn muốn cung cấp cho "khách hàng" của mình. Có vẻ như có vấn đề khi khách hàng thêm hành vi cơ bản như quyền của người dùng, vì bạn đã thực hiện xác thực người dùng; nếu bạn để nó cho máy khách thực hiện nó, bạn có thể sẽ "hỗ trợ" nhiều triển khai của cùng một mã quyền. Mặc dù bạn không "sở hữu nó", nhưng sẽ có lỗi trong mã của họ và bạn muốn khách hàng của mình có chức năng mà họ mong đợi, vì vậy, bạn ủng hộ giải quyết các vấn đề mà khách hàng đang gặp phải. Hỗ trợ nhiều cơ sở mã là không có niềm vui.

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.