Tích hợp Single Sign-On
1. Giới thiệu
Tài liệu mô tả cơ chế xác thực bên thứ ba (Single Sign-On
) giữa hệ thống Ngân hàng (Bank
) và đối tác cung cấp hóa đơn (Invoice Provider
).
Khi người dùng mua gói dịch vụ hóa đơn điện tử qua ứng dụng ngân hàng, quá trình xử lý diễn ra như sau:
-
Ngân hàng tạo JWT:
Bank tạo một token (JWT
) chứa thông tin người dùng và giao dịch, sau đó ký bằng private-key và đẩy yêu cầu sang Partner Provider (Invoice). -
Invoice Provider xác thực:
Hệ thống hóa đơn dùng public-key do Bank cung cấp để xác thực token và thực hiện các hành động tương ứng như tạo tài khoản, liên kết tài khoản hoặc cộng thêm gói dịch vụ.
Các luồng nghiệp vụ chính:
STT | Tên luồng | Mô tả |
---|---|---|
1 | On-Boarding | Tạo tài khoản mới tại Invoice Provider |
2 | Account Linking | Liên kết OUID với tài khoản đã có tại Invoice Provider |
3 | Buy More Packages | Mua thêm gói/hạn mức cho người dùng đã kích hoạt |
2. Từ ngữ - Định nghĩa
Thuật ngữ | Mô tả |
---|---|
OUID | Onboard User ID – định danh duy nhất Bank cấp. |
JWT | Token chuẩn JWS RS256 chứa OUID và thông tin giao dịch. |
JWKS | Tập public-key Bank cung cấp. |
product_code | Mã gói dịch vụ được mua. |
order_id | Mã giao dịch mua gói do Bank sinh ra. |
3. Kiến trúc tổng quan
- Bank là bên phát hành JWT.
- Invoice Provider thực hiện xác thực chữ ký JWT cục bộ bằng public key do Bank cung cấp.
- Không có tương tác ngược từ Invoice Provider về Bank trong quá trình xác thực.
- Việc xác thực JWT có thể được cấu hình bổ sung tại Gateway (Hub Invoice) nhằm tăng cường bảo mật và kiểm soát truy cập ngay từ đầu vào.
- Hệ thống cho phép bổ sung xác thực JWT tại Gateway (Hub Invoice) trước khi chuyển tiếp request về Invoice Provider.
- Khi Gateway đã xác thực JWT thành công, có thể cấu hình để Invoice Provider bỏ qua bước xác thực lại nhằm giảm tải xử lý.
- Việc xác thực tại Gateway giúp:
- Tăng cường bảo mật đầu vào
- Ngăn chặn request không hợp lệ từ sớm
- Giảm khối lượng xử lý cho Invoice Provider
- Tùy chọn xác thực tại Gateway và Invoice Provider cần được quản lý rõ ràng theo cấu hình, tránh tình trạng cả hai đều bỏ qua hoặc cùng xác thực không cần thiết.
4. Chi tiết các luồng
- On-Boarding
- Account Linking
- Buy More Packages
Khi người dùng lần đầu đăng ký gói hóa đơn,
Invoice Provider
sẽ tạo tài khoản mới cho họ bằngJWT
do ngân hàng phát hành.
Dành cho người dùng đã có tài khoản tại
Invoice Provider
.JWT
chứa thông tinOUID
và chỉ định tài khoản cần liên kết.
Người dùng đã được kích hoạt (có OUID), mua thêm dung lượng/gói. Giao dịch được xử lý bằng cách cộng thêm gói vào tài khoản hiện tại.
5. Đặc tả API (Server-to-Server)
Endpoint | Method | Mô tả | Scope |
---|---|---|---|
/api/v1/onboard | POST | Tạo tài khoản mới | onboard |
/api/v1/link-account | POST | Liên kết tài khoản có sẵn | link |
/api/v1/purchase-package | POST | Cộng thêm gói/dung lượng | purchase |
5.1 Quy định chung
-
Tất cả các request phải có header:
Authorization: Bearer <JWT>
-
Invoice Provider Xác thực JWT:
- Ký bằng RS256 (
kid
→ JWKS) aud == "invoice"
exp
còn hiệu lực vànbf
hợp lệscope
nằm trong tập cho phép của endpoint
- Ký bằng RS256 (
5.2 Ví dụ một API nghiệp vụ
Create Invoice - khách hàng phát sinh hóa đơn
POST /api/v1/invoices
Authorization: Bearer <JWT-from-Bank>
Content-Type: application/json
{
"invoice_number": "INV-2025-0001",
"amount": 450000,
"currency": "VND",
"description": "Dịch vụ ABC tháng 05/2025"
}
Invoice Provider xử lý:
- Xác thực JWT (giống bước ở trên)
- Lấy
sub
= OUID → tra bảnguser_invoice_account
- Tạo bản ghi hóa đơn, gán
ouid
- Trả kết quả:
HTTP/1.1 201 Created
{
"invoice_id": "98b2ef...",
"status": "CREATED",
"ouid": "ouid_123456"
}
Các API nghiệp vụ (lấy danh sách hóa đơn, thanh toán, tải PDF, v.v.) đều dùng chung cơ chế Bearer JWT.
Không cần Refresh Token vì Ngân hàng (theo mô hình "push") sẽ cấp một JWT mới cho mỗi hành động bảo mật.
6. Định dạng JWT
Header:
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-2025"
}
Payload (ví dụ scope: purchase):
{
"exp": 1735180923,
"iat": 1735180623,
"jti": "0d142c23-4731-4a5a-886e-757c378d5b62",
"iss": <AUTH_PROVIDER>,
"aud": "account",
"sub": "fc3c3988-7563-4d26-8a75-8af65ed6204a",
"typ": "Bearer",
"azp": "atom",
"sid": "ceaf4605-18c1-428b-bee3-9a62b555a696",
"acr": "1",
"allowed-origins": ["/*" ],
"realm_access": {
"roles": [
"read-token"
]},
"resource_access": {
"account": {
"roles": [
"manage-account",
"manage-account-links",
"view-profile"
]
}
},
"scope": "purchase",
"email_verified": false,
"user_id": "fc3c3988-7563-4d26-8a75-8af65ed6204a",
"name": "name",
"preferred_username": "preferred_username",
"given_name": "given_name",
"family_name": "family_name",
"email": "email@gmail.com",
"client_id": "client_id",
"username": "username",
"token_type": "Bearer",
"active": true
}
7. Public-Key Distribution
Bank cung cấp public-key theo định dạng JWKS tại endpoint:
GET https://bank.example.vn/.well-known/jwks.json
- Invoice Provider cache JWKS tối đa 24h
- Tự động reload khi gặp
kid
mới
8. Yêu cầu bảo mật
TLS 1.2+
bắt buộc- Token
exp
≤ 5 phút → sau đó phải cấp token mới Private-key
phải lưu trữ trong HSM/KMS- Ghi log
jti
vàorder_id
để truy vết và chống replay
9. Quy ước lỗi
HTTP | Code ứng dụng | Mô tả |
---|---|---|
400 | INVALID_JWT | Thiếu/sai định dạng claim |
401 | JWT_SIGNATURE_FAIL | Sai chữ ký |
403 | TOKEN_EXPIRED | Token hết hạn |
409 | DUPLICATE_ORDER | Giao dịch trùng order_id |
500 | PARTNER_INTERNAL_ERROR | Lỗi hệ thống phía Invoice Provider |