userVerification شیرجه عمیق

این سند در مورد اینکه userVerification در WebAuthn چیست و رفتارهای مرورگر هنگام مشخص کردن userVerification در هنگام ایجاد رمز عبور یا احراز هویت، بحث می‌کند.

«تأیید کاربر» در WebAuthn چیست؟

کلیدهای عبور بر اساس رمزنگاری کلید عمومی ساخته شده‌اند. با ایجاد یک کلید عبور، یک جفت کلید عمومی-خصوصی ایجاد می‌شود، کلید خصوصی توسط ارائه‌دهنده کلید عبور ذخیره می‌شود و کلید عمومی برای ذخیره به سرور طرف اعتمادکننده (RP) بازگردانده می‌شود. سرور می‌تواند با تأیید امضای امضا شده توسط همان کلید عبور با استفاده از کلید عمومی جفت شده، کاربر را احراز هویت کند. پرچم "کاربر حاضر" (UP) روی اعتبارنامه کلید عمومی ثابت می‌کند که شخصی در طول احراز هویت با دستگاه تعامل داشته است.

تأیید کاربر یک لایه امنیتی اختیاری است که تلاش می‌کند تأیید کند که فرد صحیح در هنگام احراز هویت حضور داشته است، نه فقط یک شخص خاص، همانطور که حضور کاربر تأیید می‌کند. در تلفن‌های هوشمند، این کار معمولاً با استفاده از مکانیسم قفل صفحه انجام می‌شود، چه بیومتریک باشد و چه پین ​​یا رمز عبور. اینکه آیا تأیید کاربر انجام شده است یا خیر، در پرچم "UV" گزارش می‌شود که در داده‌های تأییدکننده هنگام ثبت رمز عبور و احراز هویت بازگردانده می‌شود.

پنجره‌ی تأیید کاربر در iCloud Keychain در macOS. این پنجره از کاربر می‌خواهد که با استفاده از Touch ID وارد سیستم شود و مبدا درخواست‌کننده‌ی احراز هویت و همچنین نام کاربری را نمایش می‌دهد. در سمت راست بالای پنجره، دکمه‌ای با عنوان «لغو» وجود دارد.
پنجره‌ی تأیید کاربر در کروم اندروید. این پنجره از کاربر می‌خواهد هویت خود را با استفاده از تشخیص چهره یا اثر انگشت تأیید کند و مبدأ درخواست احراز هویت را نمایش می‌دهد. در پایین سمت چپ گزینه‌ای برای تأیید با استفاده از پین وجود دارد.

نحوه اعتبارسنجی UP و UV روی سرور

پرچم‌های بولی حضور کاربر (UP) و تأیید کاربر (UV) در فیلد داده‌های تأییدکننده به سرور ارسال می‌شوند. در حین تأیید اعتبار، محتوای فیلد داده‌های تأییدکننده می‌تواند با تأیید امضا با استفاده از کلید عمومی ذخیره شده، اعتبارسنجی شود. تا زمانی که امضا معتبر باشد، سرور می‌تواند پرچم‌ها را معتبر بداند.

تصویری از ساختار داده احراز هویت.
فیلدهای داده‌ی احراز هویت‌کننده در یک اعتبارنامه‌ی کلید عمومی. از چپ به راست، هر بخش از ساختار داده شامل موارد زیر است: 'RP ID HASH' (32 بایت)، 'FLAGS' (1 بایت)، 'COUNTER' (4 بایت، big-endian uint32)، 'ATTETE CRED. DATA' (طول متغیر در صورت وجود) و 'EXTENSIONS' (طول متغیر در صورت وجود (CBOR)). بخش 'FLAGS' گسترش یافته تا فهرستی از پرچم‌های بالقوه را نشان دهد که از چپ به راست برچسب‌گذاری شده‌اند: 'ED'، 'AT'، '0'، 'BS'، 'BE'، 'UV'، '0' و 'UP'.

هنگام ثبت رمز عبور و احراز هویت، سرور باید بسته به نیاز، بررسی کند که آیا پرچم UP true است یا false ، و آیا پرچم UV true است یا false .

پارامتر userVerification را مشخص کنید

طبق مشخصات WebAuthn ، RP می‌تواند با پارامتر userVerification در هر دو مرحله ایجاد و تأیید اعتبارنامه، درخواست تأیید کاربر را بدهد. این پروتکل مقادیر 'preferred' ، 'required' یا 'discouraged' را می‌پذیرد که به ترتیب به معنی زیر هستند:

  • 'preferred' (پیش‌فرض): استفاده از یک روش تأیید کاربر روی دستگاه ترجیح داده می‌شود ، اما در صورت عدم دسترسی می‌توان از آن صرف نظر کرد. اعتبارنامه پاسخ شامل یک پرچم UV با مقدار true در صورت انجام تأیید کاربر و false در صورت عدم انجام UV است.
  • 'required' : فراخوانی یک روش تأیید کاربر موجود در دستگاه الزامی است. اگر چنین روشی در دسترس نباشد، درخواست به صورت محلی با شکست مواجه می‌شود. این بدان معناست که اعتبارنامه پاسخ همیشه با پرچم UV که روی true تنظیم شده است، برمی‌گردد.
  • 'discouraged' : استفاده از روش تأیید کاربر توصیه نمی‌شود. با این حال، بسته به دستگاه، تأیید کاربر ممکن است به هر حال انجام شود و پرچم UV می‌تواند حاوی true یا false باشد.

