فاز 13 · درس 16

مجوزدهی در MCP: روش CIMD، تفکیک صادرکننده، PKCE و ارتقای دامنه

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
پیش‌نیاز
فاز 13 · درس 09 (بسترهای انتقال)، فاز 13 · درس 15 (امنیت)
نمایی شماتیک از چندین قفل و سند متصل به کلیدهای دیجیتال رمزنگاری‌شده در کنار سرورهای ابری امن
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم اصلی
  4. سه نقش اصلی را بشناسید
  5. مجوزدهی روی HTTP اعمال می‌شود
  6. کار را با فراداده‌ی منبع حفاظت‌شده آغاز کنید
  7. فراداده‌ی سرور مجوزدهی را اعتبارسنجی کنید
  8. اولویت ثبت‌نام را رعایت کنید
  9. اسناد فراداده‌ی شناسه‌ی کلاینت را ترجیح دهید
  10. DCR یک مسیر سازگاری است
  11. اعتبارنامه‌ها را به صادرکننده مقید کنید
  12. کد مجوزدهی به‌همراه PKCE
  13. فیلد iss را دقیقاً اعتبارسنجی کنید
  14. مخاطب را در سرور MCP اعتبارسنجی کنید
  15. کمترین دامنه‌ی مورد نیاز فعلی را درخواست کنید
  16. مجوزدهی و ارتباطات بی‌وضعیت MCP
  17. عدم پاس دادن مستقیم توکن
  18. رفرش توکن‌ها
  19. پیاده‌سازی عملی
  20. استفاده در عمل
  21. تحویل پروژه
  22. تمرین‌ها
  23. اصطلاحات کلیدی
  24. برای مطالعه‌ی بیشتر

وقتی ابزارها و منابع را از طریق پروتکل زمینه‌ی مدل (MCP) روی بستر HTTP و به‌صورت راه‌دور در اختیار عامل‌های هوشمند می‌گذارید، موضوع امنیت و کنترل دسترسی دیگر یک ویژگی اختیاری نیست. با فراخوانی هر ابزار، داده‌های حساس خوانده شده یا عملیات پرهزینه‌ای اجرا می‌شوند؛ بنابراین سیستم باید دقیقاً بداند چه کسی، با چه مجوزی و برای کدام منبع درخواست را فرستاده است.

در نسخه‌های جدید MCP، نشست‌های مانا و پروتکل‌های بدون وضعیت جای خود را به کنترل‌های دقیق‌تر داده‌اند. با بهره‌گیری از اسناد فراداده‌ی شناسه‌ی کلاینت (CIMD)، جایگزین کردن روش‌های منسوخ مثل DCR و مقیدسازی کامل توکن به سرور صادرکننده و منبع نهایی، راه نفوذ و سواستفاده از توکن‌های متفرقه بسته می‌شود.

در این درس یاد می‌گیرید چطور کشف خودکار سرورهای مجوزدهی را با استانداردهای RFC 9728 و RFC 8707 پیاده‌سازی کنید، جریان PKCE را در سطح کلاینت به کار ببرید و در صورت نیاز به دسترسی‌های بالاتر، دامنه‌ها را بدون قطعی ارتباط ارتقا دهید.

یک درخواست MCP راه‌دور بی‌وضعیت است، اما مجوزدهی آن ناشناس نیست. هر فقره اعتبارنامه را به صادرکننده‌ای مقید کنید که آن را ایجاد کرده و هر توکن را به منبعی که دریافتش می‌کند.

اهداف یادگیری

  • کشف سرورهای مجوزدهی از طریق فراداده‌ی منبع حفاظت‌شده.
  • ترجیح دادن اسناد فراداده‌ی شناسه‌ی کلاینت (Client ID Metadata Documents) به ثبت پویای کلاینتِ (Dynamic Client Registration) منسوخ‌شده.
  • تعیین application_type صحیح در مواقعی که استفاده از مسیر سازگاری DCR ناگزیر است.
  • اعتبارسنجی iss در پاسخ مجوزدهی و جداسازی اعتبارنامه‌ها بر اساس صادرکننده.
  • به‌کارگیری PKCE، نشانگرهای منبع، اعتبارسنجی مخاطب (audience) و دامنه‌های افزایشی.
  • ارسال درخواست‌های دارای مجوز MCP 2026-07-28 بدون نشست‌های پروتکل.

