Saturday, August 7, 2021

OAuth2 là gì ? Nó được hoạt động như thế nào ?

 OAuth2 hiện tại đang vẫn được các nền tảng xã hội lớn như Twitter, Facebook hay Google sử dụng. Vậy OAuth2 là gì? Nó được hoạt động như thế nào ? Chúng ta cùng tìm hiểu ở bài viết này nhé.



OAuth2 là gì?

Đầu tiên chúng ta cùng tìm hiểu OAuth là gì ? OAuth là viết tắt của Open Authentication hoặc Open Authorization, là một phương thức xác thực các ứng dụng có thể chia sẻ tài nguyên với nhau mà không cần chia sẻ thông tin về username và password như những cách truyền thống. 

Và như ở trên mình đã nói OAuth là viết tắt của Open Authentication hoặc Open Authorization. Với nghĩa Open Authentication nghĩa là xác thực người dùng thông qua việc đăng nhập. Còn với nghĩa là Open Authorization nghĩa là cấp quyền để có thể truy cập vào các resource do đó nếu chúng ta có 1 tài khoản Facebook thì có thể truy cập vào được nhiều ứng dụng khác nhau mà không cần đăng ký một tài khoản mới của ứng dụng đó.

Quá trình phát triển

  • Năm 2006, Twitter đưa ra chuẩn OAuth đầu tiên có tên là OpenID, điểm yếu đó là yêu cầu người dùng phải cung cấp thông tin cá nhân (username + password).
  • Năm 2010, phát hành phiên bản chính thức đầu tiên của Oauth 1.0 (RFC 5849).
  • Sau đó lỗi bảo mật nghiêm trọng được phát hiện với tên gọi Session Fixation cho phép Hacker chiếm quyền truy cập vào tài nguyên của người dùng.
  • Năm 2012, OAuth2 ra đời, tuy vẫn còn những lỗi bảo mật như dùng Chrome để Hack Facebook nhưng hiện vẫn đang được sử dụng khá rộng rãi.

Basic authentication

Thời kì đầu, việc chia sẻ tài nguyên với ứng dụng bên thứ 3 là chưa nhiều, nên khi cần phải thực hiện chuyện đó, ta chỉ dùng phương thức xác thực đơn giản nhất là Basic authentication, implement của nó cũng diễn ra theo chiều hướng trực giác, tự nhiên nhất. Flow cơ bản của nó là : khi client cần truy xuất dữ liệu (resource) trên server, server sẽ yêu cầu phía client nhập thông tin xác thực ( thường là username, password) của resource owner . Nếu như bạn là resource owner, và bạn muốn chia sẻ dữ liệu của mình với bên thứ 3 nũa, bạn sẽ phải chia sẻ cho họ thông tin xác thực . Việc làm này, có thể dễ dàng thấy, tuy đơn giản, dễ áp dụng, nhưng tiềm tàng nhiều nguy cơ về mặt bảo mật :

  • Thứ nhất là để làm việc này yêu cầu bên thứ 3 phải có khả năng lưu trữ thông tin xác thực của bạn để có thể sử dụng bất kì khi nào.

  • Thứ hai , khi bạn chia sẽ tài nguyên theo cách này, bạn không thể nào giới hạn mức độ chia sẻ tới đâu. Server ko thể phân biệt được đối tượng đang trả lời yêu cầu xác thực là resource owner, hay là bên thứ 3, và như vậy, bên thứ 3 sẽ có toàn quyền với dữ liệu của bạn.

  • Tiếp đến, giả sử bạn chia sẻ thông tin xác thực của mình với nhiều bên thứ 3 khác nhau, khi muốn thu hồi lại quyền truy cập dữ liệu đã chia sẻ, bạn sẽ phải thu hồi lại với tất cả.

