חדש: רמזים, בקשות מקור קשורות וסריאליזציה של JSON ל-WebAuthn ב-Chrome

בגרסאות Chrome 128 ו-129 נוספו תכונות חדשות ומעניינות ל-WebAuthn – ממשק ה-API הבסיסי ליצירת מערכות אימות שמבוססות על מפתחות גישה.

  • רמזים: רמזים מעניקים לצדדים נסמכים (RP) שליטה טובה יותר בממשק המשתמש של WebAuthn בדפדפן. הם שימושיים במיוחד למשתמשים ארגוניים שרוצים להשתמש במפתחות אבטחה.
  • בקשות מקור קשורות: בעזרת בקשות מקור קשורות, ספקי ה-RP יכולים להפוך מפתחות גישה לתקפים בכמה דומיינים. אם יש לכם כמה אתרים, עכשיו תוכלו לאפשר למשתמשים להשתמש שוב במפתח הגישה שלהם בכל האתרים שלכם, וכך להפחית את החיכוך בכניסה.
  • סריאליזציה של JSON: ממשקי API לסריאליזציה של JSON מאפשרים לכם לפשט את הקוד של הקצה הקדמי של RP על ידי קידוד ופענוח של אפשרויות ופרטי כניסה שמועברים אל WebAuthn API וממנו.

רמזים

בעזרת hints, צדדים נסמכים (RP) יכולים עכשיו לציין העדפות של ממשק משתמש ליצירת מפתח גישה או לאימות באמצעות מפתח גישה.

בעבר, כש-RP רצה להגביל את מאמת המשתמש שבו המשתמש יכול להשתמש כדי ליצור מפתח גישה או לבצע אימות, הוא יכול היה להשתמש ב-authenticatorSelection.authenticatorAttachment כדי לציין את "platform" או את "cross-platform". הן מגבילות את אימות החשבון לאימות בפלטפורמה או לאימות נדידה, בהתאמה. בעזרת hints, המפרט הזה יכול להיות גמיש יותר.

ה-RP יכול להשתמש ב-hints האופציונלי ב-PublicKeyCredentialCreationOptions או ב-PublicKeyCredentialRequestOptions כדי לציין את "security-key",‏ "client-device" ו-"hybrid" בסדר העדפות במערך.

בדוגמה הבאה מוצגת בקשה לדוגמה ליצירת פרטי כניסה, שמעדיפה אימותים מסוג "cross-platform" עם "security-key" בתור רמז. כך Chrome יציג ממשק משתמש שמתמקד במפתחות אבטחה למשתמשים בארגון.

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    hints: ['security-key'],
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
כשמציינים את 'security-key' כתובנית, בדפדפן מוצגת תיבת דו-שיח שמתמקדת במפתח אבטחה.
כשמציינים את 'security-key' כתובעה, בדפדפן מוצגת תיבת דו-שיח שמתמקדת במפתח אבטחה.

כש-RP רוצה לתת עדיפות לתרחיש אימות במכשירים שונים, הוא יכול לשלוח בקשת אימות שמעדיפה מאמתים מסוג "cross-platform" עם "hybrid" בתור רמז.

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    residentKey: true,
    hints: ['hybrid']
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
אם מציינים 'היברידי' כתובנית, בדפדפן תוצג תיבת דו-שיח שמתמקדת בכניסה במכשירים שונים.
כשמציינים 'היברידי' כתובת, הדפדפן מציג תיבת דו-שיח שמתמקדת בכניסה במכשירים שונים.

בעזרת בקשות מקור קשורות, ספקי ה-RP יכולים לאפשר שימוש במפתחות גישה מכמה דומיינים. פיתוח חוויית כניסה מרוכזת ושימוש בפרוטוקולים של איחוד עדיין נחשבים לפתרון המומלץ לרוב האתרים. עם זאת, אם יש לכם כמה דומיינים ולא ניתן לבצע איחוד, מקורות קשורים יכולים להיות פתרון.