صورت مسئله

یک سرور MCP راه‌دور ممکن است رکوردهای محرمانه را بخواند، روی سیستم‌های خارجی بنویسد یا پردازش‌های پرهزینه‌ای راه بیندازد. احراز هویت مشخص می‌کند چه کسی اعتبارنامه را ارائه داده است. مجوزدهی باید به این پرسش‌ها نیز پاسخ دهد:

  • کدام سرور مجوزدهی این اعتبارنامه را صادر کرده است؟
  • این توکن برای کدام منبع MCP است؟
  • کدام کلاینت و URI بازهدایت این فرایند را کامل کرده‌اند؟
  • کاربر با کدام عملیات‌ها موافقت کرده است؟
  • آیا این درخواستِ مشخص همچنان با آن موافقت همخوانی دارد؟

پروفایل مجوزدهی 2026-07-28، فرایند ثبت کلاینت و کار با صادرکننده را سخت‌گیرانه‌تر می‌کند. این پروفایل اسناد فراداده‌ی شناسه‌ی کلاینت را ترجیح می‌دهد، ثبت پویای کلاینت را منسوخ می‌داند، تعیین application_type درست را در DCR الزامی می‌کند، پاسخ‌های صادرکننده را بر اساس RFC 9207 می‌سنجد و استفاده‌ی مجدد از اعتبارنامه میان صادرکنندگان مختلف را ممنوع می‌شمارد.

این قواعد مکمل هسته‌ی بی‌وضعیت هستند و قرار نیست دست‌دادن اصلی پروتکل یا Mcp-Session-Id را بازگردانند.

مفاهیم اصلی

سه نقش اصلی را بشناسید

  • کلاینت MCP: درخواست‌ها را به نمایندگی از مالک منبع ارسال می‌کند.
  • سرور منبع MCP: توکن دسترسی را می‌پذیرد و به اندپوینت MCP سرویس می‌دهد.
  • سرور مجوزدهی: هویت مالک منبع را احراز می‌کند، رضایت او را می‌گیرد و توکن‌ها را صادر می‌کند.

سرور منبع و سرور مجوزدهی می‌توانند توسط یک مجموعه‌ی مشترک اداره شوند، اما شناسه‌ها و وظایف اعتبارسنجی آن‌ها را از هم تفکیک کنید.

مجوزدهی روی HTTP اعمال می‌شود

مشخصات مجوزدهی MCP برای بسترهای انتقال مبتنی بر HTTP کاربرد دارد. یک سرور محلی stdio درون مرز امنیتیِ پردازه و سیستم‌عامل اجرا می‌شود؛ صرفاً برای حفظ تقارن ظاهری، فرایند ساختگی OAuth در مرورگر را به stdio اضافه نکنید.

برای Streamable HTTP راه‌دور، توکن حامل (bearer token) را در تمام درخواست‌ها درون هدر Authorization بفرستید. هرگز آن را در URL نگذارید.

کار را با فراداده‌ی منبع حفاظت‌شده آغاز کنید

سرور منبع فراداده‌ی RFC 9728 را منتشر می‌کند:

{
  "resource": "https://notes.example.com/mcp",
  "authorization_servers": ["https://auth.example.com"],
  "scopes_supported": ["notes:delete", "notes:read", "notes:write"]
}

کلاینت کارش را از URL منبع MCP شروع می‌کند، این سند را واکشی می‌کند، یکی از سرورهای مجوزدهیِ معرفی‌شده را برمی‌گزیند و سپس فراداده‌ی OAuth یا OpenID Connect آن سرور را می‌گیرد.

