Mở đầu

Chắc nhiều bạn đã nghe đến khái niệm oauth. Về cơ bản thì oauth là một phương thức chứng thực, mà nhờ đó một web service hay một application bên thứ 3 có thể đại diện cho người dùng để truy cập vào tài nguyên người dùng nằm trên một dịch vụ nào đó. Các trào lưu cũng như sự lan rộng của khái niệm oauth bắt đầu khi mà các dịch vụ mạng xã hội như twitter hay facebook nở rộ, đặc biệt khi các công ty như twitter cung cấp API cho bên thứ 3 để có thể truy cập vào tài nguyên của người dùng, qua đó mở nên một thị trường mới gọi là 3rd party app.

Lịch sử

Oauth xuất hiện vào năm 2006, khi mà twitter phát triển hệ thống openId của họ , họ đã thống nhất nhiều bên gồm có facebook và google để thống nhất một “chuẩn” nhằm giúp cho application của bên thứ 3 có thể truy cập API của họ một cách dễ dàng hơn. Sau đó vào năm 2008, IETF (tổ chức chuyên đưa ra các chuẩn của internet) đã quyết định hỗ trợ cho chuẩn này, nhằm đưa ra một qui chuẩn thống nhất. Việc này dẫn đến bản RFC chính thức đầu tiên của oauth 1.0 vào năm 2010 (RFC 5849).

Sau đó xảy ra một sự kiện không ngờ khi có một lỗi bào mật khá nghiệm trọng xảy ra trên oauth1, gọi là session fixation. Lỗi này giúp cho attacker có thể “trick” cho một application thuộc bên thứ 3 “trao” cho hắn cái quyền để access vào account/resource của một ai đó bất kì. Bạn có thể tưởng tượng tài khoản facebook của bạn đang được ai đó ung dung sử dụng mà bạn không hề biết.

Sự kiện này dẫn đến sự ra đời của oauth2 vào 2012. Vào thời gian đầu thì oauth2 cũng có không ít lỗi bảo mật, ví dụ như bạn có thể sử dụng chrome để hack facebook . Cho đến hiện nay thì các chuyên gia an ninh mạng vẫn đang cảnh báo hàng ngày về các khe hở bảo mật của oauth2, tuy nhiên oauth2 vẫn được sử dụng rộng rãi. Về cơ bản thì oauth2 không chỉ đơn thuần là một protocol mà nó là một “nền tảng” mà ở đó bạn phải implement cả phía server vẫn client. Ở dưới đây mình sẽ trình bày kĩ hơn về oauth2

Mô hình cơ bản Oauth2.0

Mô hình cơ bản của oauth 2.0 có thể được hiểu qua mô hình dưới đây được lấy ra từ RFC

 +--------+                               +---------------+
 |        |--(A)- Authorization Request ->|   Resource    |
 |        |                               |     Owner     |
 |        |<-(B)-- Authorization Grant ---|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(C)-- Authorization Grant -->| Authorization |
 | Client |                               |     Server    |
 |        |<-(D)----- Access Token -------|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(E)----- Access Token ------>|    Resource   |
 |        |                               |     Server    |
 |        |<-(F)--- Protected Resource ---|               |
 +--------+                               +---------------+

Ở trên mô hình trên :

  • Resource owner là người dùng, chính là bạn
  • Client là application bên thứ 3, bạn có thể hình dung là 1 ứng dụng sử dụng facebook api chẳng hạn
  • Authrization Server và Resource Server là những dịch vụ mà phía bên facebook hay twitter phải implement để thực hiện oauth. Đây chính là điểm cơ bản tạo nên khác biệt giữa Oauth2 và Oauth1, khi “tách biệt” giữa việc chứng thực (authorization) , và việc cung cấp thông tin người dùng (resource) thành 2 server riêng.

Trong thực tế: Bạn là người dùng của facebook, bạn có các tài nguyên cá nhân của mình như là ảnh profile, số điện thoại Tôi là người viết app sử dụng facebook API, tôi muốn truy cập vào các tài nguyên trên facebook của bạn để viết phần mềm Cách Oauth giải quyết vấn đề trên Như vậy chúng ta có thể hiểu có 3 bên, tôi, bạn và facebook, oauth chính là 1 cách để 3 bên nói chuyện với nhau một cách mềm dẻo, sao cho bạn có thể trao cho tôi quyền được truy cập vào các tài nguyên của bạn trên facebook.

  • Step 1: Tôi sẽ hỏi bạn là: bạn cho tôi xin quyền truy cập vào profile cá nhân của bạn
  • Step 2: Bạn trả lời có thông qua một hình thức nào đó mà facebook kiểm soát được (ví dụ như một màn hình chứng thực do facebook cung cấp chẳng hạn!)
  • Step 3: Facebook nhận được sự đồng ý đó, và sẽ trao cho tôi một cái “chìa khoá” để có thể truy cập vào một số tài nguyên nhất định của bạn.
  • Step 4: Tôi sẽ dùng “chìa khoá” đó để truy cập vào tài nguyên của bạn.

