Tìm hiểu chuyên sâu về userVerify

Tài liệu này thảo luận về userVerification trong WebAuthn và các hành vi của trình duyệt dẫn đến khi userVerification được chỉ định trong quá trình tạo hoặc xác thực khoá truy cập.

"Xác minh người dùng" là gì trong WebAuthn?

Khoá truy cập được tạo dựa trên tiêu chuẩn mã hoá khoá công khai. Khi bạn tạo khoá truy cập, một cặp khoá riêng tư sẽ được tạo, khoá riêng tư sẽ được trình cung cấp khoá truy cập lưu trữ và khoá công khai sẽ được trả về máy chủ (RP) của bên tin cậy để lưu trữ. Máy chủ có thể xác thực người dùng bằng cách xác minh chữ ký được ký bằng cùng một khoá truy cập bằng khoá công khai được ghép nối. "Người dùng hiện tại" Cờ (UP) trên thông tin xác thực khoá công khai chứng minh rằng ai đó đã tương tác với thiết bị trong quá trình xác thực.

Xác minh người dùng là một lớp bảo mật không bắt buộc nhằm xác nhận rằng đã có đúng người trong quá trình xác thực, chứ không chỉ một người nào đó, như khẳng định sự hiện diện của người dùng. Trên điện thoại thông minh, việc này thường được thực hiện bằng cách sử dụng cơ chế khoá màn hình, có thể là dữ liệu sinh trắc học, mã PIN hoặc mật khẩu. Liệu quá trình xác minh người dùng có được báo cáo trong "UV" hay không cờ được trả về trong dữ liệu trình xác thực trong quá trình đăng ký và xác thực khoá truy cập

Ảnh chụp màn hình hộp thoại xác minh người dùng trên iCloud Keychain trên macOS. Hộp thoại nhắc người dùng đăng nhập bằng Touch ID, hiển thị thông tin xác thực yêu cầu nguồn gốc cũng như tên người dùng. Ở phía trên cùng bên phải của hộp thoại là nút có nhãn "Huỷ".
Hộp thoại xác minh người dùng trên iCloud Keychain trên macOS.
Ảnh chụp màn hình hộp thoại xác minh người dùng trên Chrome dành cho Android. Hộp thoại này sẽ nhắc người dùng xác minh danh tính bằng công nghệ nhận dạng khuôn mặt hoặc phát hiện vân tay, đồng thời cho thấy nguồn gốc yêu cầu xác thực. Ở dưới cùng bên trái là tuỳ chọn xác minh bằng mã PIN.
Hộp thoại xác minh người dùng trên Android Chrome.

Cách xác thực UP và UV trên máy chủ

Cờ boolean hiện diện của người dùng (UP) và cờ boolean xác minh của người dùng (UV) được báo hiệu đến máy chủ trong trường dữ liệu của trình xác thực. Trong quá trình xác thực, nội dung của trường dữ liệu trình xác thực có thể được xác thực bằng cách xác minh chữ ký bằng khoá công khai đã lưu trữ. Miễn là chữ ký đó hợp lệ, máy chủ có thể coi cờ đó là thật.

Hình ảnh mô tả cấu trúc dữ liệu xác thực. Từ trái sang phải, mỗi phần của cấu trúc dữ liệu sẽ có nội dung "RP ID HASH" (32 byte), "FLAGS" (1 byte), 'Counter' (Bộ đếm) (4 byte, Big-endian uint32), "ATTESTE CRED. DỮ LIỆU (độ dài biến đổi nếu có) và 'EXTENSIONS' (độ dài biến đổi nếu có (CBOR)). 'FLAGS' được mở rộng để hiển thị danh sách các cờ tiềm năng, được gắn nhãn từ trái sang phải: 'ED', 'AT', '0', 'BS', 'BE', 'UV', '0' và 'UP'.
Các trường dữ liệu Authenticator trong thông tin xác thực khoá công khai.

Khi đăng ký và xác thực khoá truy cập, máy chủ cần kiểm tra để đảm bảo cờ UP là true và cờ UV là true hay false, tuỳ thuộc vào yêu cầu.

Chỉ định tham số userVerification

