Câu trả lời cho câu hỏi của bạn có thể ở cấp mã, cấp giao thức hoặc cấp kiến trúc. Tôi sẽ cố gắng tóm tắt ở đây hầu hết các vấn đề ở cấp độ giao thức vì điều đó thường rất quan trọng trong phân tích ưu và nhược điểm. Hãy nhớ rằng OAuth2 nhiều hơn Thông tin mật khẩu của chủ sở hữu tài nguyên , theo thông số kỹ thuật, tồn tại vì "lý do di sản hoặc di chuyển", được coi là "rủi ro cao hơn các loại cấp khác" và thông số kỹ thuật nêu rõ rằng máy khách và máy chủ ủy quyền "NÊN giảm thiểu việc sử dụng loại tài trợ này và sử dụng các loại tài trợ khác bất cứ khi nào có thể".
Vẫn còn nhiều ưu điểm của việc sử dụng ROPC so với xác thực cơ bản nhưng trước khi chúng ta hiểu rõ về điều đó, hãy hiểu sự khác biệt về giao thức cơ bản giữa OAuth2 và xác thực cơ bản. Hãy đồng ý với tôi khi tôi giải thích những điều này và sẽ đến ROPC sau.
Luồng xác thực người dùng
Có bốn vai trò được xác định trong đặc tả OAuth2. Với các ví dụ, chúng là:
- Chủ sở hữu tài nguyên: Người dùng có quyền truy cập vào một số tài nguyên, ví dụ trong trường hợp của bạn, những người dùng khác nhau có thể có mức truy cập khác nhau đối với API REST;
- Máy khách: thường là ứng dụng mà người dùng đang sử dụng và cần quyền truy cập vào tài nguyên để cung cấp dịch vụ cho người dùng;
- Máy chủ tài nguyên: API REST trong trường hợp của bạn; và
- Máy chủ ủy quyền: máy chủ mà thông tin đăng nhập của người dùng được trình bày và sẽ xác thực người dùng.
Khi một ứng dụng khách chạy, nó được cấp quyền truy cập vào các tài nguyên dựa trên người dùng. Nếu người dùng có đặc quyền của quản trị viên, tài nguyên và thao tác có sẵn cho người dùng trong API REST có thể nhiều hơn người dùng không có đặc quyền của quản trị viên.
OAuth2 cũng cho phép khả năng sử dụng một máy chủ ủy quyền duy nhất có nhiều máy khách và cho nhiều tài nguyên. Ví dụ, một máy chủ tài nguyên có thể chấp nhận xác thực người dùng với Facebook (có thể đóng vai trò là máy chủ ủy quyền trong trường hợp đó). Vì vậy, khi người dùng chạy một ứng dụng (tức là máy khách), nó sẽ gửi người dùng đến Facebook. Người dùng nhập thông tin đăng nhập của họ vào Facebook và khách hàng sẽ nhận lại "mã thông báo" mà nó có thể hiển thị cho máy chủ tài nguyên. Máy chủ tài nguyên nhìn vào mã thông báo và chấp nhận nó sau khi xác minh rằng trên thực tế Facebook đã phát hành nó và cho phép người dùng truy cập vào tài nguyên. Trong trường hợp này, khách hàng không bao giờ thấy thông tin đăng nhập của người dùng (tức là thông tin đăng nhập Facebook của họ).
Nhưng giả sử bạn đang quản lý danh tính người dùng của mình (và có máy chủ ủy quyền) thay vì Facebook, nơi đã cấp mã thông báo cho khách hàng của bạn. Bây giờ, giả sử bạn cũng có một đối tác và bạn muốn cho phép ứng dụng của họ (tức là khách hàng) truy cập API REST của bạn. Với xác thực cơ bản (hoặc thậm chí ROPC), người dùng sẽ cung cấp thông tin đăng nhập cho khách hàng đó sẽ gửi nó đến máy chủ ủy quyền. Máy chủ ủy quyền sau đó sẽ cung cấp mã thông báo mà khách hàng có thể sử dụng để truy cập tài nguyên. Thật không may, điều này có nghĩa là thông tin đăng nhập của người dùng cũng hiển thị cho khách hàng đó. Tuy nhiên, bạn sẽ không muốn ứng dụng của đối tác (người có thể ở bên ngoài tổ chức của bạn) thậm chí biết mật khẩu của người dùng. Đó là một vấn đề bảo mật bây giờ. Để đạt được mục tiêu đó,
Do đó, với OAuth2, lý tưởng nhất là không sử dụng ROPC trong các trường hợp như vậy thay vì sử dụng một mã khác, chẳng hạn như luồng mã ủy quyền. Điều này bảo vệ bất kỳ ứng dụng nào biết thông tin đăng nhập của người dùng chỉ được trình bày cho máy chủ ủy quyền. Do đó, thông tin đăng nhập của người dùng không bị rò rỉ. Các vấn đề tương tự áp dụng với xác thực cơ bản, nhưng trong phần tiếp theo, tôi sẽ giải thích cách ROPC vẫn tốt hơn vì thông tin đăng nhập của người dùng vẫn không cần được khách hàng lưu trữ trong ROPC để khách hàng truy cập liên tục.
Lưu ý rằng khi người dùng đến máy chủ ủy quyền, máy chủ ủy quyền cũng có thể yêu cầu người dùng xác nhận rằng họ có muốn cho phép khách hàng truy cập tài nguyên thay mặt họ hay không. Đó là lý do tại sao nó được gọi là máy chủ ủy quyền vì quá trình ủy quyền cho khách hàng truy cập tài nguyên được yêu cầu trong quy trình. Nếu người dùng không ủy quyền cho khách hàng, họ sẽ không có quyền truy cập vào tài nguyên. Tương tự, nếu bản thân người dùng không có quyền truy cập vào tài nguyên, máy chủ ủy quyền vẫn có thể từ chối quyền truy cập và không phát hành mã thông báo.
Trong xác thực cơ bản, ngay cả máy chủ ủy quyền và máy chủ tài nguyên được kết hợp thành một thực thể duy nhất. Vì vậy, máy chủ tài nguyên muốn ủy quyền cho người dùng, vì vậy hãy hỏi thông tin đăng nhập từ máy khách. Máy khách cung cấp những thông tin được sử dụng bởi máy chủ tài nguyên để xác thực người dùng. Điều này có nghĩa là nhiều máy chủ tài nguyên về cơ bản sẽ yêu cầu thông tin đăng nhập từ người dùng.
Phát hành mã thông báo
Các khách hàng nhận mã thông báo từ máy chủ ủy quyền, giữ chúng xung quanh và sử dụng chúng để truy cập tài nguyên (chi tiết hơn về chính mã thông báo bên dưới). Các khách hàng không bao giờ biết mật khẩu của người dùng (trong các luồng khác ngoài ROPC) và không cần lưu trữ mật khẩu. Trong ROPC, mặc dù khách hàng biết mật khẩu của người dùng, họ vẫn không cần lưu trữ vì họ sử dụng các mã thông báo này để truy cập tài nguyên. Ngược lại, trong xác thực cơ bản, nếu khách hàng không muốn người dùng cung cấp thông tin đăng nhập trong mỗi phiên, thì khách hàng phải lưu trữ mật khẩu của người dùng để họ có thể cung cấp mật khẩu vào lần sau. Đây là một nhược điểm lớn đối với việc sử dụng xác thực cơ bản trừ khi máy khách chỉ là một ứng dụng web trong trường hợp đó, cookie có thể giải quyết một số vấn đề này. Với các ứng dụng gốc, đó thường không phải là một lựa chọn.
Có một khía cạnh khác của OAuth2 liên quan đến cách phát hành mã thông báo và chúng hoạt động. Khi người dùng cung cấp thông tin đăng nhập cho máy chủ ủy quyền (ngay cả trong ROPC), máy chủ ủy quyền có thể cung cấp một hoặc nhiều loại mã thông báo: 1) mã thông báo truy cập và 2) mã thông báo làm mới.
Mã thông báo truy cập được gửi đến máy chủ tài nguyên sẽ cấp quyền truy cập vào tài nguyên sau khi xác thực nó và thông thường chúng có thời gian tồn tại ngắn, ví dụ 1 giờ. Mã thông báo làm mới được khách hàng gửi đến máy chủ ủy quyền để nhận mã thông báo truy cập khác khi hết hạn và thường có tuổi thọ lớn (ví dụ: vài ngày đến vài tháng hoặc thậm chí nhiều năm).
Khi khách hàng cung cấp mã thông báo truy cập đến máy chủ tài nguyên, nó sẽ xem xét mã thông báo và sau khi xác thực, nhìn vào bên trong mã thông báo để xác định xem có cho phép truy cập hay không. Miễn là mã thông báo truy cập là hợp lệ, khách hàng có thể tiếp tục sử dụng nó. Giả sử người dùng đóng ứng dụng và khởi động vào ngày hôm sau và mã thông báo truy cập đã hết hạn. Bây giờ, khách hàng sẽ thực hiện cuộc gọi đến máy chủ ủy quyền và đưa ra mã thông báo làm mới giả sử rằng nó chưa hết hạn. Máy chủ ủy quyền, vì nó đã phát hành mã thông báo, xác minh nó và có thể xác định rằng người dùng không cần cung cấp lại thông tin đăng nhập và do đó cung cấp mã thông báo truy cập khác cho khách hàng. Bây giờ khách hàng có quyền truy cập vào máy chủ tài nguyên. Đây là cách thông thường các ứng dụng khách cho Facebook và Twitter yêu cầu thông tin đăng nhập một lần và sau đó không yêu cầu người dùng cung cấp thông tin đăng nhập lại. Các ứng dụng này không bao giờ cần biết thông tin đăng nhập của người dùng và vẫn có thể truy cập tài nguyên mỗi khi người dùng khởi động ứng dụng.
Giờ đây, người dùng có thể vào máy chủ ủy quyền (ví dụ: trong hồ sơ người dùng Facebook của họ), thay đổi mật khẩu mà không ảnh hưởng đến bất kỳ ứng dụng khách nào. Tất cả chúng sẽ tiếp tục hoạt động đúng. Nếu người dùng mất thiết bị mà họ đã có ứng dụng có mã thông báo làm mới, họ có thể yêu cầu máy chủ ủy quyền (ví dụ: Facebook) "đăng xuất" chúng khỏi các ứng dụng mà máy chủ ủy quyền (ví dụ Facebook) sẽ thực hiện bằng cách không tôn trọng bất kỳ ứng dụng nào hiện có làm mới mã thông báo và buộc người dùng cung cấp thông tin đăng nhập một lần nữa khi họ cố gắng truy cập tài nguyên thông qua các ứng dụng đó.
JWT đơn giản là định dạng mã thông báo thường được sử dụng với OAuth2 và OpenID Connect. Các phương thức ký mã thông báo và xác thực nó cũng được chuẩn hóa với các thư viện có sẵn cho các thư viện thay vì mọi máy chủ tài nguyên triển khai một giải pháp khác. Do đó, lợi thế nằm ở khả năng sử dụng lại mã đã được hiệu đính và tiếp tục được hỗ trợ.
Ý nghĩa bảo mật
Xác thực cơ bản sẽ yếu hơn khi có bất kỳ kịch bản nào ở trên. Ngoài ra còn có một mô hình mối đe dọa rộng rãi cho OAuth2 dành cho các nhà phát triển có thể sử dụng các đề xuất trong đó để tránh các lỗ hổng phổ biến trong việc triển khai của họ. Nếu bạn xem qua mô hình mối đe dọa, bạn sẽ thấy rằng nhiều lỗ hổng liên quan đến triển khai (như chuyển hướng mở và CSRF) cũng được đề cập trong đó. Tôi đã không trải qua so sánh những người chống lại xác thực cơ bản trong phản hồi này.
Ưu điểm chính cuối cùng của OAuth2 là giao thức được chuẩn hóa và nhiều máy chủ ủy quyền, máy khách và máy chủ tài nguyên tôn vinh nó. Nhiều thư viện có sẵn cho các nhà phát triển, được duy trì để các vấn đề bảo mật được tìm thấy trong các triển khai, các thư viện được cập nhật trong khi cho phép khả năng tương tác.
Phần kết luận
Nếu bạn đang viết một ứng dụng mới, IMO, trường hợp lý tưởng sẽ là tránh cả xác thực cơ bản và ROPC vì các vấn đề cố hữu trong chúng. Tuy nhiên, mỗi ứng dụng có nhu cầu, mốc thời gian, trình độ của nhà phát triển khác nhau, v.v ... nên quyết định là tùy theo từng trường hợp. Nhưng ngay cả khi bạn không có nhu cầu nhiều hơn xác thực cơ bản, bằng cách chọn nó, bạn có thể tự khóa mình vào một kiến trúc có thể không dễ dàng mở rộng (ví dụ: nếu bạn có nhiều máy chủ trong tương lai, bạn không nhất thiết muốn có người dùng cung cấp thông tin đăng nhập cho từng người trong số họ thay vì chỉ cung cấp cho máy chủ ủy quyền một lần, có thể trao mã thông báo, v.v.)
Lưu ý rằng tôi đã không giải quyết nhận xét của bạn về cách thông tin đăng nhập được gửi qua mạng vì chúng có thể được bảo mật bằng TLS hoặc giao thức tương tự hoặc bằng chứng sở hữu, v.v. Như ai đó đã đề xuất, mã hóa cơ sở 64 là 0 bảo mật, vui lòng không bị lừa dối bởi điều đó. Sự khác biệt được đề cập ở trên thường ở cấp độ kiến trúc và do đó, đó là nơi tôi tập trung vì kiến trúc là khó thay đổi nhất khi được thực hiện.
Azure Active Directory B2C Basic , một dịch vụ mà tôi hoạt động và gần đây đã được phát hành để xem trước công khai, cho phép ứng dụng bên thứ ba sử dụng AAD làm máy chủ ủy quyền có khả năng tương tác với IDP xã hội (như Facebook, Google, v.v.). Nó cũng cho phép người dùng tạo tài khoản của riêng họ thay vì sử dụng IDP xã hội và những tài khoản này sau đó có thể được sử dụng cho mục đích xác thực. Có một vài dịch vụ khác cũng như vậy (ví dụ: một dịch vụ khác tôi biết là auth0) có thể được các nhà phát triển sử dụng để thuê ngoài hoàn toàn xác thực và quản lý người dùng cho các ứng dụng và tài nguyên của họ. Các đặc điểm giao thức tương tự mà tôi đã đề cập ở trên được các nhà phát triển sử dụng để tách rời máy chủ ủy quyền (AAD), tài nguyên (ví dụ: API REST), máy khách (ví dụ: ứng dụng di động của họ) và người dùng. Tôi hy vọng lời giải thích này sẽ giúp phần nào.