هنگام ساخت URL استاندارد (well-known) طبق RFC 9728، مسیر منبع را دست‌نخورده نگه دارید. برای منبع https://notes.example.com/mcp، این درس از https://notes.example.com/.well-known/oauth-protected-resource/mcp استفاده می‌کند. حذف پسوند /mcp ممکن است به انتخاب فراداده‌ی منبع حفاظت‌شده‌ی دیگری روی همان مبدأ (origin) منجر شود.

سرور مجوزدهی را از روی نام میزبان حدس نزنید. دنبال صادرکننده‌ای که از یک بدنه‌ی خطای اعتبارسنجی‌نشده به دست آمده نروید. همواره سیاستی مشخص داشته باشید که تعیین کند کلاینت به کدام صادرکنندگان اعتماد دارد.

فراداده‌ی سرور مجوزدهی را اعتبارسنجی کنید

فراداده باید اندپوینت‌ها و کنترل‌های پشتیبانی‌شده را در اختیارتان بگذارد:

{
  "issuer": "https://auth.example.com",
  "authorization_endpoint": "https://auth.example.com/authorize",
  "token_endpoint": "https://auth.example.com/token",
  "code_challenge_methods_supported": ["S256"],
  "authorization_response_iss_parameter_supported": true,
  "client_id_metadata_document_supported": true
}

استفاده از S256 را برای PKCE اجباری کنید. رشته‌ی دقیق صادرکننده را ذخیره کنید؛ چون دقیقاً همین مقدار، کلید ثبت‌نام و ذخیره‌سازی توکن خواهد شد.

اولویت ثبت‌نام را رعایت کنید

اگر کلاینت از قبل ارتباط مشخصی با صادرکننده‌ی انتخابی دارد، از اطلاعات کلاینتِ از پیش ثبت‌شده استفاده کنید. در غیر این صورت، چنانچه سرور مجوزدهی اعلام پشتیبانی کرده باشد، اسناد فراداده‌ی شناسه‌ی کلاینت (Client ID Metadata Documents یا CIMD) را در اولویت بگذارید. از DCR تنها به‌عنوان راهکار پشتیبان و سازگاری با سیستم‌های قدیمی استفاده کنید؛ اگر هیچ‌کدام از این سازوکارها در دسترس نبود، اطلاعات کلاینت را از کاربر بگیرید (prompt).

اسناد فراداده‌ی شناسه‌ی کلاینت را ترجیح دهید

یک سند فراداده‌ی شناسه‌ی کلاینت (CIMD)، یک URL با پروتکل HTTPS به سرور مجوزدهی می‌دهد که هم شناسه‌ی کلاینت است و هم نشانیِ فراداده‌ی آن:

{
  "client_id": "https://client.example.com/oauth/metadata.json",
  "client_name": "Notes desktop client",
  "application_type": "native",
  "redirect_uris": ["http://127.0.0.1:8765/callback"],
  "grant_types": ["authorization_code"],
  "response_types": ["code"]
}

سرور مجوزدهی سند را واکشی و اعتبارسنجی می‌کند. مقدار client_id باید یک HTTPS URL دارای مسیر باشد و مقدارِ داخل سند هم دقیقاً با آن URL برابری کند. فیلدهای الزامی سند شامل client_id، client_name و redirect_uris هستند. مقدار application_type هرچند در این مثال آمده، جزو شروط CIMD نیست؛ الزام جدید آن صرفاً به مسیر DCR مربوط می‌شود.

واکشی سند را یک عملیات حساس به جعل درخواست سمت سرور (SSRF) در نظر بگیرید. مقصد را به IP تبدیل و اعتبارسنجی کنید؛ آدرس‌های loopback، خصوصی، link-local و دیگر نشانی‌های غیرمجاز را رد کنید؛ پس از بازهدایت‌ها و تغییرات DNS دوباره همه‌چیز را بررسی کنید؛ برای بازهدایت‌ها، حجم بایت‌ها و زمان محدودیت بگذارید؛ فرمت JSON را اجباری کنید و کش‌کردن را فقط بر اساس کنترل‌های معتبر کش HTTP انجام دهید. با client_name و سایر فیلدهای نمایشی مانند متنی نامطمئن رفتار کنید.