Theo quy cách WebAuthn, RP có thể yêu cầu quy trình xác minh người dùng bằng tham số userVerification trên cả quá trình tạo và xác nhận thông tin xác thực. Phương thức này chấp nhận 'preferred', 'required' hoặc 'discouraged', có nghĩa là tương ứng:

  • 'preferred' (mặc định): Việc sử dụng phương thức xác minh người dùng trên thiết bị được ưu tiên nhưng bạn có thể bỏ qua nếu không có phương thức này. Thông tin xác thực phản hồi chứa giá trị cờ UV là true nếu quá trình xác minh người dùng đã được thực hiện và false nếu không thực hiện UV.
  • 'required': Bạn cần phải gọi một phương thức xác minh người dùng có trên thiết bị. Nếu không có mã, yêu cầu sẽ không thành công trên thiết bị. Điều này có nghĩa là thông tin xác thực phản hồi luôn trả về với cờ UV được đặt thành true.
  • 'discouraged': Bạn không nên sử dụng phương thức xác minh người dùng. Tuy nhiên, tuỳ thuộc vào thiết bị, vẫn có thể thực hiện quy trình xác minh người dùng và cờ UV có thể chứa true hoặc false.

Mã mẫu để tạo khoá truy cập:

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

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

Mã mẫu để xác thực khoá truy cập:

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

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

Bạn nên chọn phương án nào cho userVerification?

Giá trị userVerification mà bạn nên sử dụng phụ thuộc vào các yêu cầu về ứng dụng cũng như nhu cầu về trải nghiệm người dùng của bạn.

Trường hợp sử dụng userVerification='preferred'

Hãy sử dụng userVerification='preferred' nếu bạn ưu tiên trải nghiệm người dùng hơn là khả năng bảo vệ.

Có những môi trường mà quá trình xác minh người dùng trở nên khó khăn hơn so với khả năng bảo vệ. Ví dụ: trên macOS không hỗ trợ Touch ID (vì thiết bị không hỗ trợ tính năng này nên bị tắt hoặc thiết bị đang ở chế độ vỏ sò), người dùng sẽ được yêu cầu nhập mật khẩu hệ thống của họ. Điều này gây phiền hà và người dùng có thể hoàn toàn bỏ qua quá trình xác thực. Nếu việc loại bỏ bước phiền hà quan trọng hơn đối với bạn, hãy sử dụng userVerification='preferred'.

Ảnh chụp màn hình hộp thoại khoá truy cập trên macOS, xuất hiện khi Touch ID không có sẵn. Hộp thoại này chứa các thông tin như xác thực yêu cầu nguồn gốc cũng như tên người dùng. Ở phía trên cùng bên phải của hộp thoại là nút có nhãn "Huỷ".
Hộp thoại khoá truy cập sẽ xuất hiện trên macOS khi không có Touch ID.

Với userVerification='preferred', cờ UV sẽ là true nếu quy trình xác minh người dùng được thực hiện thành công và false nếu quy trình xác minh người dùng bị bỏ qua. Ví dụ: trên macOS không có Touch ID, hệ thống sẽ yêu cầu người dùng nhấp vào một nút để bỏ qua quy trình xác minh người dùng và thông tin xác thực khoá công khai có cờ UV false.

Khi đó, cờ UV có thể là một tín hiệu trong bản phân tích rủi ro của bạn. Nếu việc đăng nhập có vẻ rủi ro do các yếu tố khác, bạn nên đưa ra thêm thử thách đăng nhập cho người dùng nếu không thực hiện quy trình xác minh người dùng.

Trường hợp sử dụng userVerification='required'

Hãy sử dụng userVerification='required' nếu bạn cho rằng cả UP và UV là thực sự cần thiết.

Nhược điểm của lựa chọn này là người dùng có thể gặp khó khăn khi đăng nhập. Ví dụ: trên macOS không hỗ trợ Touch ID, người dùng sẽ được yêu cầu nhập mật khẩu hệ thống của họ.

Với userVerification='required', bạn có thể đảm bảo việc xác minh người dùng được thực hiện trên thiết bị. Đảm bảo máy chủ xác minh rằng cờ UV là true.

Kết luận

Bằng cách tận dụng tính năng xác minh người dùng, các bên sử dụng khoá truy cập có thể đánh giá khả năng chủ sở hữu thiết bị đăng nhập. Họ có thể chọn yêu cầu xác minh người dùng hay không bắt buộc, tuỳ thuộc vào mức độ quan trọng của cơ chế đăng nhập dự phòng ảnh hưởng đến luồng người dùng. Đảm bảo máy chủ kiểm tra cờ UP và cờ UV để xác thực người dùng bằng khoá truy cập.