Rõ ràng, nếu cứ làm thế này thì không ổn chút nào. Cùng với sự phổ biến của việc chia sẻ tài nguyên giữa các ứng dụng, nhu cầu đặt ra lúc này là phải có một cách thức nào đó để chia sẻ tài nguyên cho bên thứ 3, mà không cần phải chia sẻ password của người dùng. Đó cũng chính là tư tưởng cốt lõi của chuẩn OAuth. Phiên bản đầu tiên của OAuth là OAuth 1.0 , và OAuth 1.0 chỉ là một giao thức (protocol). Do trọng tâm của bài viết ko phải là OAuth 1.0, nên xin được không đi vào chi tiết, ta có thể hiểu một cách tóm tắt như thế này : để thực hiện xác thực theo giao thức OAuth 1.0, ta cần phải qua 3 bước :

  • Client sẽ gọi lên Authorization Server để xin xác nhân tạm thời (temporary credentials)

  • Mở một webpage với thông tin xác nhân tạm thời đó, để user ( resource owner ) đăng nhập vào server và trao quyền truy cập cho phía client. Sau đó redirect về client, dựa theo thông tin callback gắn kèm trong request đầu tiên, gửi theo thông tin token tạm thời.

  • Gọi lên Authorization Server một lần nữa, sử dụng cả xác nhân tạm thời và token tạm thời. Server lúc này sẽ trả về cho client access token. Sử dụng token này, client từ đó về sau có thể truy cập thông tin dữ liệu của user (resource owner), cho tới khi nào resource owner rút lại quyền truy cập ( revoke ) của access token đó thì thôi.

Giao thức OAuth 1.0 ( và bản nâng cấp OAuth 1.0a ) đã giải quyết được bài toán ban đầu đặt ra, là chia sẻ quyền truy cập dữ liệu của resource owner với bên thứ 3, mà không cần phải chia sẻ thông tin xác thực (credentials). Resource owner có thể chia sẻ với nhiều bên thứ 3 khác nhau, và khi cần, có thể rút lại quyền này của một hay nhiều client tùy chọn. Tuy nhiên, khi sử dụng giao thức này, người ta sớm nhận thấy một vài điểm yếu mới phát sinh của nó :

  • Cách thức implements khá phức tạp, khiến cho việc thực thi đôi khi không thuận lợi.

  • Khi cấp access token, ta không thể quy định xem đến khi nào thì token này hết hạn, không còn giá trị sử dụng.

  • Không có phân quyền chi tiết cho mỗi token, ví dụ như token1 chỉ được thực hiện những hành động abc trên loại tài nguyên xyz, còn token2 thì lại có quyền def trên tài nguyên ftg ....

Và đề giải quyết bài toán đó, thì các nhà hoạch định internet đã xây dựng chuẩn OAuth 2.0, và cũng là trọng tâm của bài viết này. Bản draft đầu tiên của OAuth 2.0 ra đời vào năm 2010, và đã có nhiều dịch vụ áp dụng phiên bản này từ ngày đó, nhưng phải đến năm 2012, chuẩn OAuth 2.0 hoàn chỉnh mới chính thức được ra mắt. Khác với OAuth 1.0 là một giao thức (protocol), OAuth 2.0 được định nghĩa là một framework. Trong chuẩn 2.0, client không chỉ được quyền truy xuất dữ liệu nhân danh resource owner, mà clients có thể nhân danh chính mình. Qua đó, việc phân quyền cụ thể cho từng clients cũng có thể thực hiện được. Nhưng cũng chính vì những khác biệt đó, mà chuẩn OAuth2.0 ko tương thích với OAuth 1.0.


Một số khái niệm cơ bản

Khi làm việc với OAuth2 các bạn sẽ cần phải biết các khái niệm cơ bản như sau:

  • Resoure Owner: là chủ sở hữu của dữ liệu mà ta muốn chia sẻ. Ví dụ bạn muốn chia sẻ các thông tin như email, ngày sinh, giới tính, địa chỉ cho một trang web nào đó thì chúng ta có thể đăng nhập trang web đó bằng Facebook thì những thông tin như email, ngày sinh, giới tính và địa chỉ là những tài nguyên cần chia sẻ và Resource Owner lúc này chính là bạn
  • Resource Server: là server lưu trữ những thông tin mà ta chia sẻ. Server này phải có khả năng nhận và trả lời các yêu cầu (request) truy xuất dữ liệu. Như ở ví dụ trên của chúng ta thì resource server chính là Facebook.
  • Client: Là những ứng dụng muốn sử dụng những tài nguyên mà ta chia sẻ. Và chúng ta có thể thấy là ở ví dụ trên Client sẽ là trang web muốn các thông tin cá nhân của ta.
  • Authorization Server: Là đối tượng quyết định việc cấp quyền truy cập vào dữ liệu cho client. Như trong ví dụ trên, đây chính là authorization server của Facebook. Đôi khi resource server và authorization server có thể là một , nhưng về mặt chức năng mà nói, đây là 2 chức năng hoàn toàn riêng biệt.

