在 MCP 伺服器中設定 Bearer 驗證 (Authentication)
根據最新的 MCP 規範,你的 MCP 伺服器會作為資源伺服器 (Resource Server),負責驗證受保護資源的存取權杖 (Access tokens)。MCP Auth 提供多種方式來設定 Bearer 授權 (Authorization):
- JWT (JSON Web Token) 模式:內建授權方法,透過宣告 (Claims) 驗證 JWT。
- 自訂模式:允許你實作自己的授權邏輯。
Bearer 驗證 (Authentication) 中介軟體現在需要指定端點所屬的資源,以便正確對應設定的授權伺服器進行權杖驗證。
使用 JWT 模式設定 Bearer 驗證 (Authentication)
如果你的 OAuth / OIDC 提供者發行 JWT 作為授權權杖 (Authorization token),你可以在 MCP Auth 中使用內建的 JWT 模式。它會驗證 JWT 的簽章、過期時間以及你指定的其他宣告 (Claims);然後將驗證資訊填入請求內容,供 MCP 實作進一步處理。
權限範圍 (Scope) 與受眾 (Audience) 驗證
根據 OAuth 2.0 規範,audience 參數是必要的,以確保權杖驗證安全。不過,目前為了相容尚未支援資源標示符 (Resource indicator) 的授權伺服器,此參數為選填。出於安全考量,請盡可能包含 audience 參數。未來版本將強制要求受眾 (Audience) 驗證,以完全符合規範。
在 OAuth 2.0 中,權限範圍 (Scopes) 是主要的權限控制機制。即使權杖 (token) 具有正確的 audience,也不代表使用者就有執行某操作的權限——授權伺服器可能會簽發權限範圍為空或受限的權杖。
請務必使用 requiredScopes 來強制檢查權杖是否包含每個操作所需的權限。切勿假設有效的權杖就代表擁有完整存取權。
以下是基本權限範圍 (Scope) 與受眾 (Audience) 驗證的範例:
import express from 'express';
import { MCPAuth } from 'mcp-auth';
const app = express();
const mcpAuth = new MCPAuth({
/* ... */
});
const bearerAuth = mcpAuth.bearerAuth('jwt', {
resource: 'https://api.example.com', // 指定此端點所屬資源
audience: 'https://api.example.com', // 啟用受眾 (Audience) 驗證以提升安全性
requiredScopes: ['read', 'write'],
});
app.use('/mcp', bearerAuth, (req, res) => {
// 現在 `req.auth` 包含驗證資訊
console.log(req.auth);
});
在上述範例中:
audience參數會驗證 JWT 中的aud宣告 (Claim),確保權杖是專為你的 MCP 伺服器資源簽發。受眾值通常應與你的資源標示符一致。requiredScopes參數指定 JWT 必須包含read與write權限範圍 (Scopes)。若權杖未包含所有這些權限,將會拋出錯誤。
提供自訂 JWT 驗證選項
你也可以為底層 JWT 驗證函式庫提供自訂選項。在 Node.js SDK 中,我們使用 jose 函式庫進行 JWT 驗證。你可以提供以下選項:
jwtVerify:JWT 驗證流程的選項(jose的jwtVerify函式)。remoteJwtSet:遠端 JWT set 取得的選項(jose的createRemoteJWKSet函式)。
const bearerAuth = mcpAuth.bearerAuth('jwt', {
resource: 'https://api.example.com',
audience: 'https://api.example.com',
requiredScopes: ['read', 'write'],
jwtVerify: {
clockTolerance: 60, // 允許 60 秒的時鐘誤差
},
remoteJwtSet: {
timeoutDuration: 10 * 1000, // 取得遠端 JWT set 的逾時時間為 10 秒
},
});
使用自訂驗證設定 Bearer 驗證 (Authentication)
如果你的 OAuth / OIDC 提供者未發行 JWT,或你想自行實作授權邏輯,MCP Auth 允許你建立自訂驗證函式:
由於 Bearer 驗證 (Authentication) 中介軟體會根據驗證結果自動檢查簽發者 (Issuer, iss)、受眾 (Audience, aud) 及必要權限範圍 (Scope, scope),因此你無需在自訂驗證函式中重複這些檢查。你只需專注於驗證權杖有效性(如簽章、過期等)並回傳驗證資訊物件即可。
const bearerAuth = mcpAuth.bearerAuth(
async (token) => {
// 在此實作你的自訂驗證邏輯
const info = await verifyToken(token);
if (!info) {
throw new MCPAuthJwtVerificationError('jwt_verification_failed');
}
return info; // 回傳驗證資訊物件
},
{
resource: 'https://api.example.com',
audience: 'https://api.example.com', // 啟用受眾 (Audience) 驗證以提升安全性
requiredScopes: ['read', 'write']
}
);
在 MCP 伺服器中套用 Bearer 驗證 (Authentication)
要用 Bearer 驗證 (Authentication) 保護你的 MCP 伺服器,只需將 Bearer 驗證 (Authentication) 中介軟體套用到 MCP 伺服器實例即可。
const app = express();
app.use(mcpAuth.bearerAuth('jwt', {
resource: 'https://api.example.com',
audience: 'https://api.example.com', // 啟用受眾 (Audience) 驗證以提升安全性
requiredScopes: ['read', 'write']
}));
這將確保所有進入的請求都依據設定的 Bearer 驗證 (Authentication) 規則進行驗證與授權 (Authorization),並且驗證資訊會存於請求內容中。
你可以在 MCP 伺服器實作中存取這些資訊:
// `authInfo` 會從 `req.auth` 物件帶入
server.registerTool(
'whoami',
{
description: '回傳目前使用者資訊',
inputSchema: {},
},
({ authInfo }) => {
console.log(`驗證 (Authentication) 使用者:${authInfo.subject}`);
return { subject: authInfo.subject };
}
);