CodeGym /Các khóa học /ChatGPT Apps /Kiểm thử đăng nhập và quyền truy cập qua MCP Jam: None, B...

Kiểm thử đăng nhập và quyền truy cập qua MCP Jam: None, Bearer, OAuth with credentials, Default OAuth

ChatGPT Apps
Mức độ , Bài học
Có sẵn

1. MCP Jam như phòng thí nghiệm cho ủy quyền

MCP Jam không phải “một tool kỳ cục nữa”, mà là bệ thử nghiệm của bạn, có thể đóng vai MCP client. Về bản chất, đây là trình giả lập hành vi của ChatGPT khi làm việc với MCP server: nó có thể đọc .well-known/oauth-protected-resource, chạy OAuth flow, gắn token vào yêu cầu và hiển thị chính xác điều gì đã sai.

Một điểm thực hành rất quan trọng: nếu bạn đạt được Default OAuth flow thành công trong MCP Jam, bạn đã sẵn sàng khoảng 80% để tích hợp với ChatGPT App thực. Mọi thứ ChatGPT làm khi liên kết tài khoản (linking), Jam đều làm được, chỉ là với log và nút bấm minh bạch hơn.

Ở bài trước, chúng ta đã cấu hình ủy quyền cơ bản cho MCP server học tập GiftGenius: chọn phương án kiểm tra token (JWT hoặc introspection), triển khai .well-known/oauth-protected-resource và middleware bảo vệ các tool. Bây giờ hãy xem mọi thứ hoạt động trong MCP Jam thế nào ở các chế độ ủy quyền khác nhau.

Mục tiêu của bài này — học cách:

  • chủ động chuyển đổi các chế độ ủy quyền trong Jam (None, Bearer, OAuth with credentials, Default OAuth);
  • hiểu chính xác Jam gửi gì tới MCP server ở mỗi chế độ;
  • chẩn đoán phần nào của hệ thống bị hỏng: MCP Server, Auth Server hay metadata;
  • kiểm tra rằng tool được bảo vệ chỉ hoạt động khi có token, còn tool mở — hoạt động cả khi không có.

2. MCP server học tập của chúng ta: đang kiểm thử gì

Để không nói suông, nhắc lại ngắn gọn bối cảnh. Tiếp tục câu chuyện với ứng dụng học tập GiftGenius — đây là ChatGPT App giúp chọn quà tặng và hiển thị cho người dùng đơn hàng và wishlist của họ.

Về phía MCP server chúng ta đã có:

  • tool mở, ví dụ search_gifts — có thể gọi ẩn danh;
  • tool được bảo vệ, ví dụ list_user_orders — chỉ được chạy cho người dùng đã xác thực và yêu cầu scope mcp:tools.

Server có thể:

  • xuất bản .well-known/oauth-protected-resource;
  • kiểm tra token (JWT hoặc qua introspection — bạn đã chọn một cách ở bài trước);
  • trích sub (user id), scope, aud từ token và truyền chúng vào handler của các tool.

Middleware kiểm tra token điển hình trong Node.js/TypeScript có thể như sau:

// middleware/auth.ts
export function requireScope(requiredScope: string) {
  return async (req: any, res: any, next: () => void) => {
    const header = req.headers["authorization"];
    if (!header?.startsWith("Bearer ")) {
      res
        .status(401)
        .set(
          "WWW-Authenticate",
          `Bearer realm="mcp", resource_metadata="${process.env.BASE_URL}/.well-known/oauth-protected-resource", scope="${requiredScope}"`
        )
        .json({ error: "unauthorized" });
      return;
    }

    // tại đây bạn kiểm tra token (chữ ký, exp, aud, scope...)
    // và đặt kết quả vào req.user
    next();
  };
}

