Hướng dẫn OAuth2 và xây dựng một Authorization Server cơ bản cho người mới bắt đầu.
OAuth2 đã trở nên rất phổ biến, vậy OAuth2 là gì, cách áp dụng như thế nào và bạn liệu rằng đã áp dụng OAuth2 đúng chưa. Trong bài này, mình sẽ chia sẻ với mọi người về OAuth2, cách và khi nào áp dụng loại grant nào.
Chắc rằng bạn cũng đã gặp nhu cầu: một user trên hệ thống của bạn muốn chia sẻ thông tin, tài nguyên của họ cho bên thứ 3.
Hãy nhìn lại quy trình xác thực của các website trước đây cũng như rất nhiều website hiện tại:
- User sử dụng username/password để đăng nhập vào hệ thống.
- Hệ thống xác thực thông tin. Nếu hợp lệ, sẽ ghi một phiên vào cookies.
- Đến khi nào phiên vẫn active thì user vẫn có thể kết nối đến hệ thống, lấy các tài nguyên của họ.
Với quy trình như vậy thì rất khó đáp ứng được nhu cầu trên mà vẫn đảm bảo bên thứ 3 không lấy được các thông tin nhạy cảm của user như password.
Nếu hệ thống áp dụng OAuth2 thì nhu cầu trên sẽ được giải quyết dễ dàng.
Giới thiệu
OAuth2 là phương thức chứng thực, cần triển khai ở cả hai phía Server và Client.
Về lịch sử phát triển các bạn có thể xem tại đây.
OAuth2 có 4 loại grant type:
- Resource Owner Password Credentials
- Authorization Code
- Implicit
- Client Credentials
Authorization Flows
Resource Owner Password Credentials
Khi nào thì sử dụng grant này?
- Chỉ nên sử dụng cho những ứng dụng thực sự được tin tưởng vì nó trực tiếp xử lý thông tin đăng nhập của người dùng.
The flow includes the following steps:
- Ứng dụng đưa ra một form cho phép người dùng nhập thông tin đăng nhập (ví dụ: username/password).
- Ứng dụng gửi thông tin đăng nhập cùng thông tin định danh của mình lên authorization server. Authorization server xác thực thông tin, trả lại access token và refresh token (nếu có).
- Ứng dụng sử dụng access token truy cập tài nguyên trên resource server.
Authorization Code
Khi nào thì sử dụng grant này?
- Sử dụng cho những ứng dụng có độ tin cậy không cao (ứng dụng của bên thứ 3 yêu cầu truy cập vào hệ thống của bạn).
The flow includes the following steps:
- Ứng dụng gửi một link đến authorization server cho người dùng để bắt đầu quá trình nhận authorization_code. Link này bao gồm các thông tin cho phép authorization server định danh và response lại cho ứng dụng.
- Người dụng điền thông tin đăng nhập.
- Thông tin đăng nhập được gửi đến authorization server.
- Authorization server xác thực thông tin của đăng nhập và redirects người dùng đến redirect_uri của ứng dụng cùng với một authorization_code.
- Ứng dụng request đến authorization server cùng authorization_code để nhận access token cùng refresh token (nếu có).
- Ứng dụng sử dụng access token truy cập tài nguyên trên resource server.
Implicit và Client Credentials
Khi nào thì sử dụng grant này?
- Thường được sử dụng trong các ứng dụng mobile hay các ứng dụng chạy trên web, nơi mà thông tin bí mật của client không thể lưu trữ bảo mật.
Flow của grant này rất giống với Authorization Code ngoại trừ phần liên quan đến authorization_code. Do lo ngại bảo mật, trong flow này, ứng dụng sẽ không nhận authorization_code từ Authorization server, thay vào đó, Authorization server sẽ trả trực tiếp access token cho ứng dụng.
Loại grant này không hỗ trợ refresh_token.
JWT (JSON Web Tokens)
Bạn có thể thấy rằng mặc dù access token được tham chiếu trong OAuth 2.0, nhưng cho đến nay rất ít thông tin đề cập đến cách tạo và sử dụng chúng. Sự thật là framework OAuth 2.0 không chỉ rõ định dạng của access token và refresh token nên sử dụng và chính các developers tự định dạng và tích hợp tokens vào authorization flows của họ. Về mặt lý thuyết, bạn có thể sử dụng một chuỗi, chuỗi này không bao giờ hết hạn để làm access token, mặc dù rõ ràng điều đó không an toàn. Tuy nhiên, trong thực tế, rất nhiều developers đã chọn sử dụng định dạng JWT (JSON Web Token). JWT độc lập, cho phép các server xác thực token mà không cần phải hỏi nguồn dữ liệu.
Một JWT bao gồm 3 phần:
- Header: mô tả loại token và thuật toán dùng để mã hoá.
- Payload: chứa dữ liệu.
- Signature: để xác minh token.
Tất cả ba phần phải được mã hoá Base64URL để chúng được transferred an toàn trong chuỗi query.
Bạn có thể dùng nhiều thuật toán hashing với JWT và payload có nhiều trường được xác định trước (còn được gọi là registered claim names). Bài này sử dụng thuật toán RS256(RSA Signature with SHA-256) và chỉ định 2 registered claims trong payload: exp (thời điểm token hết hạn), và iss (issuer). Ngoài các claims được hỗ trợ, bạn có thể định nghĩa các claims trong payload chẳng hạn như scopes của token.
Mỗi khi JWT đến server, trước tiên hệ thống sẽ phân tích JWT và xác minh xem thuật toán được chỉ định trong header có được hỗ trợ hay không; sau đó nó kiểm tra Signature để đảm bảo rằng JWT hợp lệ và cuối cùng, xác nhận rằng các claims đã đăng ký (nếu tồn tại) là hợp lệ. Trong trường hợp của hướng dẫn này, điều đó có nghĩa là đảm bảo rằng JWT chưa hết hạn (exp) và đến từ một nguồn được dự kiến trước (iss). Các custom claims, chẳng hạn như scopes, có thể được trích xuất từ token và xác thực manually.
Expiration Date and Refresh Token
Ngoài ra, các developers cần kiểm soát được lifespan của access token và việc sử dụng refresh token. Nói chung, nếu bạn xây dựng một authorization server để bảo vệ tài nguyên quan trọng, tốt hơn hết là tránh sử dụng refresh token và giữ access token trong thời gian ngắn hạn. Đối với các tài nguyên ít quan trọng hơn, bạn có thể sử dụng refresh token và để access token tồn tại lâu hơn một chút. Tránh tạo access token dài hạn để development dễ dàng hơn.
Tham khảo:
https://en.wikipedia.org/wiki/OAuth
https://medium.com/google-cloud/understanding-oauth2-and-building-a-basic-authorization-server-of-your-own-a-beginners-guide-cf7451a16f66