روش CIMD نیاز به صدور یک شناسه‌ی پویای تازه در هر تماس اولیه را برطرف می‌کند. با این حال، نیاز به اعتبارسنجی URI بازهدایت، سیاست‌های صادرکننده یا رضایت کاربر را از بین نمی‌برد.

DCR یک مسیر سازگاری است

ثبت پویای کلاینت (DCR) همچنان برای سرورهای مجوزدهی قدیمی در دسترس است، اما برای پیاده‌سازی‌های جدید MCP منسوخ به شمار می‌رود.

هنگام استفاده از DCR، مقدار application_type را تعیین کنید:

{
  "client_name": "Notes desktop client",
  "application_type": "native",
  "redirect_uris": ["http://127.0.0.1:8765/callback"],
  "grant_types": ["authorization_code"],
  "response_types": ["code"]
}
  • کلاینت‌های دسکتاپ، موبایل، خط فرمان و loopback از native استفاده می‌کنند.
  • برنامه‌های تحت وب میزبانی‌شده روی مرورگر از web و بازهدایت‌های HTTPS راه‌دور بهره می‌برند.

حذف این فیلد در پیاده‌سازی ثبت‌نام OpenID Connect می‌تواند مقدار پیش‌فرض را روی web قرار دهد و باعث شکست یک بازهدایت معتبر loopback شود.

کد DCR را مشروط به یک تصمیم صریح برای fallback نگه دارید. بعد از هر خطای اعتبارسنجی تصادفی در CIMD، بی‌صدا به DCR سوییچ نکنید؛ این کار ممکن است یک اشکال امنیتی را به مسیری ضعیف‌تر برای ثبت کلاینت تبدیل کند.

اعتبارنامه‌ها را به صادرکننده مقید کنید

داده‌های ثبت صادرشده توسط سرور را دقیقاً ذیل همان صادرکننده ذخیره کنید:

issuer_credentials[issuer] = pre_registered_or_dcr_client
tokens[(issuer, resource)] = access_token

اگر کشف منبع حفاظت‌شده از https://auth-one.example به https://auth-two.example تغییر کرد، میزان اعتماد را دوباره بسنجید. هرگز client secret، شناسه‌ی کلاینتِ DCR، توکن دسترسیِ ثبت‌نام، رفرش توکن یا توکن دسترسیِ صادرکننده‌ی اول را برای دومی نفرستید. کلاینت‌های از پیش ثبت‌شده و DCR باید از اعتبارنامه‌هایی استفاده کنند که برای همان صادرکننده‌ی جدید ساخته شده‌اند.

شناسه‌ی کلاینت CIMD فرق دارد؛ چون یک HTTPS URL تحت میزبانی خود کلاینت است، نه اعتبارنامه‌ای که سرور مجوزدهی صادر کرده باشد. همان URL در CIMD قابل‌حمل است: صادرکننده‌ی مورد اعتماد جدید، سند را بدون نیاز به ثبت‌نام مجدد در DCR واکشی و اعتبارسنجی می‌کند. با این حال، پاسخ‌های مجوزدهی و توکن‌ها همچنان ذیل صادرکننده‌ی جدید اعتبارسنجی و ذخیره می‌شوند.

کد مجوزدهی به‌همراه PKCE

فرایند تعاملی به این صورت است:

  1. یک code_verifier با آنتروپی بالا بسازید.
  2. مقدار code_challenge را با S256 از آن تولید کنید.
  3. درخواست مجوزدهی را با مقادیر دقیق client_id، redirect_uri، scope، code_challenge و resource بفرستید.
  4. پاسخ مجوزدهی حاوی code و (در صورت ارسال) iss را دریافت کنید.
  5. پیش از استفاده از هر فیلدی در پاسخ، iss را با صادرکننده‌ی دقیقاً ثبت‌شده مطابقت دهید.
  6. کد را به‌همراه code_verifier، همان URI بازهدایت و همان resource مبادله کنید.
  7. توکن نهایی را ذیل (issuer, resource) ذخیره کنید.

پارامتر resource از استاندارد RFC 8707 در هر دو درخواست مجوزدهی و توکن می‌آید. این پارامتر URI رسمی و استاندارد سرور MCP را مشخص می‌کند.

فیلد iss را دقیقاً اعتبارسنجی کنید

استاندارد RFC 9207 از اشتباه گرفته شدن پاسخ مجوزدهی یک صادرکننده با پاسخی از سوی صادرکننده‌ی دیگر جلوگیری می‌کند.

وقتی iss در پاسخ وجود دارد، آن را بدون تغییر بزرگی و کوچکی حروف، بدون تغییر اسلش انتهایی، بدون حذف پورت پیش‌فرض و بدون نرمال‌سازی کدگذاری درصدی، با صادرکننده‌ی ذخیره‌شده مقایسه کنید. در صورت مغایرت، کاری با کد دریافتی نداشته باشید و حتی جزئیات خطای پاسخ را که ممکن است توسط مهاجم دستکاری شده باشد به کاربر نمایش ندهید.

سرور مجوزدهی که iss را بازمی‌گرداند، مقدار authorization_response_iss_parameter_supported: true را در فراداده‌اش اعلام می‌کند. کلاینت‌های امروزی حتی اگر این اعلان وجود نداشته باشد، در صورت بازگشت iss حتماً آن را اعتبارسنجی می‌کنند.

مخاطب را در سرور MCP اعتبارسنجی کنید

سرور منبع فقط توکن‌هایی را می‌پذیرد که برای خود آن صادر شده باشند:

token.issuer == configured_authorization_server
token.audience == canonical_mcp_resource

توکن‌های نامعتبر، منقضی‌شده، با صادرکننده‌ی اشتباه یا با مخاطب نادرست، خطای 401 می‌گیرند. سرور MCP نباید توکنی را که برای سرویس دیگری صادر شده بپذیرد یا انتقال دهد.

کمترین دامنه‌ی مورد نیاز فعلی را درخواست کنید

کار را با دامنه‌ای آغاز کنید که در حال حاضر لازم دارید. اگر ابزاری در ادامه‌ی کار به دامنه‌ی بیشتری نیاز داشت، سرور خطای 403 را همراه با یک چالش دامنه‌ی رسمی و معتبر بازمی‌گرداند:

WWW-Authenticate: Bearer error="insufficient_scope",
  scope="notes:delete",
  resource_metadata="https://notes.example.com/.well-known/oauth-protected-resource/mcp"

کلاینت مجوز جدید را برای کاربر شرح می‌دهد، رضایت او را می‌گیرد، فرایند مجوزدهی جدیدی را با مجموعه‌ی دامنه‌های ترکیب‌شده اجرا می‌کند و درخواست MCP را با یک id جدید برای JSON-RPC دوباره می‌فرستد.

فرض نکنید دامنه‌ی خواسته‌شده در چالش حتماً زیرمجموعه‌ای از scopes_supported است؛ این چالش برای عملیات فعلی اعتبار قطعی دارد.

مجوزدهی و ارتباطات بی‌وضعیت MCP

یک فراخوانی ابزارِ دارای مجوز همچنان بسته‌ی کامل درخواست فعلی را با خود حمل می‌کند:

POST /mcp
Authorization: Bearer <access-token>
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: notes.delete
{
  "jsonrpc": "2.0",
  "id": 12,
  "method": "tools/call",
  "params": {
    "name": "notes.delete",
    "arguments": {"id": "note-7"},
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {},
      "io.modelcontextprotocol/clientInfo": {
        "name": "oauth-lesson-client",
        "version": "1.0.0"
      }
    }
  }
}

توکن، هویتِ عامل را مجاز می‌کند و فراداده‌ی درخواست، رفتار پروتکل را تعیین می‌نماید؛ هیچ‌کدام جایگزین دیگری نیستند.

پیام‌های شبکه را با ترتیبی مشخص اعتبارسنجی کنید: نوع داده‌های JSON-RPC و فراداده، برابری هدر و بدنه، و در نهایت پشتیبانی از پروتکل. مغایرت در مسیریابی یا هدر نسخه، خطای HTTP 400 با کد -32020 برمی‌گرداند. اگر هدر و بدنه روی نسخه‌ای توافق دارند که پشتیبانی نمی‌شود، خطای HTTP 400 با کد -32022 و بخش data دقیقاً به شکل {"supported":["2026-07-28"],"requested":"<actual>"} برگردانید. یک متد ناشناخته، HTTP 404 با کد -32601 دریافت می‌کند.

تمام خطاهای درخواست، از جمله توکن نامعتبر 401 و دامنه‌ی ناکافی 403، در قالب یک بسته‌ی خطای JSON-RPC با همان id درخواست اصلی برمی‌گردند. اطلاعات ساختاریافته برای بازیابی در فیلد اختیاری data در خطا قرار می‌گیرد؛ هدر WWW-Authenticate هم همچنان یک هدر پاسخ HTTP باقی می‌ماند. اعلان‌ها (notifications) بدون id هستند، بنابراین هیچ بدنه‌ی JSON-RPC نمی‌گیرند. یک اعلان HTTP پذیرفته‌شده، پاسخ 202 با بدنه‌ی خالی برمی‌گرداند.

چون سرور متد server/discover را پیاده‌سازی کرده و ابزارها را اعلام می‌کند، باید متد الزامی tools/list را هم پیاده‌سازی کند. توصیف‌گرهای ابزار آن نام‌های پایدار، توضیحات و مقادیر inputSchema دارند که ریشه‌ی آن‌ها آبجکت است. خروجی این فهرست قطعی (deterministic) است و resultType، فراداده‌ی هویت سرور، یک ttlMs محدود و cacheScope را برمی‌گرداند. فرایند کشف و فهرست ابزارهای ناوابسته به کاربر می‌توانند پیش از مجوزدهی در دسترس باشند. اگر هرکدام بر اساس هویت کاربر فرق می‌کنند، سیاست‌های معمولی و کشینگ خصوصی را اعمال کنید.

عدم پاس دادن مستقیم توکن

سرور MCP نباید توکن دسترسی MCP کلاینت را به یک API پایین‌دستی بفرستد. یک توکن جداگانه برای سرویس پایین‌دستی با مخاطب درست بگیرید یا از الگوی صریح تبادل توکن (token exchange) استفاده کنید. اعتبارسنجی مخاطب فقط وقتی کارآمد است که سرویس‌ها توکن‌های صادرشده برای دیگران را پس بزنند.

رفرش توکن‌ها

رفرش توکن‌ها اختیاری هستند. اگر صادر شدند، آن‌ها را به صورت محرمانه نگه دارید و بر اساس صادرکننده و منبع ذخیره کنید. فرض نکنید این توکن‌ها همیشه حضور دارند. در صورتی که سرور مجوزدهی از چرخش توکن (rotation) پشتیبانی می‌کند، آن‌ها را بچرخانید و استفاده‌ی مجدد از مقادیر باطل‌شده را شناسایی کنید.

ارتقای تدریجی دامنهارتقای یک دامنه، نه کل فرایند
SCOPE STEP-UPA token scoped notes:read hits an action that needs notes:write. Instead of failing or re-running the entire OAuth dance, the server answers 403 with a WWW-Authenticate header naming the missing scope. The client asks the user to consent to just that increment, then retries with the upgraded token. Least privilege stays the default because escalation is this cheap.clientserverنیاز به نوشتنرضایت کاربراعطای notes:write؟notes:readارتقا 403WWW-Authenticate: scope=notes:writeدرخواستاعطاnotes:read+write
توکنی با دامنه notes:read با عملیاتی مواجه می‌شود که به notes:write نیاز دارد. سرور به‌جای شکست کامل یا تکرار کل مراحل OAuth، با کد 403 و هدر WWW-Authenticate حاوی دامنه ناموجود پاسخ می‌دهد. کلاینت فقط برای همان دامنه اضافه از کاربر رضایت می‌گیرد و با توکن ارتقایافته دوباره تلاش می‌کند. به دلیل کم‌هزینه بودن این ارتقا، حداقل دسترسی همچنان حالت پیش‌فرض باقی می‌ماند.

پیاده‌سازی عملی

کد code/main.py یک شبیه‌ساز درون‌پردارشی برای پروتکل و مجوزدهی است. این کد کشف منبع حفاظت‌شده، فراداده‌ی سرور مجوزدهی، ثبت‌نام CIMD، راهکار جایگزین DCR بر اساس نسخه، بررسی نوع برنامه، PKCE، اعتبارسنجی صادرکننده، توکن‌های مقید به منبع، ارتقای دامنه، server/discover، متد tools/list و درخواست بی‌وضعیت ابزار را پیاده‌سازی می‌کند.

این مدل، بدنه‌های پردازش‌شده‌ی درخواست و هدرهای مسیریابی را تحویل می‌گیرد. این کد یک تطبیق‌دهنده‌ی کامل HTTP نیست و هدرهای Content-Type یا Accept را پردازش نمی‌کند. آن را به تطبیق‌دهنده‌ی Streamable HTTP در درس 09 وصل کنید که به Content-Type: application/json و مقدار Accept شامل هر دو مورد application/json و text/event-stream نیاز دارد.

آن را اجرا کنید:

cd phases/13-tools-and-protocols/16-mcp-security-oauth-2-1
python3 code/main.py
python3 -m unittest discover code/tests -v

خروجی برنامه ابتدا فرایند کشف، سپس ثبت‌نام CIMD، یک خواندن ساده، دو مرحله ارتقای دامنه‌ی مجزا و ذخیره‌سازی اعتبارنامه‌ها بر اساس صادرکننده را نمایش می‌دهد.

استفاده در عمل

اشیاء شبیه‌ساز را به مؤلفه‌های محیط عملیاتی متصل کنید:

  • بخش ResourceServer.protected_resource_metadata تبدیل به اندپوینت RFC 9728 می‌شود.
  • بخش AuthorizationServer.metadata به فرایند کشف در RFC 8414 یا OpenID Connect بدل می‌شود.
  • بخش Client.enroll به پردازش CIMD به‌همراه یک branch صریح برای سازگاری با DCR تبدیل می‌شود.
  • اعتبارنامه‌های کلاینتِ صادرشده توسط سرور و tokens_by_issuer_resource به رکوردهای رمزنگاری‌شده تبدیل می‌شوند. نشانی CIMD می‌تواند قابل‌حمل بماند، در حالی که نتایج مجوزدهی آن همچنان مقید به صادرکننده می‌مانند.
  • بخش ResourceServer.handle تبدیل به میان‌افزاری می‌شود که پیش از هدایت درخواست، هدرهای کنونی MCP، توکن و دامنه‌ی ابزار را اعتبارسنجی می‌کند و تمام خطاهای درخواست را در یک بسته‌ی متناظر JSON-RPC نگه می‌دارد.

تحویل پروژه

این درس فایل outputs/skill-oauth-scope-planner.md را ارائه می‌دهد. این فایل اکنون ساختار اولویت‌بندی ثبت‌نام، ذخیره‌ی اعتبارنامه‌های مقید به صادرکننده، نوع برنامه، PKCE، نشانگرهای منبع، چالش‌های دامنه و محدوده‌ی درخواست‌های بی‌وضعیت فعلی را طراحی می‌کند.

تمرین‌ها

  1. چرخش رفرش توکن را اضافه کنید و در صورت استفاده‌ی مجدد از رفرش توکن قبلی، آن را پس بزنید.
  2. یک لیست مجاز (allowlist) برای صادرکننده اضافه کنید. در صورت تغییر صادرکننده، فقط نشانیِ قابل‌حمل CIMD را دوباره به کار ببرید و تمام اعتبارنامه‌ها و توکن‌های صادرشده‌ی قبلی را رد کنید.
  3. برای کدهای مجوزدهی زمان انقضا بگذارید و بررسی کنید که مبادله‌ی دیرهنگام آن‌ها ناموفق باشد.
  4. نسخه‌ای تحت وب از کلاینت با بازهدایتِ HTTPS راه‌دور بسازید و فراداده‌ی DCR آن را با کلاینتِ native مقایسه کنید.
  5. منبع دومی ذیل همان صادرکننده اضافه کنید. مطمئن شوید توکن دسترسیِ آن منبع در منبع اول کار نمی‌کند.

