DPoP ràng buộc token API: proof htu, htm qua proxy
DPoP ràng buộc token API là cách gắn access token với một khóa riêng của client, để token bị lộ cũng không dùng được nếu không có khóa đó. Mỗi request kèm một proof là JWT ký bằng khóa riêng, ghi rõ phương thức và địa chỉ đích. ProxyVN dựng máy chủ ủy quyền và máy chủ tài nguyên lab theo RFC 9449, ký proof bằng khóa ES256 thật. Lab gửi request trực tiếp, qua forward proxy và qua reverse proxy đổi đường dẫn, rồi ghi bảng phản hồi của từng ca.
DPoP ràng buộc token API: mục tiêu và phạm vi không lặp
Phần này chốt bài toán, đầu ra và giới hạn.
Bài toán cần giải
Một ứng dụng đọc dữ liệu từ API của đối tác bằng bearer token. Token nằm trong log của một công cụ gỡ lỗi, ai đọc được log là gọi được API. Đối tác chuyển sang DPoP: token chỉ dùng được khi đi kèm proof ký bằng khóa mà client giữ. Nhóm cần biết proof phải ghi gì, và proxy giữa đường ảnh hưởng ra sao.
Đầu ra nghiệm thu
Đầu ra là bộ fixture proof đúng và sai: đúng htu và htm, sai phương thức, sai host, iat cũ, replay, thiếu ath, khóa khác, gửi token dạng Bearer. Kèm theo là bảng phản hồi của máy chủ lab cho từng ca, gồm mã trạng thái, mã lỗi và header WWW-Authenticate. Thêm ba ca đi qua proxy và một ca nonce.
DPoP khác IP whitelist
IP whitelist gắn quyền với địa chỉ mạng. DPoP gắn token với khóa. Đổi proxy, đổi mạng, token DPoP vẫn dùng được nếu proof đúng. Ngược lại, dùng đúng IP mà không có khóa thì token vô dụng. Hai cơ chế giải hai bài toán khác nhau, bài này chỉ nói DPoP.
Ranh giới với HTTP Message Signatures
Bài HTTP Message Signatures trong cụm này ký các trường của thông điệp HTTP, như header hay đường dẫn, theo RFC 9421. DPoP chỉ ký một JWT nhỏ chứa phương thức, địa chỉ, thời điểm và mã băm token. DPoP không bảo vệ nội dung body hay header khác. Hai bài không dùng chung test.
Giới hạn của lab
Nói rõ ngay. Lab không dùng máy chủ ủy quyền thật. ProxyVN viết một máy chủ gộp vai trò cấp token và phục vụ API trên cổng 9487, cùng một proxy trung gian trên cổng 9488. Proof được ký thật bằng PyJWT 2.15.1 và cryptography 50.0.2 với khóa ES256. Lab chạy HTTP thường trên máy cục bộ, không có TLS.
Thứ gì theo RFC, thứ gì do lab đặt
Danh sách kiểm tra proof, tên claim, typ dpop+jwt, mã lỗi invalid_dpop_proof và use_dpop_nonce lấy từ RFC 9449. Cửa sổ thời gian 60 giây, cách lưu jti, câu chữ mô tả lỗi do ProxyVN đặt. Máy chủ thật có thể không trả mô tả lỗi chi tiết như lab.
Ai nên đọc bài này
Người viết client cho API đã bật DPoP. Người vận hành reverse proxy trước một API dùng DPoP. Người đang cân nhắc giữa DPoP, mTLS và IP whitelist để giảm rủi ro token bị lộ.
DPoP ràng buộc token API: token gắn với khóa khi request qua proxy
Phần này tóm tắt RFC 9449.
Proof là gì
RFC 9449 định nghĩa DPoP proof là một JWT, gửi trong header DPoP. Header JOSE có typ bằng dpop+jwt, alg là thuật toán chữ ký bất đối xứng, và jwk là khóa công khai của client. Thân JWT có jti, htm, htu, iat, và ath khi gửi kèm access token.
Claim |
Ý nghĩa |
|---|---|
jti |
Mã duy nhất của proof, chống gửi lại |
htm |
Phương thức HTTP của request |
htu |
Địa chỉ HTTP đích, bỏ query và fragment |
iat |
Thời điểm tạo proof |
ath |
Mã băm SHA-256 của access token, base64url |
nonce |
Giá trị máy chủ cấp, khi máy chủ yêu cầu |
Mười hai bước kiểm
RFC nêu máy chủ nhận proof phải kiểm: chỉ một header DPoP, JWT đúng dạng, đủ claim, typ đúng, alg chấp nhận được, chữ ký khớp jwk, jwk không chứa khóa riêng. Tiếp theo: htm khớp phương thức, htu khớp địa chỉ bỏ query và fragment, nonce khớp nếu có, thời điểm trong cửa sổ chấp nhận, ath và khóa khớp token khi gọi tài nguyên.
Chuẩn hóa htu
RFC khuyên máy chủ chuẩn hóa theo cú pháp và theo scheme trước khi so htu, để giảm từ chối nhầm. Ví dụ chữ hoa trong tên miền, cổng mặc định. Máy chủ lab chuẩn hóa scheme và host về chữ thường, giữ nguyên đường dẫn.
Lấy token gắn khóa
RFC nêu client gửi proof hợp lệ trong header DPoP khi gọi token endpoint, với mọi loại grant. Proof sai thì máy chủ trả lỗi invalid_dpop_proof theo định dạng lỗi của OAuth. Proof đúng thì máy chủ gắn token với khóa công khai, thường qua thumbprint của khóa.
Token type là DPoP
Token gắn khóa có token_type là DPoP thay vì Bearer. Client gửi token trong header Authorization với scheme DPoP, kèm header DPoP chứa proof mới cho mỗi request. Máy chủ tài nguyên không chấp nhận token này dưới dạng Bearer.
Nonce từ máy chủ
RFC cho phép máy chủ yêu cầu nonce để giới hạn thời gian sống của proof. Máy chủ trả lỗi use_dpop_nonce kèm header DPoP-Nonce. Client tạo proof mới có claim nonce và gửi lại. Lab thử ca này ở phần cuối.
Proxy thấy gì
Proxy chuyển request không sửa thì phương thức và địa chỉ giữ nguyên, proof vẫn đúng. Proxy đổi host hay đường dẫn thì máy chủ thấy địa chỉ khác địa chỉ client đã ký. Đây là chỗ DPoP và reverse proxy hay xung đột, phần sau lab sẽ tái lập.
DPoP ràng buộc token API: đọc token type và quy tắc khóa của server lab
Phần này dựng khóa, lấy token và xem máy chủ lab gắn token với khóa ra sao.
Tạo khóa của client
Client tạo cặp khóa EC P-256 và xuất khóa công khai dạng JWK.
from cryptography.hazmat.primitives.asymmetric import ec
from jwt.algorithms import ECAlgorithm
import json
k = ec.generate_private_key(ec.SECP256R1())
jwk = json.loads(ECAlgorithm.to_jwk(k.public_key()))
Khóa riêng không rời khỏi tiến trình. Chỉ khóa công khai nằm trong header của proof.
Thumbprint của khóa
Máy chủ lab tính thumbprint theo RFC 7638: lấy các trường crv, kty, x, y, sắp theo tên, nối không có khoảng trắng, băm SHA-256, mã hóa base64url. Thumbprint này là mã nhận diện khóa, máy chủ lưu cùng token.
Ký proof
Hàm ký proof đặt typ và jwk vào header, các claim vào thân.
def proof(htm, htu, token=None):
c = {"jti": secrets.token_urlsafe(12), "htm": htm, "htu": htu, "iat": int(time.time())}
if token:
c["ath"] = b64(hashlib.sha256(token.encode()).digest())
return jwt.encode(c, k, algorithm="ES256", headers={"typ": "dpop+jwt", "jwk": jwk})
Mỗi lần gọi tạo jti mới. Proof dùng một lần.
Ca T1: lấy token
Client gọi token endpoint với proof có htm POST và htu là địa chỉ token endpoint. Máy chủ trả token_type DPoP.
T1 token, proof dung 200 DPoP
Máy chủ lab lưu thumbprint của khóa trong proof cùng với access token vừa cấp.
Ca T2 và T3: proof sai khi lấy token
Proof ghi htu là một đường dẫn khác: máy chủ trả 400 invalid_dpop_proof. Không gửi header DPoP: cũng 400 invalid_dpop_proof. Máy chủ lab không cấp token thường khi thiếu proof. Máy chủ thật có thể cấp Bearer token trong trường hợp này, tùy chính sách.
Quy tắc khóa của máy chủ lab

Quy tắc khóa
Máy chủ lab chỉ nhận ES256. Một token gắn với đúng một khóa. Máy chủ từ chối proof có jwk chứa trường d, tức khóa riêng bị gửi nhầm. Cửa sổ thời gian 60 giây quanh iat. Mỗi jti chỉ dùng một lần trong suốt thời gian chạy lab.
Đọc token type trước khi gửi
Client đọc token_type trong phản hồi. Nếu là DPoP thì mọi request sau phải có proof. Nếu là Bearer thì máy chủ không gắn khóa, gửi proof cũng không thêm gì. Mã client nên chọn cách gửi theo token_type, không đoán.
DPoP ràng buộc token API: tạo proof có htu, htm và thời gian đúng
Phần này gọi API với proof đúng và lần lượt làm sai từng claim.
Ca R1: proof đúng
Client gọi API bằng GET, gửi Authorization với scheme DPoP và header DPoP chứa proof có htm GET, htu là địa chỉ API, ath là mã băm token. Request có query page bằng 2.
R1 API dung proof 200 rows=3
Proof ghi htu không có query, máy chủ vẫn chấp nhận, đúng quy tắc bỏ query khi so htu.
Ca R2: sai phương thức
Proof ghi htm POST nhưng request là GET. Máy chủ trả 401 với WWW-Authenticate DPoP error bằng invalid_dpop_proof.
R2 API htm sai (POST thay GET) 401 htm POST != GET
Lỗi này hay gặp khi client tạo proof một lần rồi dùng cho nhiều loại request.
Ca R3: sai host
Proof ghi htu với host api.khac.test. Máy chủ so với host thật và từ chối. Một proof bị lấy cắp không dùng được cho máy chủ khác, đó là mục đích của htu.
Ca R4: iat cũ
Proof có iat lùi mười phút. Máy chủ lab từ chối vì lệch 600 giây, vượt cửa sổ 60 giây. RFC để máy chủ chọn cửa sổ. Đồng hồ của client lệch nhiều cũng gây lỗi này, kể cả khi proof vừa tạo.
Ca R5: gửi lại proof cũ
Client gửi một proof hợp lệ, rồi gửi lại đúng proof đó. Lần hai bị từ chối vì jti đã dùng. Máy chủ phải nhớ jti trong khoảng cửa sổ thời gian để chặn replay. Ngoài cửa sổ, iat đã chặn.
Ca R8: thiếu ath
Proof không có ath khi gửi kèm token. Máy chủ lab từ chối với lý do ath không khớp token. Ath gắn proof với đúng token đó, để proof của token này không dùng cho token khác.
Bảng phản hồi

