跳轉到主要內容

在 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) 驗證

受眾 (Audience) 驗證

根據 OAuth 2.0 規範,audience 參數是必要的,以確保權杖驗證安全。不過,目前為了相容尚未支援資源標示符 (Resource indicator) 的授權伺服器,此參數為選填。出於安全考量,請盡可能包含 audience 參數。未來版本將強制要求受眾 (Audience) 驗證,以完全符合規範。

請務必驗證權限範圍 (Scopes)

在 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 必須包含 readwrite 權限範圍 (Scopes)。若權杖未包含所有這些權限,將會拋出錯誤。

提供自訂 JWT 驗證選項

你也可以為底層 JWT 驗證函式庫提供自訂選項。在 Node.js SDK 中,我們使用 jose 函式庫進行 JWT 驗證。你可以提供以下選項:

  • jwtVerify:JWT 驗證流程的選項(josejwtVerify 函式)。
  • remoteJwtSet:遠端 JWT set 取得的選項(josecreateRemoteJWKSet 函式)。
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 };
  }
);