Wednesday, February 9, 2022

[Dev] OAuth and OpenID Connect

1. Khái niệm

OIDC (OpenID Connect ): một giao thức mở và tin cậy cho phép user xác thực (authenticate) bằng hệ thống bên ngoài ( google, facebook...)

Vd: Đăng nhập hệ thống bằng tài khoản facebook, google

OAuth (Open Authorization): một giao thức cho phép một ứng dụng lấy thông tin của user mà không cần phải biết password của user đó.

Vd:  Sau khi người dùng đã đăng nhập bằng tài khoản facebook, app sẽ lấy được thông tin facebook của user đó. Ở đây việc xác thực thuộc về phía facebook.

Note: Xác thực trước, phân quyền sau

2. OAuth 2.0

2.1 OAuth extension

Oauth bản chất là open framework, được định nghĩa một cách trừu tượng. Ở đây nó chỉ đề ra các tiêu chuẩn, nhưng không nói cụ thể các bước triển khai như thế nào. Vì vậy để áp dụng vào thực tế công việc, người ta phải cài đặt thêm một số tính năng mở rộng để đảm bảo việc truyền tải dễ dàng và an toàn. 

2.2 JWT (JSON Web Token)

Có nhiều loại token nhưng trong OAuth2, ng ta thường sự dụng dạng JWT. Bản chất JWT là 1 container JSON để chứa thông tin user. :)

Thành phần:

  • Header: loại token, thuật toán
  • Payload: chứa thông tin user
  • Signature: chữ ký mã hóa header và payload

Được encode (base64) chứ không encrypt

Các field tiêu chuẩn: iss, iat,aud, exp

More info: https://en.wikipedia.org/wiki/JSON_Web_Token

2.3 OAuth 2 + OIDC

Bản chất OIDC chạy trên nền OAuth2. Nó là một extension để bổ sung tính năng authentication cho OAuth 2. Sử dụng OpenId Connect thì nội dung của access token mà Client sử dụng để request tới Resource Server (BE) sẽ bao gồm cả thông tin user đang grant quyền truy cập tới những resources này.

OAuth2 token:

{

  "access_token": "SlAV32hkKG",

  "token_type": "Bearer",

  "refresh_token": "8xLOxBtZp8",

  "expires_in": 3600,

}

OAuth2 + OIDC token:

{

  "access_token": "SlAV32hkKG",

  "token_type": "Bearer",

  "refresh_token": "8xLOxBtZp8",

  "expires_in": 3600,

  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjFlOWdkazcifQ.ewogImlzc

    yI6ICJodHRwOi8vc2VydmVyLmV4YW1wbGUuY29tIiwKICJzdWIiOiAiMjQ4Mjg5

    NzYxMDAxIiwKICJhdWQiOiAiczZCaGRSa3F0MyIsCiAibm9uY2UiOiAibi0wUzZ

    fV3pBMk1qIiwKICJleHAiOiAxMzExMjgxOTcwLAogImlhdCI6IDEzMTEyODA5Nz

    AKfQ.ggW8hZ1EuVLuxNuuIJKX_V8a_OMXzR0EHR9R6jgdqrOOF4daGU96Sr_P6q

    Jp6IcmD3HP99Obi1PRs-cwh3LO-p146waJ8IhehcwL7F09JdijmBqkvPeB2T9CJ

    NqeGpe-gccMg4vfKjkM8FcGvnzZUN4_KSP0aAp1tOJ1zZwgjxqGByKHiOtX7Tpd

    QyHE5lcMiKPXfEIQILVq0pc_E2DzL7emopWoaoZTF_m0_N0YzFC6g6EJbOEoRoS

    K5hoDalrcvRYLSrQAZZKflyuVCyixEoV9GfNQC3_osjzw2PAithfubEEBLuVVk4

    XUVrWOLrLl0nx7RkKU8NXNHq-rvKMzqg"

}


3. OAuth 2.0 Framework - RFC 6749

3.1 Thành phần tiêu chuẩn

  • Access token
  • Refresh token
  • Scopes: được lấy những thông tin nào của user 

3.2 OAuth Grant Types

Nói về các phương pháp để lấy token

Có các loại cơ bản sau:

  • Authorization Code Flow
  • PKCE
  • Client Credentials
  • Resource Owner Password
  • Device Code

3.3 Một số endpoint chính

  • /authorize
  • /token
  • /introspect
  • /revoke
  • /info
  • /.well-known/oauth-authorization-server

3.4 ODIC scopes

  • openid: sub
  • profile
  • phone
  • offline_access: trả thêm refresh token

{

  "sub": "35666371",

  "email": "styler@onelogin.com",

  "preferred_username": "Sally",

  "name": "Sally Tyler",

  "at_hash": "znht1pnyrypkT0KdL5HqQQ",

  "rt_hash": "bKEikCYYUi6nXf4GyGnrOA",

  "aud": "78d1d040-20c9-0136-5146-067351775fae92920",

  "exp": 1523664626,

  "iat": 1523657426,

  "iss": "https://openid-connect.onelogin.com/oidc"

}


4. OAuth2 Token

4.1 JWT

  • Header: loại token, thuật toán mã hóa
  • Payload: sub, access token
  • Signature:

4.2 Validity

  • Kiểm tra header
  • Kiểm tra payload
  • Kiểm tra Signature

*Tip: nên sử dụng thư viện để làm việc này

4.3 Access token và Refresh Token

Phải bảo mật refresh token

4.4 Id token

Token JWT chứa profile

Token = Access token + id token

4.5 Các vấn đề về an toàn

  • Lưu trữ dữ liệu cẩn thận
  • Chỉ lấy dữ liệu cần thiết
  • Xóa dữ liệu khi được yêu cầu
  • Nếu token dùng để truy xuất dữ liệu quan trọng thì nên để thời gian hết hạn ngắn.
  • Bảo mật refresh token


5. Grant type: Authorization code

Đổi authorization code để lấy access token.

Có hỗ trợ refresh token

5.1 Flow

1. Client request đến Auth server

2. Client đăng nhập thành công

3. Auth server gửi auth code cho client

4. Client gửi auth code, client id, client secret cho auth server để lấy token

5. Client sử dụng access token này để truy cập


6. Grant type: PKCE (Proof Key for Code Exchange)

Client secret không tham gia quá trình xác thực

6.1 Flow

1. Client tạo code verifier (>43 kí tự)

2. Client tạo code challenge Base64(SHA256(code verifier)))

3. Client gửi code challenge đến Auth server để xác thực

4. Nếu xác thực thành công, Auth server gửi auth code về cho client

5. Client gửi auth code, client id, code verifier cho auth server để lấy token

6. Client sử dụng access token này để truy cập


7. Grant type: Auth code + PKCE

Mạnh nhưng phức tạp

Thay client secret bằng code verifer

7.1 Flow

1. Client tạo code verifier (>43 kí tự)

2. Client tạo code challenge Base64(SHA256(code verifier)))

3. Client request đến Auth server

4. Client đăng nhập thành công

5. Auth server gửi auth code cho client

6. Client gửi auth code, client id, code verifier cho auth server để lấy token

7. Auth server trả về access token

8. Client sử dụng access token này để truy cập


8 Grant type: Implicit

Đã deprecated. Lựa chọn số 2 nếu ko làm đc Auth code flow + PKCE

Không hỗ trợ refresh token

Mobile/ SPA

8.1 Flow

1. Client request đến Auth server

2. Client đăng nhập thành công

3. Auth server callback về 1 url kèm token (Risk)

4. Client sử dụng access token này để truy cập

8.2 Bảo mật

Luôn phải hỗ trợ SSL

Validate token (header, payload, signature)


9. Grant type: Resource Owner Password

Không thể revoke token

9.1 Flow

1. User gửi username/ password cho Auth server

2. Auth server gửi access token cho client

3. Client sử dụng access token này để truy cập

10 Grant type: Client credential flow

10.1 Flow

1. User gửi client id, client secret cho Auth server

2. Auth server gửi access token cho client

3. Client sử dụng access token này để truy cập


11. Grant type: Device grant flow

Đăng nhập trên smart TV, PS4

Thường dùng trên các thiết bị khó nhập liệu bằng cách đăng nhập đại diện qua 1 thiết bị khác

11.1 Flow

1. TV tạo ra 1 device id

2. TV gửi device id đến Auth server

3. Auth server trả về TV verification url kèm client id, device code, 

4. TV định kỳ gửi client id, device code đến Auth server để kiểm tra có token chưa

5. Mobile truy xuất verification url này

6. Mobile thực hiện đăng nhập

7. Auth server lưu token tương ứng với client id và device code

8. TV thực hiện bước 4 và nhận được token

9. TV sử dụng token để đăng nhập


12 Outh Architecture

  • Sử dụng SSL/TLS
  • Validate token (built library)
  • Bảo mật token, refresh token
  • Sử dụng các thư viện uy tín.

12.1 Setup OAuth server bằng Node JS

https://github.com/jaredhanson/oauth2orize

12.2 Setup OAuth server bằng PHP

https://github.com/thephpleague/oauth2-server

13.3 OAuth as a service

OKTA

Grant type choosing path:




Tài liệu tham khảo

https://en.wikipedia.org/wiki/JSON_Web_Token

https://oauth.net/2/

https://www.appsdeveloperblog.com/keycloak-authorization-code-grant-example/

https://www.appsdeveloperblog.com/oauth-device-authorization-grant-flow-example/

https://aaronparecki.com/oauth-2-simplified/

Thư viện

https://www.oauth.com/playground/

https://github.com/openid/AppAuth-iOS