Middleware này sẽ được dùng trước các tool MCP được bảo vệ. Nếu không có token — chúng ta trả 401WWW-Authenticate đúng với resource_metadata, như đặc tả MCP Authorization yêu cầu. Phần phân tích chi tiết việc kiểm tra token và triển khai các hàm phụ trợ bạn đã làm ở bài trước, ở đây xem như đã có sẵn.

3. Các chế độ ủy quyền trong MCP Jam: tổng quan

Trong MCP Jam có vài chế độ ủy quyền để kết nối tới MCP server. Chúng tương ứng các mô hình OAuth điển hình: từ hoàn toàn không có token tới Authorization Code + PKCE đầy đủ.

Tóm tắt:

  1. None (No Auth) — Jam hoàn toàn không thêm header Authorization. Đây là truy cập ẩn danh. Phù hợp cho MCP server mở và kiểm tra rằng tài nguyên đóng từ chối đúng với 401WWW-Authenticate.
  2. Bearer Token — Jam thêm Authorization: Bearer <token>, do bạn dán thủ công trong giao diện. Phù hợp cho kiểm tra nhanh: token đã lấy ở đâu đó (curl, Keycloak UI), và bạn muốn kiểm tra hành vi MCP resource.
  3. OAuth with credentials (Client Credentials) — Jam tự lấy token bằng client_credentials từ Auth Server, dùng Client ID và Secret đã chỉ định. Đây là chế độ “confidential client”, gần với ủy quyền server-to-server không có người dùng tham gia.
  4. Default OAuth (Authorization Code + PKCE) — chế độ chính cho các client kiểu ChatGPT (public client không có secret). Jam tự đọc resource_metadata, tìm Auth Server, mở trình duyệt với /authorize, thực hiện PKCE flow và nhận token người dùng.

Để dễ hình dung, gói lại trong bảng.

Chế độ trong Jam Jam gửi gì Ai lấy token Kịch bản điển hình
None Không có Authorization Không ai Tool ẩn danh, kiểm tra 401
Bearer Token Bearer <manual> Bạn (curl, UI IdP) Kiểm thử logic Resource Server
OAuth with cred. Bearer <client token> Jam qua client_credentials Công cụ dịch vụ/quản trị
Default OAuth Bearer <user token> Jam qua Authorization Code+PKCE Đăng nhập người dùng như trong ChatGPT

Bây giờ đi qua từng chế độ và chạy thử MCP server GiftGenius của chúng ta.

4. Chế độ None: kiểm tra server từ chối đúng cách

Bắt đầu từ chế độ đơn giản nhất: không có ủy quyền.