Bảng phản hồi
Bảng dưới là đầu ra nghiệm thu, gom từ output thật của máy chủ lab.
Ca |
Proof |
Mã |
Lỗi |
WWW-Authenticate |
|---|---|---|---|---|
T1 |
Đúng, token endpoint |
200 |
token_type DPoP |
|
T2 |
htu sai, token endpoint |
400 |
invalid_dpop_proof |
|
T3 |
Không có DPoP |
400 |
invalid_dpop_proof |
|
R1 |
Đúng, có query |
200 |
||
R2 |
htm POST cho GET |
401 |
htm sai |
DPoP invalid_dpop_proof |
R3 |
htu host khác |
401 |
htu sai |
DPoP invalid_dpop_proof |
R4 |
iat lùi 10 phút |
401 |
iat lệch |
DPoP invalid_dpop_proof |
R5 |
Gửi lại proof cũ |
401 |
jti đã dùng |
DPoP invalid_dpop_proof |
R6 |
Token dạng Bearer |
401 |
DPoP invalid_token |
|
R7 |
Khóa khác |
401 |
khóa khác token |
DPoP invalid_dpop_proof |
R8 |
Thiếu ath |
401 |
ath không khớp |
DPoP invalid_dpop_proof |
Mã 400 và 401
Ở token endpoint, lỗi proof trả 400 theo định dạng lỗi OAuth. Ở máy chủ tài nguyên, lỗi trả 401 với header WWW-Authenticate theo scheme DPoP. Client nên đọc cả mã trạng thái lẫn header để biết lỗi nằm ở đâu.
DPoP ràng buộc token API: gửi request hợp lệ qua intermediary không sửa đích
Phần này đưa request qua proxy và xem token bị lộ có dùng được không.
Ca R6: gửi token dạng Bearer
Lấy token DPoP và gửi với scheme Bearer, không có proof. Máy chủ trả 401 với WWW-Authenticate DPoP error bằng invalid_token, kèm algs ES256. Token gắn khóa không bị hạ xuống bearer token.
Ca R7: token bị lộ
Một tiến trình khác có token nhưng không có khóa của client. Nó tạo khóa riêng và ký proof đúng mọi claim. Máy chủ từ chối vì thumbprint khóa trong proof khác thumbprint lưu cùng token.
R7 token bi lo, ke trom ky proof bang khoa khac 401 khoa proof khac khoa token
Đây là lý do có DPoP: token một mình không đủ.
Ca P1: qua forward proxy không sửa
Client đặt proxy là cổng 9488 trong session của requests. Proxy nhận request với URL đầy đủ, chuyển tới máy chủ đích, không đổi phương thức, host hay đường dẫn. Máy chủ chấp nhận.
P1 qua forward proxy, khong sua 200 rows=3
Proof không quan tâm request đi đường nào, chỉ quan tâm đích cuối có khớp htu không. Kết quả giống hệt ca R1 khi gọi thẳng, cùng mã 200 và cùng dữ liệu trả về.
Proxy không đọc được khóa
Proxy thấy header Authorization và DPoP nếu không có TLS, như trong lab. Proxy có thể chép token và proof. Nhưng proof dùng một lần nhờ jti, và proof mới cần khóa riêng mà proxy không có. Với TLS và proxy dạng CONNECT, proxy không thấy gì cả.
Ca P2: reverse proxy đổi đường dẫn

