本文档讨论了 WebAuthn 中的 userVerification
是什么,以及在 passkey 创建或身份验证期间指定 userVerification
时产生的浏览器行为。
WebAuthn 中的“用户验证”是什么?
通行密钥 (Passkey) 构建于公钥密码学之上。通过创建通行密钥,会生成一个公私钥对,私钥由通行密钥提供商存储,公钥返回给依赖方 (RP) 服务器进行存储。服务器可以通过使用配对的公钥验证由同一通行密钥签名的签名来验证用户身份。“用户存在 (UP)”公钥凭据上的标志证明在身份验证期间有人与设备进行了交互。
用户验证是可选的安全层,旨在断言在身份验证期间在场的是正确的人,而不仅仅是某些人(如用户存在所断言的那样)。在智能手机上,这通常通过使用屏幕锁定机制来完成,无论是生物识别还是 PIN 码或密码。是否执行了用户验证会在通行密钥注册和身份验证期间在身份验证器数据中返回的“UV”标志中报告。


如何在服务器上验证 UP 和 UV
用户存在 (UP) 和用户已验证 (UV) 布尔标志在身份验证器数据字段中向服务器发出信号。在身份验证期间,可以通过使用存储的公钥验证签名来验证身份验证器数据字段的内容。只要签名有效,服务器就可以认为标志是真实的。

在通行密钥注册和身份验证时,服务器应检查 UP 标志是否为 true
,以及 UV 标志是 true
还是 false
,具体取决于需求。
指定 userVerification
参数
根据 WebAuthn 规范,RP 可以在凭据创建和断言时使用 userVerification
参数请求用户验证。它接受 'preferred'
、'required'
或 'discouraged'
,分别表示:
'preferred'
(默认值):首选在设备上使用用户验证方法,但如果不可用,则可以跳过。如果执行了用户验证,则响应凭据包含true
的 UV 标志值;如果未执行 UV,则包含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'
。
在某些环境中,用户验证带来的摩擦大于保护。例如,在 Touch ID 不可用的 macOS 上(因为设备不支持、已禁用或设备处于蛤壳模式),系统会要求用户输入其系统密码。这会导致摩擦,用户可能会完全放弃身份验证。如果消除摩擦对您来说更重要,请使用 userVerification='preferred'
。

使用 userVerification='preferred'
,如果成功执行用户验证,则 UV 标志为 true
;如果跳过用户验证,则 UV 标志为 false
。例如,在 Touch ID 不可用的 macOS 上,它会要求用户单击按钮以跳过用户验证,并且公钥凭据包含 false
UV 标志。
然后,UV 标志可以成为您风险分析中的一个信号。如果由于其他因素导致登录尝试看起来有风险,则在未执行用户验证的情况下,您可能希望向用户呈现额外的登录挑战。
何时使用 userVerification='required'
如果您认为 UP 和 UV 都是绝对必要的,请使用 userVerification='required'
。
此选项的一个缺点是,用户在登录时可能会遇到更多摩擦。例如,在 Touch ID 不可用的 macOS 上,系统会要求用户输入其系统密码。
使用 userVerification='required'
,您可以确保在设备上执行用户验证。确保服务器验证 UV 标志是否为 true
。
结论
通过利用用户验证,通行密钥依赖方可以衡量设备所有者登录的可能性。是否需要用户验证,或者使其成为可选,取决于回退登录机制对用户流程的影响程度。确保服务器检查通行密钥用户身份验证的 UP 标志和 UV 标志。