เจาะลึกการยืนยันผู้ใช้

เอกสารนี้จะอธิบายว่า userVerification คืออะไรใน WebAuthn และลักษณะการทำงานของเบราว์เซอร์ที่เกิดขึ้นเมื่อมีการระบุ userVerification ในระหว่างการสร้างหรือการตรวจสอบสิทธิ์พาสคีย์

"การยืนยันตัวตนผู้ใช้" ใน WebAuthn คืออะไร

พาสคีย์สร้างขึ้นจากวิทยาการเข้ารหัสคีย์สาธารณะ การสร้างพาสคีย์จะทำให้ระบบสร้างคู่คีย์สาธารณะและส่วนตัว โดยผู้ให้บริการพาสคีย์จะจัดเก็บคีย์ส่วนตัว และระบบจะส่งคืนคีย์สาธารณะไปยังเซิร์ฟเวอร์ของ Relying Party (RP) เพื่อจัดเก็บ เซิร์ฟเวอร์สามารถตรวจสอบสิทธิ์ผู้ใช้ได้โดยการยืนยันลายเซ็นที่ลงนามด้วยพาสคีย์เดียวกันโดยใช้คีย์สาธารณะที่จับคู่ไว้ แฟล็ก "ผู้ใช้ปัจจุบัน" (UP) ในข้อมูลเข้าสู่ระบบคีย์สาธารณะจะพิสูจน์ว่ามีผู้โต้ตอบกับอุปกรณ์ในระหว่างการตรวจสอบสิทธิ์

การยืนยันผู้ใช้เป็นเลเยอร์ความปลอดภัยที่ไม่บังคับซึ่งพยายามยืนยันว่าบุคคลที่ถูกต้องอยู่ระหว่างการตรวจสอบสิทธิ์ ไม่ใช่แค่บุคคลใดก็ตามตามที่การแสดงตัวของผู้ใช้ยืนยัน ในสมาร์ทโฟน โดยปกติแล้วจะทำได้โดยใช้กลไกการล็อกหน้าจอ ไม่ว่าจะเป็นไบโอเมตริกหรือ PIN หรือรหัสผ่าน ระบบจะรายงานว่ามีการยืนยันผู้ใช้หรือไม่ในแฟล็ก "UV" ที่แสดงในข้อมูลเครื่องมือตรวจสอบสิทธิ์ระหว่างการลงทะเบียนและการตรวจสอบสิทธิ์ด้วยพาสคีย์

กล่องโต้ตอบการยืนยันผู้ใช้ในพวงกุญแจ iCloud บน macOS กล่องโต้ตอบจะแจ้งให้ผู้ใช้ลงชื่อเข้าใช้โดยใช้ Touch ID พร้อมแสดงต้นทางที่ขอการตรวจสอบสิทธิ์ รวมถึงชื่อผู้ใช้ ที่ด้านขวาบนของกล่องโต้ตอบจะมีปุ่มที่ระบุว่า "ยกเลิก"
กล่องโต้ตอบการยืนยันผู้ใช้ใน Chrome สำหรับ Android กล่องโต้ตอบจะแจ้งให้ผู้ใช้ยืนยันตัวตนโดยใช้การจดจำใบหน้าหรือการตรวจจับลายนิ้วมือ และแสดงต้นทางที่ขอการตรวจสอบสิทธิ์ ที่ด้านซ้ายล่างจะมีตัวเลือกให้ยืนยันโดยใช้ PIN

วิธีตรวจสอบ UP และ UV ในเซิร์ฟเวอร์

ระบบจะส่งสัญญาณแฟล็กบูลีนการแสดงตัวของผู้ใช้ (UP) และผู้ใช้ที่ยืนยันแล้ว (UV) ไปยังเซิร์ฟเวอร์ในช่องข้อมูลเครื่องมือตรวจสอบสิทธิ์ ในระหว่างการตรวจสอบสิทธิ์ คุณสามารถตรวจสอบเนื้อหาของช่องข้อมูลเครื่องมือตรวจสอบสิทธิ์ได้โดยการยืนยันลายเซ็นโดยใช้คีย์สาธารณะที่จัดเก็บไว้ ตราบใดที่ลายเซ็นถูกต้อง เซิร์ฟเวอร์จะถือว่าการแจ้งเป็นของจริง