כל הבקשות ל-WebAuthn חייבות לציין מזהה צד נסמך (RP ID), וכל מפתחות הגישה משויכים למזהה RP יחיד. באופן מסורתי, מקור יכול לציין מזהה RP רק על סמך הדומיין שלו, כך שבמקרה כזה www.example.co.uk יכול לציין מזהה RP של example.co.uk, אבל לא של example.com. באמצעות בקשות מקור קשורות, אפשר לאמת מזהה RP שצוין על ידי אחזור קובץ JSON ידוע שנמצא בכתובת /.well-known/webauthn מהדומיין היעד. לכן, example.co.uk (וגם example.in, ‏ example.de וכו') יכולים להשתמש במזהה RP של example.com אם example.com מציין אותם בפורמט הבא:

כתובת אתר: https://example.com/.well-known/webauthn

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example.sg",
    "https://example.net",
    "https://exampledelivery.com",
    "https://exampledelivery.co.uk",
    "https://exampledelivery.de",
    "https://exampledelivery.sg",
    "https://myexamplerewards.com",
    "https://examplecars.com"
  ]
}

במאמר איך מאפשרים שימוש חוזר במפתחות גישה באתרים שונים באמצעות בקשות מקור קשורות מוסבר איך מגדירים בקשות מקור קשורות.

שרשור (serialization) של JSON

אובייקטים של בקשות ותגובות ב-WebAuthn מכילים כמה שדות שמכילים נתונים בינאריים גולמיים ב-ArrayBuffer, כמו מזהה פרטי הכניסה, מזהה המשתמש או האתגר. אם אתר רוצה להשתמש ב-JSON כדי להחליף את הנתונים האלה עם השרת שלו, צריך קודם לקודד את הנתונים הבינאריים, למשל באמצעות Base64URL. המצב הזה מוסיף מורכבות מיותרת למפתחים שרוצים להתחיל להשתמש במפתחות גישה באתרים שלהם.

WebAuthn מציע עכשיו ממשקי API לניתוח של בקשות אובייקט PublicKeyCredentialCreationOptions ו-PublicKeyCredentialRequestOptions של WebAuthn ישירות מ-JSON, ולסריאליזציה של התשובה PublicKeyCredential ישירות ל-JSON. כל השדות עם ערך ArrayBuffer שנושאים נתונים בינאריים גולמיים עוברים המרה אוטומטית מהערכים שלהם בקידוד Base64URL או אליהם. ממשקי ה-API האלה זמינים מ-Chrome 129.

לפני יצירת מפתח גישה, מאחזרים מהשרת אובייקט PublicKeyCredentialCreationOptions מקודד ב-JSON ומפענחים אותו באמצעות PublicKeyCredential.parseCreationOptionsFromJSON().

Browser Support

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

export async function registerCredential() {

  // Fetch encoded `PublicKeyCredentialCreationOptions`
  // and JSON decode it.
  const options = await fetch('/auth/registerRequest').json();

  // Decode `PublicKeyCredentialCreationOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseCreationOptionsFromJSON(options);  

  // Invoke the WebAuthn create() function.
  const cred = await navigator.credentials.create({
    publicKey: decodedOptions,
  });
  ...

אחרי שיוצרים מפתח גישה, צריך לקודד את פרטי הכניסה שנוצרו באמצעות toJSON() כדי שאפשר יהיה לשלוח אותם לשרת.

Browser Support

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

  ...
  const cred = await navigator.credentials.create({
    publicKey: options,
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch('/auth/registerResponse', credential);
  ...

לפני האימות באמצעות מפתח גישה, צריך לאחזר מהשרת את הערך PublicKeyRequestCreationOptions המקודד ב-JSON ולפענח אותו באמצעות PublicKeyCredential.parseRequestOptionsFromJSON().

Browser Support

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

export async function authenticate() {

  // Fetch encoded `PublicKeyCredentialRequestOptions`
  // and JSON decode it.
  const options = await fetch('/auth/signinRequest').json();

  // Decode `PublicKeyCredentialRequestOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseRequestOptionsFromJSON(options);

  // Invoke the WebAuthn get() function.
  const cred = await navigator.credentials.get({
    publicKey: options
  });
  ...

אחרי האימות באמצעות מפתח גישה, צריך לקודד את פרטי הכניסה שנוצרו באמצעות השיטה toJSON() כדי שניתן יהיה לשלוח אותם לשרת.

Browser Support

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

  ...
  const cred = await navigator.credentials.get({
    publicKey: options
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch(`/auth/signinResponse`, credential);
  ...

מידע נוסף

מידע נוסף על WebAuthn ועל מפתחות גישה זמין במקורות המידע הבאים: