授权请求(阶段 B)

POST /ath/authorize 发起用户端授权流程。实现者验证代理已注册且已获批准,然后为用户发起 OAuth 授权同意流程。

请求

{
  "client_id": "ath_travelbot_001",
  "agent_attestation": "<signed JWT>",
  "provider_id": "example-mail",
  "scopes": ["mail:read"],
  "user_redirect_uri": "https://travel-agent.example.com/callback",
  "state": "<random-state-string>",
  "resource": "https://api.example.com/v1"
}

请求字段

字段类型必填描述
client_idstring注册时获取的代理客户端 ID
agent_attestationstring新鲜的签名 JWT,用于证明代理身份
provider_idstring要授权的服务提供方
scopesstring[]要请求的范围(必须在已批准范围内)
user_redirect_uristringOAuth 授权同意后的重定向地址
statestring用于 CSRF 保护的不透明状态值(必须(MUST)使用 CSPRNG 生成,至少 128 位熵)
resourcestring目标资源服务器 URI(RFC 8707

响应

{
  "authorization_url": "https://example.com/oauth/authorize?client_id=...&scope=mail:read&code_challenge=...&code_challenge_method=S256&state=...",
  "ath_session_id": "ath_sess_abc123"
}

响应字段

字段类型描述
authorization_urlstring用户应被引导至的 OAuth 授权同意 URL
ath_session_idstring用于令牌交换步骤的会话标识符

行为

  • 实现者必须(MUST)验证代理已注册且 agent_status"approved"
  • 实现者必须(MUST)验证证明 JWT 有效
  • 实现者必须(MUST)检查代理已获得所请求服务提供方的批准
  • 请求的范围必须(MUST)在代理针对该服务提供方已批准的范围内
  • authorization_url 必须(MUST)包含 PKCE 参数(RFC 7636)— code_challengecode_challenge_method=S256
  • 对应的 code_verifier 存储在服务端,在令牌交换时发送
  • 代理将用户引导至 authorization_url
  • 授权同意后,OAuth 回调由 ATH 实现者处理
  • 当实现者将用户重定向到上游 authorization_url 时,必须(MUST)同时建立浏览器端会话绑定(例如设置 HTTP-only cookie),将用户的浏览器与 ath_session_id 关联。在 OAuth 回调时,实现者必须(MUST)验证呈现回调的浏览器与被重定向到同意页面的浏览器匹配
  • ath_session_id 必须(MUST)在创建后 10 分钟内过期
  • ath_session_id 必须(MUST)为一次性使用——在令牌交换成功消费后作废
  • 实现者必须(MUST)验证证明 JWT 的 sub 声明与 client_id 注册的 agent_id 匹配