Trong MCP Jam, bạn chọn server của mình (ví dụ, http://localhost:4000/mcp) và trong cài đặt kết nối chọn chế độ ủy quyền None.

Khi đó sẽ xảy ra:

  • Jam thiết lập kết nối MCP;
  • khi gọi tool, nó không thêm header Authorization;
  • bạn có thể gọi các tool mở (ví dụ, search_gifts);
  • khi gọi tool được bảo vệ (ví dụ, list_user_orders) server của bạn phải phản hồi 401 Unauthorized.

Quan trọng là server thêm WWW-Authenticate chính xác kèm theo phản hồi 401. Ví dụ phản hồi với các trường bổ sung realmscope, gần với khuyến nghị của OpenAI và MCP Authorization spec:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="mcp",
  resource_metadata="https://giftgenius.example.com/.well-known/oauth-protected-resource",
  scope="mcp:tools"
Content-Type: application/json

{"error": "unauthorized"}

Khi thấy phản hồi như vậy, Jam hiểu: tài nguyên được bảo vệ, đây là nơi lấy metadata (resource_metadata), và scope nào được mong đợi. Ở chế độ None, nó chỉ hiển thị lỗi cho bạn, nhưng ở chế độ Default OAuth nó sẽ tự động đi theo resource_metadata được chỉ định và khởi chạy OAuth flow.

Về gỡ lỗi, ở chế độ None bạn kiểm tra:

  • các tool mở hoạt động hoàn toàn không cần token;
  • các tool được bảo vệ không bao giờ chạy ẩn danh;
  • header WWW-Authenticate tuân thủ đặc tả (bao gồm Bearerresource_metadata).

Nghe như kiểm tra tầm thường, nhưng rất nhiều vấn đề bắt đầu từ việc 401 được trả về mà không có WWW-Authenticate hoặc có tham số sai trong đó (ví dụ, resource_metadata_uri cũ thay vì resource_metadata hiện hành).

5. Chế độ Bearer Token: kiểm thử nhanh logic Resource Server

Bước tiếp theo — chế độ mà bạn đã có token hợp lệ (lấy ngoài Jam) và muốn kiểm tra đúng logic Resource Server: xử lý/chấp nhận/từ chối token, xử lý scope và audience, và liên kết sub với người dùng dịch vụ của bạn.

Trong MCP Jam, chuyển sang chế độ Bearer Token và dán vào ô token, ví dụ:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Giờ Jam sẽ thêm vào mỗi yêu cầu MCP header:

Authorization: Bearer eyJhbGciOi...

MCP server của bạn nhận yêu cầu, đi qua middleware requireScope("mcp:tools"), giải mã JWT và kiểm tra claims. Mã kiểm tra điển hình có thể viết giản lược như sau:

// auth/verifyToken.ts
import jwt from "jsonwebtoken";

export function verifyToken(header: string) {
  const token = header.replace("Bearer ", "");
  const payload = jwt.verify(token, process.env.JWT_PUBLIC_KEY!);
  // tại đây có thể kiểm tra aud, scope, v.v.
  return payload as { sub: string; scope?: string };
}

Và dùng nó trong middleware:

// bên trong requireScope
const payload = verifyToken(header);
if (!payload.scope?.includes(requiredScope)) {
  res.status(403).json({ error: "insufficient_scope" });
  return;
}
(req as any).user = { id: payload.sub };
next();

Ở chế độ Bearer bạn có thể thử nghiệm:

  • dán token thiếu scope cần thiết và đảm bảo server phản hồi 403/401;
  • dán token có aud sai và xem server từ chối;
  • dán token hết hạn để kiểm tra lỗi invalid_token.

Đây là chế độ “đập nhanh” logic Resource Server cục bộ mà không cần UI login và PKCE. Mọi thứ bạn kiểm tra ở đây sau đó áp dụng y hệt cho token mà ChatGPT hoặc Jam sẽ lấy ở chế độ Default OAuth.

6. Chế độ OAuth with credentials (Client Credentials): token “thay mặt ứng dụng”

Giờ đến chế độ ít gặp hơn nhưng hữu ích để hiểu: OAuth with credentials, tức grant client_credentials. Trong Jam bạn chỉ định:

  • Client ID
  • Client Secret
  • các scope cần thiết (ví dụ mcp:tools)

Jam thực hiện yêu cầu tới token_endpoint của Auth Server với nội dung xấp xỉ:

POST /oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&
client_id=<ID>&
client_secret=<SECRET>&
scope=mcp:tools

Auth Server trả token, trong đó sub thường biểu thị chính client (ví dụ, sub = "mcp-jam-test-client"), chứ không phải người dùng cụ thể. Jam bắt đầu dùng token này như Bearer bình thường.

Điều này hữu ích gì trong thế giới MCP:

  • các tool dịch vụ/quản trị không gắn với người dùng cụ thể (ví dụ, xuất log, health-check, hỗ trợ kỹ thuật);
  • kiểm tra rằng MCP server biết phân biệt token người dùng và token “client”, nếu logic nghiệp vụ của bạn có tính đến điều đó.

Trong bối cảnh ChatGPT Apps, chế độ này thường không dùng, vì ChatGPT là public client nên không giữ secret (public client theo định nghĩa không có client_secret). Nhưng trong Jam, nó giúp nhìn rõ sự khác nhau giữa:

  • “Tôi chỉ nhét token có sẵn” (chế độ Bearer);
  • “Jam tự đi lấy token bằng thông tin client” (OAuth with credentials).

Trên server học tập, bạn có thể tạo MCP tool đặc biệt admin_list_all_orders, chỉ truy cập bằng token có grant_type=client_credentials và vai trò tương ứng. Đây không phải phần bắt buộc của bài hôm nay, nhưng là thử nghiệm hữu ích.

7. Chế độ Default OAuth: Authorization Code + PKCE đầy đủ, như ChatGPT

Giờ đến “nhân vật chính”: Default OAuth. Chính chế độ này gần nhất với điều ChatGPT làm khi liên kết tài khoản App của bạn. Client đọc resource_metadata, đi tới Auth Server, mở trang đăng nhập cho người dùng, nhận authorization code và đổi lấy access token theo Authorization Code + PKCE S256.

Phân tích chuỗi bước. Để trực quan — sơ đồ.

sequenceDiagram
    participant Jam as MCP Jam (Client)
    participant RS as MCP Server (Resource)
    participant PRM as /.well-known/oauth-protected-resource
    participant AS as Auth Server (Keycloak/Auth0)
    
    Jam->>RS: Gọi tool được bảo vệ (không có token)
    RS-->>Jam: 401 + WWW-Authenticate (resource_metadata=PRM)
    Jam->>PRM: GET /.well-known/oauth-protected-resource
    PRM-->>Jam: JSON với resource, authorization_servers, scopes_supported...
    Jam->>AS: GET /authorize?client_id=...&code_challenge=...&scope=...
    Note right of AS: Người dùng đăng nhập và cấp quyền
    AS-->>Jam: redirect với authorization_code
    Jam->>AS: POST /token (code + code_verifier)
    AS-->>Jam: { access_token, scope, expires_in, ... }
    Jam->>RS: Gọi tool với Authorization: Bearer <access_token>
    RS-->>Jam: Kết quả tool thành công

Trong chế độ này bạn cần kiểm tra:

  1. Phản hồi 401/WWW-Authenticate từ MCP server là hợp lệ. Nếu server không trả resource_metadata hoặc trả URL sai, Jam sẽ không thể đọc PRM và khởi chạy OAuth flow.
  2. Tài liệu .well-known/oauth-protected-resource hợp lệ. Trong đó phải có các resource, authorization_servers, scopes_supported... đúng, để Jam biết đi đâu lấy token và xin scope nào.
  3. Cấu hình Auth Server đúng.
    • Bật Authorization Code Flow với PKCE S256.
    • Client ID khớp cái được mong đợi trong PRM (hoặc đăng ký qua DCR — Dynamic Client Registration).
    • Redirect URI trong Auth Server trùng khớp chính xác với cái Jam dùng.
  4. PKCE S256. Jam tạo code_challenge và kỳ vọng Auth Server hỗ trợ phương thức S256. Nếu PKCE tắt hoặc chỉ hỗ trợ plain, flow sẽ hỏng.
  5. Scope và audience. Auth Server phải cấp token với aud phù hợp và các scope được yêu cầu (mcp:tools...), còn MCP server — phải kiểm tra chúng.

Kết quả của Default OAuth thành công, bạn sẽ có:

  • trong Jam — kết nối tới MCP server, nơi tool được bảo vệ list_user_orders trả dữ liệu chính xác cho đúng người dùng mà bạn đã đăng nhập ở Auth Server;
  • trong log của Auth Server — authorize + trao đổi token thành công;
  • trong log của MCP server — xác thực token thành công và trích được sub.

Để gỡ lỗi, thường hữu ích thêm logger đơn giản trong handler của tool, để chắc chắn rằng bạn thực sự thấy userId từ token:

// bên trong handler của MCP tool list_user_orders
export async function listUserOrders(args: any, context: any) {
  const user = context.user as { id: string };
  console.log("[MCP] listUserOrders for user", user.id);
  // sau đó bạn trả về đơn hàng của người dùng này
}

8. Hỏng ở đâu: chẩn đoán theo từng chế độ

Bây giờ bàn về cách dựa vào triệu chứng trong MCP Jam để hiểu chính xác vấn đề ở đâu: MCP server, Auth Server hay metadata. Phần này là một checklist chẩn đoán theo chế độ.

Nếu ở chế độ None:

Bạn gọi tool được bảo vệ, server trả:

  • 200 OK và thực thi ngay cả khi không có token — nghĩa là bạn chưa kiểm tra token trước tool này. Cần thêm middleware hoặc kiểm tra scope.
  • 401, nhưng không có WWW-Authenticate hoặc resource_metadata sai — Jam sẽ không biết đi đâu lấy metadata, và không thể khởi động Default OAuth. Hãy sửa header theo ví dụ ở trên.

Nếu ở chế độ Bearer Token:

  • Jam liên tục nhận 401/403 ngay cả với token mà bạn chắc chắn hợp lệ khi gọi trực tiếp (qua curl hoặc Postman). Khả năng cao logic Resource Server có vấn đề: kiểm tra aud/scope sai hoặc dùng nhầm public key để xác minh JWT.
  • Nếu Bearer token hoạt động trong Jam nhưng không hoạt động sau đó trong Default OAuth — thì vấn đề không nằm ở MCP server, mà ở Auth Server hoặc PRM: token lấy qua Default OAuth khác về scope/aud so với token bạn thử thủ công.

Nếu ở chế độ OAuth with credentials:

  • Nếu Jam không thể lấy token (lỗi ở bước /token) — hãy tìm nguyên nhân trong cấu hình client ở Auth Server (secret sai, client_credentials không được phép hoặc scope bị cấm).
  • Nếu có token nhưng MCP server từ chối — có thể server của bạn kỳ vọng sub người dùng (email/ID người dùng), còn token chỉ có định danh client. Hoặc aud/scope không khớp mong đợi.

Nếu ở chế độ Default OAuth:

Đây là kịch bản nhiều cạm bẫy nhất. Lỗi thường gặp:

  • Redirect URI sai. Auth Server báo invalid_redirect_uri hoặc đơn giản là không cấp code. Hãy đảm bảo URI của Jam được thêm vào cấu hình client của IdP không thừa dấu gạch chéo hay lỗi chính tả.
  • Thiếu hoặc PKCE không được hỗ trợ. Nếu Auth Server yêu cầu PKCE mà Jam (hoặc bản Jam cũ) không gửi code_challenge, hoặc ngược lại — Jam gửi S256 còn IdP không hỗ trợ phương thức đó, bạn sẽ thấy invalid_request.
  • Scope không khớp. Trong PRM bạn tuyên bố mcp:tools, còn client ở IdP chỉ được phép openid, hoặc ngược lại — Jam xin nhiều scope hơn IdP sẵn sàng cấp.
  • Audience (aud) không khớp. Token được cấp với aud khác với cái MCP server kỳ vọng (ví dụ, URL của tài nguyên khác). Server sẽ từ chối hợp lý.

Rất quan trọng là biết xem log ở ba nơi:

  • MCP Jam — lỗi khi phân tích PRM và khi gửi HTTP tới Auth Server;
  • Auth Server — log của /authorize/token cho biết nó từ chối vì lý do gì;
  • MCP server — lý do từ chối token (invalid_token, insufficient_scope, wrong_audience).

9. Điều này liên quan gì tới ChatGPT App thực

Vì sao chúng ta dành nhiều thời gian với Jam thay vì lao ngay vào Developer Mode của ChatGPT? Vì Jam là bệ thử: nó cho bạn quyền điều khiển các chế độ ủy quyền và hiển thị toàn bộ “nội bộ” của flow.

Khi bạn chạy Default OAuth trong Jam và đưa tới thành công, bạn thực chất xác nhận rằng:

  • .well-known/oauth-protected-resource của MCP server là chính xác;
  • Auth Server (Keycloak/Auth0/…) được cấu hình đúng;
  • vai trò, scope, audience và claims khớp kỳ vọng;
  • MCP server biết kiểm tra token và gắn token với người dùng.

ChatGPT, khi kết nối cùng MCP server, sẽ làm y như vậy: đọc PRM, đi tới Auth Server, nhận token và bắt đầu gọi tool với Authorization: Bearer.

Khác biệt là trong ChatGPT bạn chỉ thấy kết quả cuối (“liên kết tài khoản thành công” hoặc “đã có lỗi”), còn trong Jam — bạn thấy toàn bộ giao thức và có thể lần từng bước để hiểu “lỗi ở đâu”.

10. Mini-practice: kiểm thử tuần tự MCP server GiftGenius của chúng ta

Gom lại thành một kịch bản đơn giản mà bạn có thể lặp lại trên dự án của mình.

Trước tiên chạy MCP server của bạn (ví dụ, pnpm dev:mcp), đảm bảo rằng:

  • nó lắng nghe tại http://localhost:4000/mcp (hoặc URL của bạn);
  • endpoint /.well-known/oauth-protected-resource trả JSON đúng;
  • Auth Server (Keycloak) đang chạy và có public client cấu hình cho Jam/ChatGPT.

Tiếp theo:

  1. Chế độ None.
    Kết nối Jam tới MCP server không ủy quyền. Kiểm tra rằng:
    • search_gifts chạy bình thường;
    • list_user_orders trả 401 với WWW-Authenticate đúng.
  2. Chế độ Bearer Token.
    Lấy access token qua Keycloak (UI hoặc curl). Gắn vào Jam, gọi list_user_orders và đảm bảo rằng:
    • với token hợp lệ, tool chạy và trả đơn hàng của người dùng cụ thể;
    • với token thiếu mcp:tools hoặc có aud khác — server trả lỗi.
  3. Chế độ OAuth with credentials.
    Nếu bạn có confidential client: chỉ định client_idclient_secret trong Jam, đặt scope cần thiết, gọi tool kỹ thuật (ví dụ, admin_list_all_orders) và kiểm tra rằng nó chỉ hoạt động với token dịch vụ như vậy.
  4. Chế độ Default OAuth.
    Bật Default OAuth, gọi list_user_orders. Jam sẽ tự:
    • nhận 401 + WWW-Authenticate,
    • đọc PRM,
    • mở trình duyệt, nơi bạn đăng nhập vào Keycloak,
    • nhận token qua Authorization Code + PKCE,
    • gọi MCP tool với token, sau đó bạn sẽ thấy đơn hàng của mình trong phản hồi.

Nếu cả bốn chế độ hoạt động như kỳ vọng — xin chúc mừng, bạn không chỉ “cấu hình gì đó với Keycloak”, mà thật sự hiểu cách kiểm tra và gỡ lỗi toàn bộ auth flow.

11. Lỗi thường gặp khi làm việc với MCP Jam và kiểm thử ủy quyền

Trong thực tế, các vấn đề này thường lặp lại theo những mẫu lỗi. Dưới đây là vài kịch bản “không nên làm”, để bạn nhận ra qua triệu chứng.

Lỗi số 1: kỳ vọng tool được bảo vệ sẽ hoạt động ở chế độ None.
Đôi khi lập trình viên bật Jam ở chế độ None, gọi list_user_orders và ngạc nhiên vì 401, rồi “cho chắc” gỡ bỏ kiểm tra token ở server. Hậu quả là MCP tool bắt đầu hoạt động ẩn danh, điều hoàn toàn không thể chấp nhận cho dữ liệu cá nhân và kịch bản thương mại. Chế độ None là để kiểm tra rằng server từ chối đúng khi không có token và trả WWW-Authenticate với resource_metadata.

Lỗi số 2: quên hoặc cấu hình sai header WWW-Authenticate.
Rất phổ biến: server trả 401 không có WWW-Authenticate hoặc với tham số cũ resource_metadata_uri. Jam (cũng như ChatGPT) trong trường hợp này không hiểu phải đi đâu lấy Protected Resource Metadata, và Default OAuth không khởi chạy. Biến thể tối thiểu đủ dùng — WWW-Authenticate: Bearer resource_metadata="https://.../.well-known/oauth-protected-resource". Các trường realmscope là tùy chọn; điều quan trọng là đừng quên resource_metadata.

Lỗi số 3: chỉ kiểm thử chế độ Bearer và bỏ qua Default OAuth.
Lập trình viên tự lấy token, dán vào Jam, thấy mọi thứ hoạt động và nghĩ là xong. Đến khi kết nối ChatGPT thật thì hóa ra .well-known sai, PKCE không hỗ trợ, redirect URI không khớp, và linking thất bại. Kiểm thử chế độ Bearer là cần, nhưng chưa đủ. Cần chạy Default OAuth, nếu không bạn sẽ không kiểm tra một nửa các thiết lập quan trọng của Auth Server và PRM.

Lỗi số 4: dùng client_credentials ở nơi cần token người dùng.
Đôi khi trong tuyệt vọng, lập trình viên bật chế độ OAuth with credentials và bắt đầu lấy token qua client_credentials, rồi dùng chúng cho các tool người dùng như list_user_orders. Kết quả là sub trong token là client_id, không phải người dùng thật, và logic nghiệp vụ trở nên kỳ quặc (ví dụ, hiển thị dữ liệu “chung” hoặc lỗi khi tìm người dùng với ID như vậy). Với kịch bản ChatGPT có người dùng thật, cần Authorization Code + PKCE (Default OAuth), còn client_credentials chỉ phù hợp cho tác vụ dịch vụ.

Lỗi số 5: scope và audience không đồng nhất giữa PRM, Auth Server và MCP server.
Trong .well-known/oauth-protected-resource bạn khai báo resource — https://giftgenius.example.com, và scopes hỗ trợ — ["mcp:tools"]. Ở Auth Server, client được cấp token không có aud, còn MCP server khi kiểm tra token thì kỳ vọng nghiêm ngặt aud = "https://giftgenius.example.com" và có mcp:tools. Kết quả là token lấy qua Default OAuth bị MCP server từ chối, và bạn mất nửa ngày tìm “phép màu”. Luôn kiểm tra rằng PRM, cấu hình client ở IdP và kiểm tra ở middleware của MCP server thống nhất về audiencescope.

Lỗi số 6: dùng phiên bản MCP Jam quá cũ.
Đặc tả MCP Authorization phát triển tích cực, xuất hiện các trường mới (resource_metadata, PKCE flow cải thiện, công cụ gỡ lỗi bổ trợ). Nếu Jam của bạn quá cũ, nó có thể không hiểu các trường mới hoặc làm việc với tên tham số cũ. Điều này dẫn tới lỗi “siêu thực”: bạn cấu hình theo RFC mới nhất, nhưng Jam không biết xử lý. Trước khi tuyệt vọng, hãy đảm bảo Jam được cập nhật phiên bản hiện hành.

1
Nhiệm vụ
ChatGPT Apps, mức độ, bài học
Đã khóa
Chế độ Bearer Token — dev-JWT + xác thực scope/aud/exp
Chế độ Bearer Token — dev-JWT + xác thực scope/aud/exp
1
Nhiệm vụ
ChatGPT Apps, mức độ, bài học
Đã khóa
Default OAuth + OAuth with credentials — hai công cụ, hai scope, hai chế độ Jam
Default OAuth + OAuth with credentials — hai công cụ, hai scope, hai chế độ Jam
1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Xác thực và truy cập
Xác thực và truy cập
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION