ورود یکپارچه
ورود یکپارچه به یک ارائهدهندهٔ هویت (IdP) بیرونی اجازه میدهد تصمیم بگیرد چه کسی میتواند به سرور Control Center شما وارد شود. دو پروتکل پشتیبانی میشود — SAML 2.0 و OpenID Connect — و هر دو به یک جا میرسند: یک اعتبارنامهٔ تازهساختهٔ دستگاه که در همهٔ مراحل بعدی از یک دعوت یا جفتسازی با QR قابل تشخیص نیست.
ساختار یک ورود
بخش با عنوان “ساختار یک ورود”ورودهای SAML از طریق مرورگر انجام میشوند. IdP هیچوقت اتصالی به سرور شما باز نمیکند؛ مرورگر کاربر همهچیز را حمل میکند:
browser ──> /saml/login ──> IdP ──POST SAMLResponse──> /saml/acs │ verify ▼ provision user (maybe) │ ▼ browser handoff: device PSK in the URL fragment (never a query parameter)چون مرورگر حامل است، سروری پشت NAT برای ورود بدون مشکل کار میکند: localhost، LAN، Tailscale، VPN یا یک تونل همه جواب میدهند — فقط مرورگر کاربر باید به نشانی ACS برسد. رلهٔ WebSocket که کنترل از راه دور تلفن از آن استفاده میکند نمیتواند رفتوبرگشت HTTP را حمل کند؛ به همین دلیل نقطههای ورود SSO همیشه مبدأ HTTP سرور را هدف میگیرند.
OpenID Connect همین ساختار را با یک رفتوبرگشت authorization code و PKCE دنبال میکند؛ ادعاها روی TLS از نقطهٔ پایانی توکن صادرکننده خوانده میشوند، پس مرورگر اصلاً دادهٔ هویت را تأمین نمیکند.
آداپتورها
بخش با عنوان “آداپتورها”Control Center مسئولیت را عمداً تقسیم میکند:
| قطعه | کجا | چه چیزی را در اختیار دارد |
|---|---|---|
کتابخانهٔ بومی cc_saml |
packages/cc_natives/native/saml/ |
تأیید XML-DSig، کانونیکالسازی، اعتبارسنجی پروفایل SAML — واگذارشده به crate ثابتشدهٔ saml با Rust خالص در پشت یک C ABI بیحالت |
SamlService / OidcService |
cc_server_core |
وضعیت ورود (ردیابهای درخواست در انتظار، حذف تکراری بازپخش)، تنظیمات سیاست اعتبارسنجی، فراخوانی مشترک تأمین |
SsoProvisioner |
cc_server_core |
یافتن یا ساختن کاربر، سنجاقکردن subject ارائهدهنده، اعطای عضویت زیر سیاست عضویت خودکار |
ScimService |
cc_server_core |
سطح push مربوط به SCIM 2.0 (چرخهٔ عمر تأمین و لغو تأمین) |
SsoSettingsService |
cc_server_core |
ردیفهای اتصال ذخیرهشده، اعمال مجدد زنده، توکن SCIM |
عمداً هیچ جایگزین رمزنگاری SAML تمامDart وجود ندارد: XML-DSig و
کانونیکالسازی دستساز دقیقاً همان جایی است که آسیبپذیریهای signature
wrapping زندگی میکنند؛ پس نبودِ کتابخانهٔ cc_saml هم ورود SAML و هم بالا
آمدن سرور را رد میکند. کتابخانهٔ بومی عمداً بیحالت است — وضعیت میان
درخواستها در سرویسهای Dart میماند، یکبارمصرف و کوتاهعمر.
یک ورود چه چیزی را تأیید میکند
بخش با عنوان “یک ورود چه چیزی را تأیید میکند”درون کتابخانهٔ بومی تأییدشده و سرویس، به ترتیب:
- امضای assertion (همیشه لازم؛ امضای پاکت پاسخ بسته به پیکربندی اختیاری است) — از نظر ساختاری در برابر signature wrapping مقاوم است، چون بار دادهٔ اعتبارسنجیشده به عنصر تأییدشده گره خورده،
- issuer با IdP پیکربندیشده مطابقت دارد،
- audience همین ارائهدهندهٔ سرویس را نام میبرد،
- destination همان URL مربوط به ACS ماست،
InResponseToبا یک AuthnRequest در انتظار که خودمان صادر کردهایم مطابقت دارد (پاسخهای ناخواسته و آغازشده از IdP بهطور پیشفرض خاموش هستند)،- پنجرههای lifetime در محدودهٔ انحراف ساعت میمانند (پیشفرض 90 ثانیه) و
- شناسهٔ assertion هرگز قبلاً دیده نشده باشد (کش بازپخش).
شکستها بهصورت کدهای نوعدار برمیگردند — signature، expired، audience، destination، issuer، request-match — و نقطههای پایانی با خطاهای عمومی پاسخ میدهند، تا مهاجم چیزی دربارهٔ اینکه چرا یک جعل شکست خورده یاد نگیرد.
حسابها و سنجاقکردن subject
بخش با عنوان “حسابها و سنجاقکردن subject”اولین ورود SSO، subject تغییرناپذیر ارائهدهنده (issuer بهعلاوهٔ
SAML NameID / OIDC sub یا SCIM externalId) را روی حساب سنجاق میکند. از
آن پس، این subject است — نه ایمیل — که ورود را شناسایی میکند. اگر کسی
بعداً همان ایمیل را از همان IdP یا IdP دیگری ارائه کند، حساب سنجاقشده او
را رد میکند. همین است که نمیگذارد ایمیلی بازیافتی نزد یک ارائهدهنده به
تصاحب حساب تبدیل شود.
تأمین و لغو تأمین
بخش با عنوان “تأمین و لغو تأمین”تأمین JIT هنگام ورود رخ میدهد (SsoProvisioner). SCIM یک سطح push
جداگانه است (ScimService) که همان subject را روی ردیف کاربر سنجاق
میکند؛ عضویتهای فضای کاری را اعطا نمیکند. لغو تأمین — SCIM
active: false یا DELETE — اگر حساب مالک یک فضای کاری باشد رد میکند
(اول انتقال دهید). در غیر این صورت، ابتدا هر اعتبارنامهٔ دستگاه را لغو
میکند (نشستها از طریق پایش دستگاه ظرف چند ثانیه میافتند)، هر عضویت
فضای کاری را برمیدارد و حساب را غیرفعال مهر میزند. ردیف کاربر باقی
میماند: انتساب دائمی است. فعالسازی مجدد ورود را برمیگرداند اما هرگز
عضویتها را دوباره نمیدهد.
چه چیزی بیرون میماند
بخش با عنوان “چه چیزی بیرون میماند”- نگاشت گروه→نقش هنگام ورود انجام میشود بر پایهٔ ویژگیهای SAML / ادعاهای OIDC — گروههای SCIM که push میشوند ذخیره نمیشوند.
- نقش مالک از مسیر SSO قابل دسترسی نیست — نه بهعنوان نقش پیشفرض و نه از طریق نگاشت گروه.
- رلهٔ WebSocket هرگز کانال SSO نیست؛ تلفنهایی که سرور را فقط از طریق رله میبینند نمیتوانند یک رفتوبرگشت مرورگری را با آن کامل کنند.