auth: refresh_token() requests offline_access that was never granted, so refreshes fail with invalid_scope
Maintainer thường phản hồi trong vòng 3 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 65/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- rust
- Lĩnh vực
- authentication
Hướng nghiên cứu
Bắt đầu tại refresh_token() trong crates/rmcp/src/transport/auth.rs, nơi add_offline_access_if_supported được gọi trên granted_scopes đã lưu trước khi dựng yêu cầu refresh, và sau đó đọc chính hàm trợ giúp đó. Tiếp theo, đọc bài kiểm thử refresh_token_adds_offline_access_when_as_supports_it, hiện đang kỳ vọng offline_access trong yêu cầu refresh. Công việc hoàn tất khi các yêu cầu refresh chỉ gửi granted_scopes (hoặc bỏ qua scope), bài kiểm thử đó được viết lại cho khớp, và hành vi của luồng ủy quyền trong #897 không thay đổi.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
Since #897, AuthorizationManager::refresh_token() adds offline_access to the refresh request whenever the authorization server lists it in scopes_supported, even if the stored grant doesn't include it. An authorization server that didn't grant offline_access refuses that refresh with invalid_scope. The client then has to re-authorize every time the access token expires.
Where
crates/rmcp/src/transport/auth.rs L2309-L2313:
let mut refresh_scopes = stored_credentials.granted_scopes.clone();
self.add_offline_access_if_supported(&mut refresh_scopes);
let requested_scopes = refresh_scopes.clone();
for scope in refresh_scopes {
refresh_request = refresh_request.add_scope(Scope::new(scope));
The test added in #897, refresh_token_adds_offline_access_when_as_supports_it, expects a refresh of a grant holding only read to send offline_access read.
Why this breaks
RFC 6749 §6: the refresh request's scope "MUST NOT include any scope not originally granted by the resource owner". The authorization server is right to answer invalid_scope.
Requesting offline_access at authorization time doesn't guarantee it's granted. OIDC Core §11 requires prompt=consent alongside offline_access "unless other conditions for processing the request permitting offline access … are in place", and rmcp adds the scope without the prompt. node-oidc-provider, for one, drops offline_access from the grant by default. An OP can still issue a refresh token without the scope (node-oidc-provider allows this through its issueRefreshToken hook), and SEP-2207's own "No guarantee" item allows for that. Every refresh rmcp then sends is rejected:
POST /token
grant_type=refresh_token&refresh_token=…&scope=openid+profile+email+offline_access
HTTP/1.1 400 Bad Request
{"error":"invalid_scope","error_description":"refresh token missing requested scope","scope":"offline_access"}
SEP-2207, which #676/#897 implement, only covers authorization requests. Client guidance item 2: the client "MAY add the offline_access scope to the list of scopes from the resource server before making authorization requests to the Authorization Server". It doesn't extend that to refresh requests.
Reproduction
- Run an authorization server that strips
offline_accesswithoutprompt=consent(node-oidc-provider 9.x does by default), still issues refresh tokens to the client (for node-oidc-provider, anissueRefreshTokenthat returnstruefor clients allowed therefresh_tokengrant), and listsoffline_accessinscopes_supported. - Authorize with rmcp. The token response's
scopedoesn't includeoffline_access, but a refresh token is issued. - Let the access token expire, or call
refresh_token(). The token endpoint returnsinvalid_scopeforoffline_access.
Seen in the wild with Codex CLI 0.155.0 and 0.161.0 (codex-mcp-client, rmcp 3.3.0). Restricting Codex's configured scopes doesn't help: the login requests only the configured scopes, but every refresh still gets offline_access added. Still present on main (08e021153ef0).
Suggested fix
Don't add offline_access on the refresh path. Send the stored granted_scopes, or omit scope entirely, which RFC 6749 §6 defines as "equal to the scope originally granted". If the grant does include offline_access, it's already in granted_scopes, so nothing is lost. #897's scope-upgrade change is a re-authorization, so SEP-2207 does cover it and it can stay.
- Ngôn ngữ chính
- Rust
- Star
- 4k
- Fork
- 654
- Merge trung bình
- 3 ngày 15 giờ
- Pull request đã merge (30 ngày)
- 37
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của modelcontextprotocol/rust-sdk
-
bug P2 ready for work T-config
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
modelcontextprotocol/rust-sdk#1335 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
P3 question Stale T-documentation T-enhancement
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 86/100
modelcontextprotocol/rust-sdk#1155 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
bug P1 ready for work T-handler T-model
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 28/100
modelcontextprotocol/rust-sdk#1337 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
enhancement P2 ready for work T-security T-transport
Độ khó 3/5 Nửa ngày Mức phù hợp với người mới 40/100
modelcontextprotocol/rust-sdk#1334 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
enhancement P3 ready for work T-documentation T-examples
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 30/100
modelcontextprotocol/rust-sdk#1332 ·
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của modelcontextprotocol/rust-sdk
Issue tương tự
-
[Bug]: Web chat input doesn't regain focus after a reply finishesCó thể đã có người làm @GaijinSystems đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
zeroclaw-labs/zeroclaw#11658 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
good first issue help wanted
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
bytecodealliance/wasm-tools#2768 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
documentation
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
NuSkooler/enigma-bbs#907 ·
Maintainer thường phản hồi trong vòng 1 ngày