اصطلاحات کلیدی

اصطلاح معنی
فراداده‌ی منبع حفاظت‌شده سند RFC 9728 که منبع و سرورهای مجوزدهی را مشخص می‌کند
CIMD سند فراداده با HTTPS که نشانی آن همان شناسه‌ی کلاینت OAuth است
DCR ثبت پویای کلاینت که منسوخ شده و فقط برای سازگاری نگه داشته می‌شود
application_type مقدار native یا web که برای اعتبارسنجی قوانین URI بازهدایت به کار می‌رود
PKCE مدل اعتبارسنج و چالش S256 برای محافظت از کد مجوزدهیِ رهگیری‌شده
iss شناسه‌ی صادرکننده در پاسخ مجوزدهی طبق RFC 9207
نشانگر منبع پارامتر RFC 8707 که درخواست توکن را به یک منبع MCP مقید می‌کند
مخاطب (Audience) منبعی که توکن برای آن معتبر است
ارتقای دامنه (Step-up) جلب رضایت جدید و صدور توکن برای دامنه‌ی اضافه‌ی مورد نیاز در عملیات فعلی
اعتبارنامه‌های مقید به صادرکننده رکوردهای ثبت‌نام و توکن که دقیقاً بر اساس صادرکننده‌ی سرور مجوزدهی تفکیک شده‌اند

برای مطالعه‌ی بیشتر

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسدر تاریخ 2026-07-28، کدام سازوکار برای ثبت کلاینت‌های جدید MCP OAuth ترجیح داده می‌شود؟
  2. حین درسیک کلاینت دسکتاپ با ریدایرکت loopback باید چه application_typeای را هنگام استفاده از DCR به عنوان روش جایگزین اعلام کند؟
  3. حین درسکلاینت باید با مقدار iss در پاسخ احراز هویت چه کار کند؟
  4. حین درسکلاینت چگونه باید اعتبارنامه‌ها و توکن‌های دسترسی تولیدشده توسط صادرکننده را کلیدگذاری کند؟
  5. پس از درسمنبعی خطای 403 با دامنه notes:delete برمی‌گرداند. گام بعدی درست چیست؟
  6. پس از درسآدرس متادیتای RFC 9728 برای منبع MCP به نشانی https://notes.example.com/mcp چیست؟

سؤالات متداول

چرا روش CIMD به ثبت پویای کلاینت (DCR) ترجیح داده می‌شود؟

روش CIMD شناسه‌ی کلاینت را به یک URL با پروتکل HTTPS تبدیل می‌کند که حاوی مشخصات کلاینت است. این روش نیاز به ثبت‌نام پویا و صدور شناسه‌ی جدید در هر تماس اولیه را حذف کرده و مدیریت کلاینت را ساده‌تر و امن‌تر می‌کند.

نقش اعتبارسنجی iss بر اساس RFC 9207 چیست؟

این اعتبارسنجی مانع از این می‌شود که پاسخ مجوزدهیِ دریافتی از یک صادرکننده با پاسخی از سوی صادرکننده‌ی دیگر اشتباه گرفته شود یا مهاجم بتواند کدهای اعتبارسنجی را دستکاری کند.

در صورت ناکافی بودن دامنه (Scope) برای اجرای یک ابزار، سرور MCP چه واکنشی نشان می‌دهد؟

سرور خطای 403 را در قالب یک بسته‌ی JSON-RPC همراه با چالش رسمی دامنه (WWW-Authenticate) بازمی‌گرداند تا کلاینت پس از جلب رضایت کاربر، دامنه‌ها را ارتقا داده و درخواست را مجدداً ارسال کند.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.