Oauth 3-legged và 2-legged

Trước khi đi vào cụ thể thì chúng ta phải làm quen với một khái niệm gọi là flow chứng thực Client Credentials . Flow này có thể hiểu đơn giản là Step 1 và 2 ở trên, tức là: làm thế nào để bạn nói cho facebook được là bạn trao quyền cho tôi access vào profile của bạn?

Phần thứ 2 trong mô hình ở trên

 +---------+                                  +---------------+
 |         |                                  |               |
 |         |>--(A)- Client Authentication --->| Authorization |
 | Client  |                                  |     Server    |
 |         |<--(B)---- Access Token ---------<|               |
 |         |                                  |               |
 +---------+                                  +---------------+

phần này chính là Client Credentials Flow Mục đích chính của flow này là để cho bên cung cấp dịch vụ (facebook) biết được là bạn “đã” cung cấp cho “tôi” quyền được truy cập thông tin của bạn. Thông tin này có thể được cung cấp tại lúc mà tôi hỏi bạn, hoặc có thể được cung cấp “trước” tại một thời điểm nào đó. Chính sự khác biệt này tạo ra 2 cách làm khác nhau là 3-legged và 2-legged oauth.

Oauth 3-legged

Đây chính là flow phổ thông cho mô hình oauth2 hiện nay. Client Credentials Flow sẽ được thực hiện thông qua việc redirect người dùng đến website của bên cung cấp dịch vụ, người dùng sẽ lựa chọn có hoặc không đồng ý (bạn có thể gợi nhớ lại khi bạn đăng nhập vào facebook app lần đầu tiên, facebook sẽ cho bạn một form để chọn có/không). Sau đó dựa vào redirect_uri mà “tôi” cung cấp trước đó cho facebook, facebook sẽ redirect-back lại dịch vụ của “tôi”, kèm theo một token đã được chứng thực. Sau cùng “tôi” sẽ sử dụng token đó như “chìa khoá” để truy cập vào profile của bạn

Flow chứng thực này yêu cầu cả 3 bên: “bạn”, “tôi”, và “facebook”, do đó mà nó được gọi là 3-legged. Mô hình 3-legged oauth2:

Oauth 2-legged

Vậy nếu tôi là một ứng dụng được facebook tin tưởng “hoàn toàn” thì sao. Ví dụ tôi là CEO của instagram chẳng hạn. Vậy thì cần gì bạn phải accept cho tôi truy cập tài nguyên của bạn trên facebook . Hoặc một ví dụ khác là tôi làm một widget của google app và bạn cho tôi quyền sử dụng gmail account của bạn. Trong những trường hợp trên thì flow redirect đi redirect lại như ở trên là không cần thiết, khi đó thì chỉ cần tôi nói chuyện trực tiếp với bên cung cấp dịch vụ là tôi cần thông tin của bạn thôi là đủ. Việc cấp quyền của bạn cho tôi có thể được thực hiện tại một thời điểm bất kỳ như lúc bạn cài đặt app của tôi vào desktop chẳng hạn (pre-installed app)

Mô hình này không cần bạn, chỉ cần “tôi” và “facebook”, do đó mà nó được gọi là 2-legged

Một số vấn đề của oauth2

Oauth2 không chỉ là một “protocol” mà còn là một “framework”, đòi hỏi bạn phải implement cả ở phía server và client. Ngoài ra việc oauth2 tách authorization server và resource server ra cũng khiến cho việc implement khá là mất công nếu làm từ đầu. Ngoài ra thì Oauth2 cũng có khá nhiều nhược điểm , đặc biệt là liên quan đến security. Tuy nhiên việc các công ty đứng đầu như facebook, twitter hay google đi tiên phong trong việc implement oauth2 khiến chúng ta không thể tránh khỏi cái framework này, nên việc hiểu rõ nó là khá quan trọng.