Reverse proxy đổi đường dẫn
Đặt proxy làm reverse proxy công khai ở địa chỉ có tiền tố v1, bỏ tiền tố khi chuyển vào máy chủ nội bộ. Client ký htu là địa chỉ công khai, đúng địa chỉ nó gọi. Máy chủ nội bộ so với địa chỉ nội bộ của chính nó và từ chối.
P2 reverse proxy bo /v1, RS so URL noi bo 401 htu http://127.0.0.1:9488/v1/api/data != http://127.0.0.1:9487/api/data
Client không sai gì. Lỗi nằm ở cách máy chủ biết địa chỉ của chính mình.
Ca P3: máy chủ cấu hình địa chỉ công khai
Cấu hình máy chủ lab so htu với địa chỉ công khai thay vì địa chỉ nội bộ. Cùng request như P2 được chấp nhận. Đây là cách sửa đúng: máy chủ đứng sau reverse proxy phải biết địa chỉ mà client nhìn thấy. Sửa ở máy chủ một lần, mọi client đều chạy, không client nào phải biết cấu trúc mạng phía sau.
Ca P4: client ký địa chỉ nội bộ
Ngược lại, client biết địa chỉ nội bộ và ký htu theo địa chỉ đó, trong khi gọi qua reverse proxy. Máy chủ đã cấu hình địa chỉ công khai từ chối. Sửa client theo kiểu này là sai hướng, và còn làm lộ cấu trúc nội bộ.
Lấy địa chỉ công khai từ đâu
Máy chủ sau reverse proxy có thể lấy địa chỉ công khai từ cấu hình tĩnh, hoặc từ header do proxy thêm như Forwarded hay X-Forwarded-Host. Đọc header chỉ an toàn khi máy chủ chỉ nhận request từ proxy tin cậy. Lab dùng cấu hình tĩnh, cách đơn giản nhất.
DPoP ràng buộc token API: thử proof sai đích và đối soát lỗi xác thực
Phần này nói về nonce, đồng hồ và cách đọc lỗi.
Ca N1 và N2: máy chủ yêu cầu nonce

