وبلاگ / راهنمای مسیر یادگیری و فناوری
راهنمای مسیر یادگیری و فناوری

Passkey در ASP.NET Core 10: مهاجرت امن از رمز عبور بدون قفل‌کردن کاربر

راهنمای معماری و اجرای Passkey در ASP.NET Core Identity؛ از RP ID، Host Header و State امن تا بازیابی حساب، محدودیت منابع، rollout مرحله‌ای و آزمون مسیرهای ثبت و ورود.

· ۲۱ بازدید

ورود با معمولاً در نمایش اولیه بسیار ساده به نظر می‌رسد: کاربر یک دکمه را می‌زند، Windows Hello یا قفل زیستی گوشی را تأیید می‌کند و وارد می‌شود. پیچیدگی واقعی پشت همین تجربه کوتاه پنهان است؛ دامنه‌ای که Credential به آن متصل می‌شود، State میان دو درخواست، بازیابی حساب، تعویض دستگاه و سیاست حذف اعتبارنامه همگی بخشی از امنیت‌اند.

این مسیر را برای برنامه‌های مبتنی بر کوتاه‌تر کرده است، اما کوتاه‌شدن کد به معنی حذف تصمیم‌های معماری نیست. این راهنما نشان می‌دهد چگونه را مرحله‌ای اضافه کنید، چه کنترل‌هایی را پیش از Production بسنجید و چرا حذف فوری رمز عبور می‌تواند کاربر را قفل یا مسیر Recovery را به ضعیف‌ترین حلقه تبدیل کند.

چیست و چه چیزی نیست؟

یک Public Key Credential مبتنی بر است. هنگام Registration، Authenticator یک جفت کلید می‌سازد؛ کلید خصوصی در محیط Authenticator باقی می‌ماند و سرور کلید عمومی و داده‌های لازم را ذخیره می‌کند. هنگام Authentication، سرور Challenge تازه می‌فرستد و Authenticator پس از تأیید کاربر آن را امضا می‌کند. سرور امضا را با کلید عمومی می‌سنجد.

اثر انگشت یا Face ID خود نیست. این‌ها روش User Verification برای بازکردن Credential روی دستگاه‌اند. برنامه وب تصویر چهره یا اثر انگشت را دریافت نمی‌کند. همچنین یک Magic Link یا OTP نیست؛ امنیت آن از کلید نامتقارن، Challenge و محدودشدن Credential به Relying Party می‌آید.

چه چیزی در ASP.NET Core آماده است؟

راهنمای رسمی Passkey در ASP.NET Core Identity سه سناریوی اصلی را معرفی می‌کند: افزودن به حساب موجود، ایجاد حساب بدون Password و ورود بدون Password. قالب Blazor Web App نیز اجزای مدیریت و ورود را ارائه می‌دهد.

محدوده قابلیت را جدی بگیرید. پیاده‌سازی داخلی برای سناریوهای احراز هویت طراحی شده و جای کتابخانه عمومی برای هر مدل Attestation، سیاست سخت‌افزار سازمانی یا پروتکل سفارشی نیست. طبق مستندات Microsoft، Attestation Statement نیز به‌طور پیش‌فرض اعتبارسنجی نمی‌شود و در عامل اصلی ورود است، نه 2FA داخلی آماده.

دو Ceremony که باید کامل بمانند

Registration یا Attestation

سرور Creation Options و یک Challenge یکتا می‌سازد. مرورگر آن را به Authenticator می‌دهد، کلید ساخته می‌شود و پاسخ به سرور بازمی‌گردد. سرور پاسخ را بررسی و Public Key را به حساب درست متصل می‌کند. این فرایند دو درخواست دارد؛ اطلاعات میان آن دو همان نقطه‌ای است که پیاده‌سازی دست‌ساز اغلب آسیب‌پذیر می‌شود.

Authentication یا Assertion

سرور Request Options و Challenge تازه می‌سازد. Authenticator با کلید خصوصی امضا می‌کند و سرور Assertion را با Public Key ذخیره‌شده می‌سنجد. مشخصات WebAuthn Level 3 این دو Ceremony و نقش مرورگر، Authenticator و Relying Party را تعریف می‌کند.

Challenge نباید قابل‌پیش‌بینی یا قابل‌استفاده مجدد باشد. موفق‌شدن یک امضا نیز کافی نیست؛ Origin، RP ID، User Presence یا User Verification و State درخواست باید با سیاست برنامه تطبیق داده شوند.

RP ID؛ مرز امنیتی پنهان در نام دامنه

Relying Party ID تعیین می‌کند Credential برای کدام دامنه معتبر است. در ASP.NET Core گزینه ServerDomain این محدوده را صریح می‌کند. اگر تنظیم نشود، پیاده‌سازی می‌تواند از Host Header استفاده کند؛ بنابراین Reverse Proxy و برنامه باید Hostهای مجاز را اعتبارسنجی کنند.

  • برای محیط Production، RP ID را صریح و مستند تنظیم کنید.
  • دامنه Stage را از Production جدا نگه دارید؛ Credential یک محیط نباید ناخواسته در دیگری کار کند.
  • محتوای آپلودی یا غیرقابل‌اعتماد را زیر دامنه‌ای که در محدوده RP ID است میزبانی نکنید.
  • اگر چند Origin مجاز دارید، سیاست Origin را صریح و با آزمون منفی تعریف کنید.

برای نمونه، Credential ثبت‌شده در دامنه ریشه ممکن است محدوده زیردامنه‌ها را نیز تحت تأثیر قرار دهد. این تصمیم باید با معماری Tenantها، CDN، پنل مدیریت و دامنه‌های مشتری هماهنگ شود، نه این‌که از روی مقدار Host اولین درخواست حدس زده شود.

HTTPS و Host Header فقط تنظیم زیرساخت نیستند

عملیات در Production به HTTPS وابسته است. HSTS، پایان درست TLS در Proxy و انتقال معتبر Forwarded Headers باید همراه با برنامه آزموده شوند. اگر برنامه پشت Load Balancer قرار دارد، نباید هر Host ارسالی کاربر را معتبر فرض کند.

در کانتینر، یکسان‌بودن تنظیمات میان Kestrel، Ingress و DNS اهمیت دارد. اصول تکرارپذیری مطرح‌شده در راهنمای Docker برای توسعه‌دهندگان را به احراز هویت گسترش دهید: Configuration دامنه را نسخه‌بندی کنید، Secret را بیرون Image نگه دارید و Smoke Test را با Host واقعی اجرا کنید.

State ثبت‌نام را در Hidden Field نگذارید

مستندات Microsoft هشدار می‌دهد State تولیدشده میان Creation Options و پاسخ Credential باید چهار ویژگی داشته باشد: تمامیت، اتصال به Session و کاربر درخواست‌کننده، مصرف یک‌باره و عمر کوتاه. اگر شناسه کاربر داخل Hidden Field یا Storage محافظت‌نشده باشد، مهاجم می‌تواند خود را به حساب دیگری متصل کند.

مسیر پیشنهادی معمولاً استفاده از متدهای SignInManager است؛ این مسیر State موقت را مدیریت می‌کند. اگر ناچارید IPasskeyHandler را مستقیم فراخوانی کنید، State را روی سرور یا با ASP.NET Core Data Protection محافظت کنید، آن را پیش از مصرف حذف و نتیجه User Entity را با کاربر واردشده مقایسه کنید.

طراحی Recovery پیش از حذف Password

مقاوم در برابر فیشینگ است، اما کاربر ممکن است دستگاهش را از دست بدهد، Sync Provider را تغییر دهد یا Credential را پاک کند. اگر Recovery فقط یک ایمیل ضعیف باشد، مهاجم مسیر اصلی را دور می‌زند. از طرف دیگر، نبود Recovery می‌تواند صاحب واقعی حساب را قفل کند.

  1. در شروع، را به حساب موجود اضافه کنید و روش قبلی را فوراً حذف نکنید.
  2. ثبت حداقل دو یا یک Credential پشتیبان را تشویق کنید.
  3. Recovery Code را یک‌بار نمایش و ذخیره امن آن را توضیح دهید.
  4. برای Recovery حساس، Risk Signal، تأخیر، اعلان و بررسی دستگاه قبلی را ترکیب کنید.
  5. حذف آخرین را به Re-authentication و یک روش پشتیبان معتبر وابسته کنید.