ภาพโครงสร้างข้อมูลการตรวจสอบสิทธิ์
ฟิลด์ข้อมูล Authenticator ในข้อมูลเข้าสู่ระบบคีย์สาธารณะ จากซ้ายไปขวา แต่ละส่วนของโครงสร้างข้อมูลจะอ่านเป็น "แฮชรหัส RP" (32 ไบต์), "FLAGS" (1 ไบต์), "COUNTER" (4 ไบต์, uint32 แบบ Big-Endian), "ATTESTE CRED. DATA' (ความยาวตัวแปรหากมี) และ 'EXTENSIONS' (ความยาวตัวแปรหากมี (CBOR)) ส่วน "FLAGS" จะขยายเพื่อแสดงรายการ Flag ที่อาจเกิดขึ้น โดยมีป้ายกำกับจากซ้ายไปขวาเป็น "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 หากไม่มีการยืนยันตัวตนผู้ใช้
  • '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 ไม่พร้อมใช้งาน (เนื่องจากอุปกรณ์ไม่รองรับ ปิดใช้ หรืออยู่ในโหมดฝาพับ) ระบบจะขอให้ผู้ใช้ป้อนรหัสผ่านของระบบแทน ซึ่งทำให้เกิดความไม่สะดวกและผู้ใช้อาจเลิกใช้การตรวจสอบสิทธิ์ไปเลย หากการลดอุปสรรคเป็นสิ่งสำคัญกว่า ให้ใช้ userVerification='preferred'

กล่องโต้ตอบพาสคีย์ใน macOS ที่ปรากฏขึ้นเมื่อ Touch ID ไม่พร้อมใช้งาน
กล่องโต้ตอบพาสคีย์ที่แสดงใน macOS เมื่อ Touch ID ไม่พร้อมใช้งาน กล่องโต้ตอบมีข้อมูล เช่น ต้นทางที่ขอการตรวจสอบสิทธิ์ รวมถึงชื่อผู้ใช้ ที่ด้านขวาบนของกล่องโต้ตอบจะมีปุ่มที่ระบุว่า "ยกเลิก"

เมื่อใช้ userVerification='preferred' แฟล็ก UV จะเป็น true หากยืนยันผู้ใช้สำเร็จ และเป็น false หากข้ามการยืนยันผู้ใช้ เช่น ใน macOS ที่ไม่มี Touch ID ระบบจะขอให้ผู้ใช้คลิกปุ่มเพื่อข้ามการยืนยันผู้ใช้ และข้อมูลเข้าสู่ระบบคีย์สาธารณะจะมีfalse แฟล็ก UV

จากนั้นแฟล็ก UV จะเป็นสัญญาณในการวิเคราะห์ความเสี่ยง หากความพยายามในการลงชื่อเข้าใช้ดูมีความเสี่ยงเนื่องจากปัจจัยอื่นๆ คุณอาจต้องแสดงคำถามในการเข้าสู่ระบบเพิ่มเติมแก่ผู้ใช้หากไม่ได้ทำการยืนยันผู้ใช้

กรณีที่ควรใช้ userVerification='required'

ใช้ userVerification='required' หากคุณคิดว่าทั้ง UP และ UV จำเป็นอย่างยิ่ง

ข้อเสียของตัวเลือกนี้คือผู้ใช้อาจพบอุปสรรคมากขึ้นเมื่อลงชื่อเข้าใช้ ตัวอย่างเช่น ใน macOS ที่ไม่มี Touch ID ระบบจะขอให้ผู้ใช้ป้อนรหัสผ่านของระบบ

userVerification='required' ช่วยให้คุณมั่นใจได้ว่าการยืนยันผู้ใช้จะดำเนินการในอุปกรณ์ ตรวจสอบว่าเซิร์ฟเวอร์ยืนยันว่าแฟล็ก UV เป็น true

บทสรุป

การยืนยันผู้ใช้ช่วยให้ผู้ให้บริการที่ใช้พาสคีย์ประเมินความเป็นไปได้ที่เจ้าของอุปกรณ์จะลงชื่อเข้าใช้ได้ ผู้ดูแลระบบสามารถเลือกได้ว่าจะกำหนดให้มีการยืนยันผู้ใช้หรือจะเลือกให้เป็นตัวเลือกก็ได้ โดยขึ้นอยู่กับว่ากลไกการลงชื่อเข้าใช้สำรองมีความสำคัญต่อโฟลว์ของผู้ใช้มากน้อยเพียงใด ตรวจสอบว่าเซิร์ฟเวอร์ตรวจสอบแฟล็ก UP และแฟล็ก UV สำหรับการตรวจสอบสิทธิ์ผู้ใช้ด้วยพาสคีย์