Bắt tay nonce
Bật chế độ nonce trên máy chủ lab. Request có proof không nonce nhận 401 với WWW-Authenticate DPoP error bằng use_dpop_nonce và header DPoP-Nonce. Client tạo proof mới có claim nonce, gửi lại, nhận 200.
N1 server doi nonce 401 use_dpop_nonce
N2 thu lai voi nonce 200 rows=3
Client cần xử lý use_dpop_nonce như một bước bắt tay, không coi là lỗi.
Nonce đi qua proxy
Ở ca nonce, proxy lab chuyển cả header DPoP-Nonce về client. Một proxy lọc header lạ sẽ làm mất nonce, và client không bao giờ tạo được proof hợp lệ. Khi đặt proxy trước API dùng DPoP, kiểm danh sách header được chuyển, gồm DPoP, DPoP-Nonce và WWW-Authenticate.
Đồng hồ của client
Ca R4 cho thấy iat lệch quá cửa sổ là bị từ chối. Máy client có đồng hồ lệch vài phút sẽ thấy lỗi này với mọi request. Đồng bộ thời gian trên máy client. Nonce cũng giúp vì máy chủ dựa vào nonce do chính nó cấp thay vì đồng hồ của client.
Đọc lỗi theo thứ tự
Thấy 401 từ máy chủ tài nguyên, đọc header WWW-Authenticate. Có use_dpop_nonce thì lấy nonce và thử lại. Có invalid_dpop_proof thì kiểm htm, htu, iat, ath. Có invalid_token thì kiểm scheme Authorization và token còn hạn không. Thứ tự này giúp sửa nhanh.
Mô tả lỗi của lab chi tiết hơn thật
Máy chủ lab trả mô tả như htm POST khác GET để dễ học. Máy chủ thật thường chỉ trả mã lỗi, không nói claim nào sai, để không giúp kẻ tấn công. Khi gỡ lỗi với máy chủ thật, client tự in proof đã gửi, giải mã phần thân và so với request.
In proof để gỡ lỗi
Phần thân của proof là JSON mã hóa base64url, đọc được mà không cần khóa. In ra htm, htu, iat của proof cùng phương thức và URL thật của request. Không in token, chỉ in vài ký tự đầu của ath.
DPoP ràng buộc token API: vận hành client và proxy
Phần này nối các ca lab với việc chạy thật.
Tạo proof ngay trước khi gửi
Mỗi request cần proof mới với jti mới và iat hiện tại. Tạo proof trong hàm gửi request, không tạo sẵn hàng loạt. Thư viện retry tự gửi lại request với cùng header sẽ gặp lỗi replay, vì proof cũ đã dùng. Cần móc vào bước retry để tạo proof mới.
Giữ khóa riêng
Khóa riêng sống trong bộ nhớ của tiến trình, hoặc trong kho khóa của hệ điều hành nếu cần dùng lại giữa các lần chạy. Token gắn với khóa, mất khóa thì phải lấy token mới. Không ghi khóa riêng ra tệp cấu hình hay biến môi trường.
Một khóa cho mỗi client
Mỗi bản cài của ứng dụng có khóa riêng. Dùng chung một khóa cho nhiều máy làm mất ý nghĩa ràng buộc, vì lộ ở một máy là lộ ở mọi máy. Lab có hai client với hai khóa khác nhau, và token của client này không dùng được bằng khóa của client kia.
Proxy trong mạng doanh nghiệp
Proxy dạng CONNECT với TLS chuyển luồng mã hóa, không đụng tới header. DPoP chạy bình thường. Proxy chặn TLS để kiểm tra nội dung thì đọc được header, nhưng vẫn không tạo được proof mới. Proxy viết lại URL thì gây lỗi htu như ca P2.
Reverse proxy trước API
Người vận hành reverse proxy trước một API dùng DPoP cần ba việc: chuyển nguyên header DPoP, DPoP-Nonce, WWW-Authenticate; cho máy chủ biết địa chỉ công khai; không cache phản hồi có Authorization. Ca P2 và P3 là bộ test tối thiểu cho cấu hình này.
DPoP và hạn mức
Hạn mức API gắn với client và token, không gắn với IP. DPoP không đổi điều đó. Đổi proxy không làm token có thêm quyền hay thêm hạn mức. Dùng nhiều IP với cùng token vẫn bị tính chung.
DPoP ràng buộc token API: so với các cách ràng buộc khác
Phần này đặt DPoP cạnh những cách anh em hay dùng để giảm rủi ro token bị lộ, để chọn đúng công cụ.
Bearer token thuần
Bearer token là vé ai cầm cũng dùng được. Nó đơn giản, mọi thư viện hỗ trợ. Rủi ro nằm ở log, ở công cụ gỡ lỗi, ở máy bị nhiễm mã độc. Ca R6 cho thấy máy chủ đã bật DPoP sẽ không nhận token gắn khóa dưới dạng bearer, nên không có đường lùi về cách cũ.
IP whitelist
IP whitelist chỉ cho request từ một số địa chỉ. Nó không cần đổi client, nhưng gắn chặt ứng dụng với mạng. Đổi nhà mạng, đổi proxy là phải cập nhật danh sách. Token bị lộ vẫn dùng được từ một máy trong mạng được phép. DPoP không có những giới hạn này.
mTLS
Mutual TLS gắn token với chứng chỉ client ở tầng TLS. Nó mạnh, nhưng proxy chặn TLS hay bộ cân bằng tải kết thúc TLS sẽ làm mất thông tin chứng chỉ trước khi tới máy chủ tài nguyên. DPoP nằm ở tầng HTTP nên đi qua được những thành phần đó, miễn là header được giữ.
Khi nào chọn DPoP
DPoP hợp với public client như ứng dụng desktop, ứng dụng di động, ứng dụng web chỉ có giao diện, nơi không có chứng chỉ client. Nó cũng hợp khi request đi qua nhiều lớp proxy mà không kiểm soát được tầng TLS. Cái giá là mỗi request phải ký một JWT.
Chi phí ký mỗi request
Ký ES256 một JWT nhỏ tốn rất ít thời gian so với một request mạng. Lab chạy mười bảy ca trong vài giây, phần lớn thời gian là khởi động. Với crawler gửi hàng chục request mỗi giây, chi phí ký vẫn nhỏ. Chi phí đáng tính là độ phức tạp của mã retry và nonce.
Máy chủ nhớ jti
Máy chủ phải lưu jti trong khoảng cửa sổ thời gian để chặn replay như ca R5. Với nhiều máy chủ tài nguyên sau một bộ cân bằng tải, kho jti phải dùng chung. Nếu mỗi máy chủ nhớ riêng, proof gửi lại tới máy chủ khác có thể lọt. Nonce giảm được gánh nặng này.
Kết hợp với scope
DPoP giới hạn ai dùng được token, scope giới hạn token làm được gì. Ứng dụng đọc dữ liệu chỉ xin quyền đọc. Token gắn khóa với scope tối thiểu là cấu hình chặt nhất trong các lựa chọn đã nêu, mà vẫn đi qua proxy được.
Thư viện có sẵn
Lab tự viết hàm ký proof bằng PyJWT để thấy rõ từng claim. Với dự án thật, kiểm xem thư viện OAuth đang dùng đã hỗ trợ DPoP chưa. Dùng thư viện có sẵn thì vẫn chạy lại bảng ca của bài, nhất là R5 với retry và N1 với nonce.
DPoP ràng buộc token API: đầu ra nghiệm thu và phần chưa chạy
Phần này gom tiêu chí đạt, tệp đầu ra và những gì còn phải kiểm.
Danh sách kiểm tra
Client và hạ tầng đạt khi mọi dòng dưới đây đúng.
- Client đọc token_type và gửi scheme DPoP khi token là DPoP.
- Mỗi request có proof mới, jti mới, iat hiện tại.
- htm và htu lấy từ chính request sắp gửi, htu bỏ query.
- ath là mã băm của đúng token đang gửi.
- Client xử lý use_dpop_nonce bằng cách thử lại với nonce.
- Bước retry tạo proof mới, không gửi lại proof cũ.
- Proxy chuyển nguyên header DPoP, DPoP-Nonce, WWW-Authenticate.
- Máy chủ sau reverse proxy so htu với địa chỉ công khai.
Tệp đầu ra của lab
Lab có run.py chứa máy chủ, proxy, client và mười bảy ca, cùng tệp ket_qua.json chứa bảng phản hồi. Chạy lại mất vài giây, mỗi lần sinh khóa và token mới.
Những gì lab chưa chạy
Chưa chạy máy chủ ủy quyền thật, chưa có TLS, chưa thử refresh token gắn khóa, thuật toán khác ES256, proxy chặn TLS, máy chủ đọc header Forwarded. Cửa sổ thời gian, cách lưu jti, câu chữ lỗi là của lab.
Kiểm lại với máy chủ thật
Chạy T1, R1, R2 và R7 với tài khoản thử của nhà cung cấp. Nếu API đứng sau reverse proxy của chính anh em, chạy thêm P2 và P3. So mã trạng thái và header với bảng trong bài.
Proxy ở đâu trong luồng này
Proxy là đường đi của request, không phải một phần của DPoP. Forward proxy không sửa thì proof vẫn đúng, như ca P1. Với API được phép truy cập, khi cần IP Việt Nam ổn định, anh em có thể mua proxy tại trang chủ ProxyVN. Vai trò proxy có ở bài Web Scraping proxy là gì, cách ghi chuỗi proxy ở bài định dạng proxy.
DPoP ràng buộc token API: câu hỏi thường gặp
Các câu dưới đây gom những điểm anh em hay hỏi.
DPoP có thay TLS không?
Không. DPoP ràng buộc token với khóa, TLS bảo vệ đường truyền. RFC yêu cầu dùng cả hai. Lab chạy không TLS chỉ để quan sát header.
Token DPoP bị lộ có dùng được không?
Không, nếu không có khóa riêng. Ca R7 cho thấy proof ký bằng khóa khác bị từ chối.
Đi qua proxy có làm proof sai không?
Forward proxy không sửa request thì không. Reverse proxy đổi host hay đường dẫn thì có, trừ khi máy chủ so với địa chỉ công khai.
htu có tính query không?
Không. RFC nêu so htu bỏ query và fragment. Ca R1 có query page vẫn được chấp nhận.
use_dpop_nonce có phải lỗi không?
Không hẳn. Đó là máy chủ yêu cầu nonce. Lấy giá trị DPoP-Nonce, tạo proof mới có nonce, gửi lại.
Mỗi request cần một proof mới?
Có. Mỗi proof có jti riêng và chỉ dùng một lần. Ca R5 cho thấy gửi lại proof cũ bị từ chối dù mọi claim khác đều đúng.
Có thể dùng RS256 thay ES256 không?
RFC cho phép mọi thuật toán chữ ký bất đối xứng đã đăng ký, trừ none. Máy chủ lab chỉ nhận ES256. Máy chủ thật công bố danh sách trong tham số algs của header WWW-Authenticate, như ca R6.
Refresh token có gắn khóa không?
RFC có mô tả việc gắn refresh token với khóa cho public client. Lab không thử bước refresh. Khi làm với máy chủ thật, gửi proof ở cả request refresh.
Bài có chạy máy chủ thật không?
Không. Máy chủ là bản lab theo RFC 9449, proof ký thật bằng ES256. Chính sách của nhà cung cấp cụ thể cần kiểm riêng.
DPoP ràng buộc token API và những điều cần nhớ
DPoP ràng buộc token API làm token bị lộ trở nên vô dụng, miễn là mỗi request có proof mới với htm, htu, iat, ath đúng, và máy chủ biết địa chỉ công khai của chính mình. Hãy tạo proof ngay trước khi gửi, xử lý nonce, kiểm proxy chuyển đủ header. Proxy.vn - Nhà cung cấp dịch vụ proxy chất lượng hàng đầu Việt Nam khuyên anh em chạy bộ ca DPoP ràng buộc token API với máy chủ thử.