OAuth2 hoạt động như thế nào?

Sau khi đã tìm hiểu xong các khái niệm cơ bản trên, chúng ta cùng tìm hiểu cách hoạt động của OAuth2 nhé. Khi bạn đăng nhập với Facebook (Google) thì trang web sẽ dẫn bạn tới trang của Facebook hoặc Google và liệt kê một số các quyền trang web đó muốn bạn chia sẻ. Như ví dụ ở trên thì website sẽ yêu cầu bạn cung cấp các thông tin như email, ngày sinh, giới tính, địa chỉ. Nếu bạn đồng ý cung cấp những thông tin đó thì mới có thể đăng nhập để sử dụng các dịch vụ của website đó.

Khi bạn đồng ý cung cấp các quyền đó, Facebook sẽ sinh ra một AccessToken cho các quyền đó và website đấy có thể sử dụng được. Do đó nếu có kẻ xấu muốn đánh cắp tài khoản của bạn từ website kia thì cũng chỉ lấy được những thông tin đó mà không lấy đưoc tài khoản của bạn, không ảnh hưởng tới các ứng dụng khác bạn đang sử dụng.

Sơ đồ luồng hoạt động của OAuth2

Từ ví dụ trên chúng ta có thể hình dung ra OAuth2 sẽ được hoạt động theo luồng như sơ đồ dưới đây:

OAuth2
  • Ứng dụng yêu cầu ủy quyền để truy cập vào Resource Server (Gmail,Facebook, Twitter hay Github…) thông qua User
  • Nếu User ủy quyền cho yêu cầu trên, Ứng dụng sẽ nhận được ủy quyền từ phía User (dưới dạng một token string)
  • Ứng dụng gửi thông tin định danh (ID) của mình kèm theo ủy quyền của User tới Authorization Server
  • Nếu thông tin định danh được xác thực và ủy quyền hợp lệ, Authorization Server sẽ trả về cho Ứng dụng access_token. Đến đây quá trình ủy quyền hoàn tất.
  • Để truy cập vào tài nguyên (resource) từ Resource Server và lấy thông tin, Ứng dụng sẽ phải đưa ra access_token để xác thực.
  • Nếu access_token hợp lệ, Resource Server sẽ trả về dữ liệu của tài nguyên đã được yêu cầu cho ứng dụng đó.

Authorization Request & Grant

Authorization grant thể hiện sự chấp thuận của resource owner cho phép client truy cập vào protected resource. Tùy vào mối quan hệ giữa client với resource owner, cũng như tính chất của client , OAuth 2.0 có định nghĩa các loại grant type phù hợp cho đa số các tình huống, cũng như hỗ trợ định nghĩa thêm custom grant type. Về cơ bản, ta có 4 loại grant sau, tìm hiểu sâu về mỗi loại này sẽ là nội dung của bài viết phần tới.

Authorization Code
Implicit Grant
Resource Owner Password Credentials
Client Credentials

Ưu điểm của OAuth2

  • OAuth 2.0 là một giao thức rất linh hoạt dựa trên SSL (Secure Sockets Layer đảm bảo dữ liệu giữa máy chủ web và trình duyệt vẫn giữ được tính riêng tư) để lưu token truy cập của người dùng.
  • Cho phép truy cập hạn chế vào dữ liệu của người dùng và cho phép truy cập khi authorization token hết hạn.
  • Có khả năng chia sẻ dữ liệu cho người dùng mà không phải tiết lộ thông tin cá nhân.
  • Dễ dàng hơn để thực hiện và cung cấp xác thực mạnh mẽ hơn.

Tại sao chúng ta nên sử dụng OAuth2

  • Để đọc dữ liệu của người dùng từ một ứng dụng khác.
  • Nó cung cấp quy trình authorization cho web, ứng dụng máy tính để bàn và thiết bị di động.
  • Đây là một ứng dụng web phía máy chủ sử dụng authorization code và không tương tác với thông tin đăng nhập của người dùng.

No comments:

Post a Comment

So sánh các GitFlow model và áp dụng với CICD

https://medium.com/oho-software/so-s%C3%A1nh-c%C3%A1c-gitflow-model-v%C3%A0-%C3%A1p-d%E1%BB%A5ng-v%E1%BB%9Bi-cicd-b6581cfc893a