طبق راهنمای Microsoft، پرچم‌های Backup Eligibility و Backup State می‌توانند برای درخواست Credential اضافی کمک کنند. این سیگنال‌ها جای سیاست Recovery را نمی‌گیرند، اما در تشخیص حساب تک‌نقطه‌ای مفیدند.

Attestation؛ نیاز سازمانی یا پیچیدگی اضافه؟

Attestation می‌تواند درباره مدل Authenticator اطلاعاتی بدهد، اما اعتبارسنجی زنجیره اعتماد و نگه‌داری Trust Store ساده نیست. ASP.NET Core به‌طور پیش‌فرض Attestation Statement را validate نمی‌کند و Microsoft پیشنهاد می‌کند فقط وقتی نیاز مشخصی برای محدودکردن Authenticator دارید سراغ اعتبارسنجی سفارشی بروید.

برای محصول عمومی، الزام سخت‌افزار خاص می‌تواند نرخ موفقیت ثبت را کاهش دهد. برای سامانه سازمانی پرریسک، ممکن است AAGUID و فهرست مدل‌های مجاز لازم باشد. تصمیم را براساس Threat Model بگیرید، نه تصور این‌که Attestation همیشه امنیت بیشتری بدون هزینه ایجاد می‌کند.

محدودیت منابع را فراموش نکنید

Endpoint ثبت می‌تواند برای پرکردن پایگاه داده یا ایجاد Stateهای موقت فراوان سوءاستفاده شود. راهنمای Microsoft پیشنهاد می‌کند تعداد هر کاربر و طول نام نمایشی محدود شود. این کنترل‌ها را با Rate Limit، الزام ورود برای افزودن Credential و Audit تکمیل کنید.

  • حداکثر تعداد Credential فعال برای هر حساب؛
  • حداکثر طول و Character Policy برای Display Name؛
  • Rate Limit جدا برای Creation Options و ثبت نهایی؛
  • انقضای کوتاه State و پاک‌سازی Stateهای ناقص؛
  • Audit برای افزودن، تغییرنام و حذف ؛
  • اعلان به کاربر پس از تغییر Credentialهای امنیتی.

مهاجرت چهارمرحله‌ای بدون قفل‌کردن کاربر

مرحله اول: مشاهده و آماده‌سازی

پشتیبانی مرورگر و دستگاه، نرخ استفاده از MFA، تعداد Recovery موفق و شکست‌های ورود را اندازه بگیرید. برای انواع کاربر—عمومی، مدیر، پشتیبان و حساب سرویس—سیاست جدا داشته باشید. برای حساب انسانی است؛ حساب سرویس به Credential ماشین مناسب نیاز دارد.

مرحله دوم: ثبت اختیاری

پس از ورود مطمئن، افزودن را پیشنهاد دهید. نام قابل‌فهم مانند «لپ‌تاپ کاری» بگیرید و تاریخ ثبت و آخرین استفاده را نشان دهید. حذف و تغییرنام باید ساده اما محافظت‌شده باشد.

مرحله سوم: ترجیح در ورود

را گزینه نخست رابط کنید و Password را به مسیر جایگزین ببرید. نرخ Success، Cancel، Timeout و بازگشت به Password را براساس Browser و Device بررسی کنید. متن خطا نباید اطلاعات وجود حساب را افشا کند.

مرحله چهارم: Passwordless انتخابی

فقط کاربری که چند Credential یا Recovery قوی دارد وارد حالت بدون Password شود. حذف Password باید تصمیم آگاهانه و قابل‌بازگشت باشد. برای نقش‌های حساس، سیاست جدا و Re-authentication قوی تعریف کنید.

مثال معماری برای برنامه Blazor

راهنمای Blazor Web App نقطه شروع مناسبی برای اجزای رابط و اتصال به است. در معماری Production، جریان را به چند مسئولیت تقسیم کنید: Endpoint تولید Options، Cookie یا State محافظت‌شده، فراخوانی در مرورگر، Endpoint اعتبارسنجی پاسخ، ذخیره Credential و Audit.

کد Domain باید نتیجه‌ها را شفاف مدل کند: موفقیت، Challenge منقضی، Origin نامعتبر، Credential ناشناخته، User Verification ناموفق و Conflict. الگوهای Result و Pattern Matching که در راهنمای Union Type در C# 15 بررسی شده‌اند، برای جلوگیری از تبدیل همه شکست‌ها به Exception عمومی مفیدند.

