🔐 MCP授权机制

🎯 什么是MCP授权?

想象一下,MCP(Model Context Protocol)就像是一个智能助手系统,而授权机制就是确保只有"合法用户"才能使用这个系统的安全门禁。

💡 生活比喻

就像你去银行办理业务一样:

  • 你需要先证明自己的身份(身份验证)
  • 银行会给你一个临时通行证(访问令牌)
  • 有了这个通行证,你才能进行各种操作
  • 通行证有时效性,过期需要重新申请

👥 三个重要角色

🏠 MCP服务器

提供服务的"房子",需要保护,只允许有权限的人进入

👤 MCP客户端

想要使用服务的"用户",需要先获得通行证

🏛️ 授权服务器

负责发放通行证的"保安室",验证身份并发放访问令牌

🔄 授权流程详解

让我们看看完整的授权过程是如何进行的:

1. 客户端请求访问
2. 重定向到授权页面
3. 用户登录授权
4. 获得授权码
5. 交换访问令牌
6. 使用令牌访问服务

📋 详细步骤

  1. 请求访问:客户端告诉授权服务器"我想访问某个MCP服务"
  2. 身份验证:用户需要登录并确认授权
  3. 获得授权码:授权服务器给客户端一个临时的授权码
  4. 交换令牌:客户端用授权码换取真正的访问令牌
  5. 访问服务:客户端带着令牌去访问MCP服务器

🔑 授权码和访问令牌的获取

🎯 从哪里获取?

💡 获取地点说明

  • 授权码:从授权服务器获取(用户登录后)
  • 访问令牌:从授权服务器的令牌端点获取
  • 刷新令牌:通常与访问令牌一起提供

📝 具体获取流程

第一步:获取授权码

GET /authorize?response_type=code &client_id=your_client_id &redirect_uri=https://your-app.com/callback &scope=read write &state=random_string &resource=https://mcp.example.com HTTP/1.1 Host: auth.example.com

用户登录成功后,授权服务器会重定向到你的应用,URL中包含授权码:

https://your-app.com/callback?code=AUTHORIZATION_CODE&state=random_string

第二步:用授权码换取访问令牌

POST /token HTTP/1.1 Host: auth.example.com Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=AUTHORIZATION_CODE &redirect_uri=https://your-app.com/callback &client_id=your_client_id &client_secret=your_client_secret &resource=https://mcp.example.com

授权服务器返回访问令牌:

{ "access_token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "def50200...", "scope": "read write" }

🤔 为什么要分两次?不能直接获取令牌吗?

OAuth 采用先获取授权码(Authorization Code)、再交换访问令牌(Access Token)的两步流程(授权码模式),主要是为了平衡安全性功能性。这种设计解决了以下几个关键问题:

⚠️ 1. 防止令牌泄露(主要针对Web应用)

  • 问题:在传统Web应用中,OAuth的重定向是通过浏览器完成的。如果直接返回访问令牌(如隐式模式),令牌会暴露在URL或浏览器历史记录中,可能被恶意脚本或中间人攻击窃取。
  • 解决方案:授权码是一个短期有效的临时凭证,即使被拦截,攻击者也无法直接用授权码获取资源(还需配合客户端密钥交换)。而令牌通过后端信道(服务端到服务端)传输,避免暴露给浏览器。

🔒 2. 客户端身份验证

  • 授权码模式要求客户端(应用服务器)在交换令牌时验证身份(如client_id + client_secret)。这确保了只有合法的客户端能换取令牌,而拦截授权码的第三方无法完成这一步(除非他们同时窃取了客户端密钥)。

🛡️ 3. 减少令牌传输环节

令牌只在以下两个安全信道中传输:

  1. 授权服务器 → 客户端后端(通过HTTPS)
  2. 客户端后端 → 资源服务器(通过HTTPS)

避免了令牌经过用户浏览器或移动端App(可能被恶意应用读取)。

💡 生活比喻

这就像银行的双重验证:

  • 第一次:你出示身份证,银行确认你的身份(获得授权码)
  • 第二次:你提供银行卡和密码,银行给你现金(获得访问令牌)
  • 为什么分两次:如果银行直接给你现金,万一身份证被偷了,钱就没了

🔐 安全机制详解

阶段 安全措施 目的
授权码获取 用户必须亲自登录
重定向到可信域名
确保用户真实授权
令牌交换 需要客户端密钥
授权码一次性使用
防止授权码被滥用
令牌使用 HTTPS传输
令牌有时效性
保护令牌安全

🔍 授权服务器发现

MCP服务器需要告诉客户端"我的授权服务器在哪里":

HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer realm="mcp.example.com", resource="https://mcp.example.com/.well-known/oauth-authorization-server"

客户端收到这个响应后,就知道去哪里申请授权了。

🎫 访问令牌的使用

获得访问令牌后,客户端需要这样使用:

GET /mcp HTTP/1.1 Host: mcp.example.com Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

重要:令牌必须放在HTTP头部的Authorization字段中,不能放在URL里!

🛡️ 安全考虑

🔒 必须遵循的安全原则

  • 所有通信必须使用HTTPS加密
  • 访问令牌要安全存储,不能泄露
  • 令牌有时效性,过期需要刷新
  • 服务器必须验证令牌的有效性

⚠️ 常见安全风险

  • 令牌泄露:如果令牌被偷走,攻击者可以冒充你
  • 重定向攻击:恶意网站可能试图窃取你的授权码
  • 令牌复用:一个令牌只能用于指定的服务,不能跨服务使用

📊 错误处理

当出现问题时,服务器会返回相应的错误代码:

状态码 含义 解决方案
401 未授权 需要重新登录或刷新令牌
403 禁止访问 权限不足,需要申请更高权限
400 请求错误 检查请求格式是否正确

💡 实际应用场景

MCP授权机制在以下场景中特别有用:

🚀 总结

MCP授权机制就像是一个智能的门禁系统:

虽然看起来复杂,但核心思想很简单:先证明身份,再获得通行证,最后使用服务