OAuth: 403 responses without insufficient_scope incorrectly retry with same token
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 55/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 停滞
- 技术栈
- python
调研方向
阅读 src/mcp/client/auth/oauth2.py 第 662-681 行附近的内容,重点关注提取 error 字段后如何处理 403 响应。确认 insufficient_scope、其他错误以及没有 error 字段时的行为;只有 scope-challenge 路径会重试,其他 403 响应都会立即抛出异常时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
Summary
The OAuth client unconditionally retries all 403 responses, even when the error is not insufficient_scope. This causes an unnecessary retry attempt with the same token that will fail for the same reason.
Location
src/mcp/client/auth/oauth2.py, lines 662-681
The Bug
elif response.status_code == 403:
error = self._extract_field_from_www_auth(response, "error")
# Only performs step-up if error == "insufficient_scope"
if error == "insufficient_scope":
self._select_scopes(response)
token_response = yield await self._perform_authorization()
await self._handle_token_response(token_response)
# BUG: Retries unconditionally, even when no new tokens were obtained
self._add_auth_header(request)
yield request
Lines 679-681 execute regardless of whether step-up authorization occurred, causing a retry with the same credentials.
Expected vs Actual Behavior
| Scenario | Expected | Actual |
|---|---|---|
403 with insufficient_scope |
Get new tokens → retry | ✅ Correct |
403 with different error (e.g., invalid_token) |
Raise error immediately | ❌ Retries once with same token, then fails |
| 403 with no error field | Raise error immediately | ❌ Retries once with same token, then fails |
Impact
- Wasted network round-trip: Client makes doomed retry request that will fail for the same reason
- Poor error feedback: Delays error reporting by one request cycle
- Spec non-compliance: MCP Authorization Spec implies retry only for
insufficient_scope - Resource waste: Unnecessary load on server and client
Fix
Move the retry logic inside the if error == "insufficient_scope": block and raise an error otherwise:
elif response.status_code == 403:
error = self._extract_field_from_www_auth(response, "error")
if error == "insufficient_scope":
try:
self._select_scopes(response)
token_response = yield await self._perform_authorization()
await self._handle_token_response(token_response)
# Retry with new tokens
self._add_auth_header(request)
yield request
except Exception:
logger.exception("OAuth flow error")
raise
else:
# Permanent authorization failure - cannot be resolved by retry
raise OAuthFlowError(
f"Access forbidden: {error or 'insufficient permissions'}"
)
References
- RFC 6750 Section 3.1 - Defines
insufficient_scopeas the only 403 error code - MCP Authorization Spec - Scope challenge handling
Authored by Claude, reviewed by @maxisbey
- 主要语言
- Python
- 星标
- 24.3k
- 派生
- 4k
- 平均合并
- 1 天 1 小时
- 30 天内合并 PR
- 31
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
modelcontextprotocol/python-sdk 的其他 Issue
-
v1 v2
难度 2/5 1-3 小时 新手友好度 85/100
modelcontextprotocol/python-sdk#3546 · 4 条评论 ·
-
v1 v2
难度 2/5 1-3 小时 新手友好度 76/100
modelcontextprotocol/python-sdk#3545 · 1 条评论 ·
-
v1 v2
难度 1/5 1 小时以内 新手友好度 91/100
modelcontextprotocol/python-sdk#3508 · 2 条评论 ·
-
难度 2/5 1-3 小时 新手友好度 64/100
modelcontextprotocol/python-sdk#3504 ·
-
v1 v2
难度 2/5 1-3 小时 新手友好度 82/100
modelcontextprotocol/python-sdk#3492 · 1 条评论 ·
查看 modelcontextprotocol/python-sdk 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 86/100
zostera/django-bootstrap4#894 ·
-
难度 2/5 1-3 小时 新手友好度 78/100
use-agent-os/agent-os#3276 ·
-
难度 2/5 1-3 小时 新手友好度 88/100
zephyrproject-rtos/zephyr#119726 ·
-
area/auth bug comp/agent P3 platform/discord type/security
难度 2/5 1-3 小时 新手友好度 88/100
NousResearch/hermes-agent#117848 ·
-
难度 2/5 1-3 小时 新手友好度 82/100
zilliztech/memsearch#759 ·