نمونه کد برای ایجاد رمز عبور:

const publicKeyCredentialCreationOptions = {
  // ...
  authenticatorSelection: {
    authenticatorAttachment: 'platform',
    residentKey: 'required',
    requireResidentKey: true,
    userVerification: 'preferred'
  }
};

const credential = await navigator.credentials.create({
  publicKey: publicKeyCredentialCreationOptions
});

نمونه کد برای احراز هویت با رمز عبور:

const publicKeyCredentialRequestOptions = {
  challenge: /* Omitted challenge data... */,
  rpId: 'example.com',
  userVerification: 'preferred'
};

const credential = await navigator.credentials.get({
  publicKey: publicKeyCredentialRequestOptions
});

برای userVerification کدام گزینه را باید انتخاب کنید؟

مقدار userVerification که باید استفاده کنید به الزامات برنامه شما و همچنین نیازهای تجربه کاربری شما بستگی دارد.

چه زمانی از userVerification='preferred' استفاده کنیم؟

اگر تجربه کاربری را بر حفاظت اولویت می‌دهید، از userVerification='preferred' استفاده کنید.

محیط‌هایی وجود دارند که تأیید کاربر بیشتر از محافظت، دردسرساز است. برای مثال، در macOS که Touch ID در دسترس نیست (چون دستگاه از آن پشتیبانی نمی‌کند، غیرفعال است یا دستگاه در حالت clamshell قرار دارد)، از کاربر خواسته می‌شود که به جای آن رمز عبور سیستم خود را وارد کند. این باعث دردسر می‌شود و ممکن است کاربر احراز هویت را به طور کامل کنار بگذارد. اگر حذف دردسر برای شما مهم‌تر است، از userVerification='preferred' استفاده کنید.

کادر محاوره‌ای رمز عبور در macOS که وقتی Touch ID در دسترس نیست، ظاهر می‌شود.
یک کادر محاوره‌ای رمز عبور که در macOS نمایش داده می‌شود، زمانی که Touch ID در دسترس نیست. این کادر محاوره‌ای حاوی اطلاعاتی مانند مبدا درخواست احراز هویت و همچنین نام کاربری است. در سمت راست بالای کادر محاوره‌ای، دکمه‌ای با عنوان «لغو» وجود دارد.

با userVerification='preferred' ، اگر تأیید کاربر با موفقیت انجام شود، پرچم UV برابر با true و اگر تأیید کاربر نادیده گرفته شود، false خواهد بود. برای مثال، در macOS که Touch ID در دسترس نیست، از کاربر خواسته می‌شود برای نادیده گرفتن تأیید کاربر، روی دکمه‌ای کلیک کند و اعتبارنامه کلید عمومی شامل یک پرچم UV false است.

پرچم UV می‌تواند به عنوان یک سیگنال در تحلیل ریسک شما عمل کند. اگر تلاش برای ورود به سیستم به دلیل عوامل دیگر پرخطر به نظر برسد، در صورت عدم انجام تأیید کاربر، ممکن است بخواهید چالش‌های ورود بیشتری را برای کاربر ارائه دهید.

چه زمانی از userVerification='required' استفاده کنیم؟

اگر فکر می‌کنید هر دو مورد UP و UV کاملاً ضروری هستند، از userVerification='required' استفاده کنید.

نکته منفی این گزینه این است که کاربر ممکن است هنگام ورود به سیستم با مشکل بیشتری مواجه شود. برای مثال، در macOS که Touch ID در دسترس نیست، از کاربر خواسته می‌شود رمز عبور سیستم خود را وارد کند.

با استفاده از userVerification='required' می‌توانید مطمئن شوید که تأیید کاربر روی دستگاه انجام می‌شود. مطمئن شوید که سرور تأیید می‌کند که پرچم UV true است.

نتیجه‌گیری

با تأیید کاربر، طرفین متکی به رمز عبور می‌توانند احتمال ورود صاحب دستگاه را ارزیابی کنند. این انتخاب آنهاست که آیا تأیید کاربر را الزامی کنند یا آن را اختیاری کنند، بسته به اینکه مکانیسم ورود مجدد چقدر بر جریان کاربر تأثیر می‌گذارد. مطمئن شوید که سرور پرچم UP و پرچم UV را برای تأیید اعتبار کاربر با کلید عبور بررسی می‌کند.