ماتریس آزمون ضروری

  • ثبت روی Authenticator پلتفرم و Security Key در صورت پشتیبانی محصول؛
  • ورود روی همان دستگاه و Cross-device Flow؛
  • Challenge منقضی، مصرف‌شده و دستکاری‌شده؛
  • Origin و Host نامعتبر، HTTP و Proxy با Header اشتباه؛
  • حذف Credential، آخرین Credential و Credential حساب دیگر؛
  • لغو توسط کاربر، Timeout و دستگاه بدون قابلیت لازم؛
  • Recovery پس از گم‌شدن دستگاه و تغییر ایمیل؛
  • Rate Limit و سقف تعداد Credential؛
  • Accessibility دکمه‌ها، پیام خطا و جریان استفاده با صفحه‌کلید.

آزمون واحد برای Serialization کافی نیست. Ceremony واقعی به Browser و Authenticator وابسته است؛ حداقل یک مجموعه End-to-End روی سیستم‌عامل‌ها و مرورگرهای هدف اجرا کنید.

شاخص‌های rollout که باید دیده شوند

نرخ ثبت ، Success ورود، زمان کامل‌شدن، Cancel، Timeout، fallback به Password، تعداد Credential هر حساب و درخواست Recovery را اندازه بگیرید. داده‌ها را به‌صورت Aggregate نگه دارید و از ثبت اطلاعات حساس Credential در Log خودداری کنید.

افزایش ثبت بدون کاهش Recovery یا Support Ticket نشانه بهتری از صرفاً زیادشدن کلیک دکمه است. برای نقش‌های حساس، رویداد افزودن یا حذف باید هشدار و Audit قابل‌پیگیری داشته باشد.

خطاهای رایج

  • فرض‌کردن این‌که Biometric به سرور ارسال می‌شود؛
  • اعتماد به Host Header بدون Allowlist؛
  • قرار دادن State ثبت‌نام در Hidden Field محافظت‌نشده؛
  • حذف فوری Password بدون Recovery آزموده‌شده؛
  • نداشتن سقف Credential و Rate Limit؛
  • نادیده‌گرفتن Origin و زیردامنه‌های غیرقابل‌اعتماد؛
  • اجرای سفارشی کامل وقتی SignInManager سناریو را پوشش می‌دهد؛
  • ذخیره پاسخ خام یا داده حساس در Logهای عمومی.

چک‌لیست پیش از Production

  • ServerDomain یا RP ID صریح و Hostهای مجاز محدود شده‌اند.
  • HTTPS، HSTS و Forwarded Headers در مسیر واقعی آزموده شده‌اند.
  • State دارای Integrity، Session Binding، Expiration و Single-use است.
  • مالکیت حساب پیش از ذخیره Credential دوباره بررسی می‌شود.
  • Recovery و حذف آخرین سیاست روشن دارند.
  • سقف تعداد، طول نام و Rate Limit اعمال شده‌اند.
  • Audit و اعلان تغییر Credential فعال‌اند.
  • ماتریس Browser، Device و Failure Path پاس شده است.
  • Rollout مرحله‌ای، Feature Flag و Rollback آماده‌اند.

جمع‌بندی

Passkey می‌تواند تجربه ورود را ساده‌تر و مقاومت در برابر فیشینگ را بیشتر کند، زیرا سرور Secret مشترک Password را نگه نمی‌دارد و Credential به Relying Party مربوط محدود می‌شود. اما امنیت نهایی به تمام مسیر وابسته است: دامنه، State، Recovery، مدیریت Credential و Monitoring.

در از قابلیت داخلی و الگوی SignInManager شروع کنید. ابتدا ثبت اختیاری، سپس ترجیح و در پایان Passwordless انتخابی را بسنجید. هر مرحله باید شاخص موفقیت، آزمون منفی و مسیر بازگشت داشته باشد. تکنولوژی ورود وقتی موفق است که هم مهاجم را متوقف کند و هم صاحب واقعی حساب راه امنی برای بازگشت داشته باشد.

اگر می‌خواهید را بدون تضعیف بازیابی حساب یا قفل‌کردن کاربران به سامانه ASP.NET Core خود اضافه کنید، برای ممیزی معماری احراز هویت و طراحی rollout با خانه برنامه‌نویسان البرز در تماس باشید.