如何在 iOS 上启用指纹 WebAuthn
How to enable fingerprint WebAuthn on iOS
阅读 extensive documentation about WebAuth API 后,我无法在 iOS 上成功启用平台身份验证。
我已经尝试将 Authenticator Attachment 设置为跨平台和平台,除了 iOS:
之外它们产生了一致的结果
╭────────────────┬───────────────────────┬────────────────────────────┬────────────────────────────┬───────────────────────────────────────────────╮
│ Attachment │ Windows 10 │ Android 8 │ MacOS Catalina │ iOS 13 │
│ │ Edge/Chrome │ Chrome/Opera │ Chrome/Safari │ Webkit(Everything else is this anyways) │
╞════════════════╬═══════════════════════╬════════════════════════════╬════════════════════════════╬═══════════════════════════════════════════════╡
│ cross-platform ║ USB Key │ USB/Bluetooth Key │ USB/Bluetooth Key │ USB/Bluetooth Key │
│ platform ║ Fingerprint/Face/Pin │ Fingerprint/USB/Bluetooth │ Fingerprint │ "Insert security key" │
└────────────────┴───────────────────────┴────────────────────────────┴────────────────────────────┴───────────────────────────────────────────────┘
遗憾的是,目前对 iOS 的支持仅限于外部验证器。对 iOS 的完全支持确实是阻碍广泛采用的最后一件事,所以祈祷 iOS 14 将提供所需的功能。
它在 iOS 13.3 发行说明中得到了简短的提及:
https://developer.apple.com/documentation/ios_ipados_release_notes/ios_ipados_13_3_release_notes
ETA 这将很快到来:
chrome 将不支持任何扩展:
https://bugs.chromium.org/p/chromium/issues/detail?id=1097972
Chromium 团队请求 iOS 13,14
支持 WebAuth
https://bugs.chromium.org/p/chromium/issues/detail?id=1101804
2020 年 10 月 19 日,Apple 发布了他们对 WebAuthn 的解释:https://webkit.org/blog/11312/meet-face-id-and-touch-id-for-the-web/
从 iOS 14 和 macOS Big Sur 开始支持 FaceID 和 TouchID。 要使其正常工作,对于作为平台身份验证器的每个 allowCredentials 条目,您需要添加 transport: ["internal"]
,否则将继续提示输入 USB/NFC 令牌。
本质上,这:
const publicKeyCredentialRequestOptions = {
challenge: challengeBuffer,
allowCredentials: [{
id: 'credentialsIdentifierOne', // Windows Hello
type: 'public-key'
}, {
id: 'credentialsIdentifierTwo', // iOS FaceID
type: 'public-key'
}],
timeout: 60000
}
变成这样:
const publicKeyCredentialRequestOptions = {
challenge: challengeBuffer,
allowCredentials: [{
id: 'credentialsIdentifierOne', // Windows Hello
type: 'public-key',
transports: ["internal"]
}, {
id: 'credentialsIdentifierTwo', // iOS FaceID
type: 'public-key',
transports: ["internal"]
}],
timeout: 60000
}
总的来说,这与 specs 一致,您 应该 能够通过调用 .getTransports()
检索身份验证器的传输列表AuthenticatorResponse
。这在教程中没有广泛记录,甚至没有得到广泛支持,所以要小心:
设置跨平台身份验证器时,returned 值通常只包含使用的传输方式,而不是身份验证器支持的所有传输方式。例如,YubiKey 5 NFC 仅在插入时使用 return ["usb"]
。
因此,您应该避免为这些身份验证器一起设置 transports
,或者将它们设置为所有“非内部”传输:["usb", "nfc", "ble"]
.
至于调用.getTransports()
,检查是否可用(2020年12月,Safari仍然没有),如果不可用,则回退根据您何时请求平台身份验证器或跨平台身份验证器来适当transports
。
另一个非常重要的点:如果你在你的应用程序中启动 SFSafariWebView 来处理这个问题,无论是 PWA、Cordova 还是本机,它都会意外失败。原因? Apple 决定在将 FaceID 作为选项提供给用户之前需要用户激活 (click/tap)。更糟糕的是,您不知道身份验证肯定会失败 - iOS 看起来一切都是 运行 正确,甚至提示用户插入他们的身份验证器,同时知道没有这样的身份验证器存在(凭据 ID 指向 iOS 知道的 FaceID)。
上述问题的解决方案是添加一个额外的步骤并通过要求用户在调用 WebAuthn 代码之前按下按钮来中断身份验证流程。
对我来说,来自 .Net 的 WebAuthn 是一个完整的编码转换噩梦!然而,我终于让它工作了,但后来遇到了 iOS 的问题。最后,一旦我弄清楚 Mac 和 iOS 在我设置 AuthenticatorAttachment 时都不喜欢它是怎么回事,就我而言,修复是一个简单的修复。因此,我最终不得不使用从这里获得的函数来检测 OS:
然后我编码出来如下:
var os = getOS();
if (os == 'iOS' || os =='Mac OS') {
credentialOptions.authenticatorSelection.authenticatorAttachment = undefined;
}
阅读 extensive documentation about WebAuth API 后,我无法在 iOS 上成功启用平台身份验证。
我已经尝试将 Authenticator Attachment 设置为跨平台和平台,除了 iOS:
╭────────────────┬───────────────────────┬────────────────────────────┬────────────────────────────┬───────────────────────────────────────────────╮
│ Attachment │ Windows 10 │ Android 8 │ MacOS Catalina │ iOS 13 │
│ │ Edge/Chrome │ Chrome/Opera │ Chrome/Safari │ Webkit(Everything else is this anyways) │
╞════════════════╬═══════════════════════╬════════════════════════════╬════════════════════════════╬═══════════════════════════════════════════════╡
│ cross-platform ║ USB Key │ USB/Bluetooth Key │ USB/Bluetooth Key │ USB/Bluetooth Key │
│ platform ║ Fingerprint/Face/Pin │ Fingerprint/USB/Bluetooth │ Fingerprint │ "Insert security key" │
└────────────────┴───────────────────────┴────────────────────────────┴────────────────────────────┴───────────────────────────────────────────────┘
遗憾的是,目前对 iOS 的支持仅限于外部验证器。对 iOS 的完全支持确实是阻碍广泛采用的最后一件事,所以祈祷 iOS 14 将提供所需的功能。
它在 iOS 13.3 发行说明中得到了简短的提及:
https://developer.apple.com/documentation/ios_ipados_release_notes/ios_ipados_13_3_release_notes
ETA 这将很快到来:
chrome 将不支持任何扩展:
https://bugs.chromium.org/p/chromium/issues/detail?id=1097972
Chromium 团队请求 iOS 13,14
支持 WebAuthhttps://bugs.chromium.org/p/chromium/issues/detail?id=1101804
2020 年 10 月 19 日,Apple 发布了他们对 WebAuthn 的解释:https://webkit.org/blog/11312/meet-face-id-and-touch-id-for-the-web/
从 iOS 14 和 macOS Big Sur 开始支持 FaceID 和 TouchID。 要使其正常工作,对于作为平台身份验证器的每个 allowCredentials 条目,您需要添加 transport: ["internal"]
,否则将继续提示输入 USB/NFC 令牌。
本质上,这:
const publicKeyCredentialRequestOptions = {
challenge: challengeBuffer,
allowCredentials: [{
id: 'credentialsIdentifierOne', // Windows Hello
type: 'public-key'
}, {
id: 'credentialsIdentifierTwo', // iOS FaceID
type: 'public-key'
}],
timeout: 60000
}
变成这样:
const publicKeyCredentialRequestOptions = {
challenge: challengeBuffer,
allowCredentials: [{
id: 'credentialsIdentifierOne', // Windows Hello
type: 'public-key',
transports: ["internal"]
}, {
id: 'credentialsIdentifierTwo', // iOS FaceID
type: 'public-key',
transports: ["internal"]
}],
timeout: 60000
}
总的来说,这与 specs 一致,您 应该 能够通过调用 .getTransports()
检索身份验证器的传输列表AuthenticatorResponse
。这在教程中没有广泛记录,甚至没有得到广泛支持,所以要小心:
设置跨平台身份验证器时,returned 值通常只包含使用的传输方式,而不是身份验证器支持的所有传输方式。例如,YubiKey 5 NFC 仅在插入时使用 return ["usb"]
。
因此,您应该避免为这些身份验证器一起设置 transports
,或者将它们设置为所有“非内部”传输:["usb", "nfc", "ble"]
.
至于调用.getTransports()
,检查是否可用(2020年12月,Safari仍然没有),如果不可用,则回退根据您何时请求平台身份验证器或跨平台身份验证器来适当transports
。
另一个非常重要的点:如果你在你的应用程序中启动 SFSafariWebView 来处理这个问题,无论是 PWA、Cordova 还是本机,它都会意外失败。原因? Apple 决定在将 FaceID 作为选项提供给用户之前需要用户激活 (click/tap)。更糟糕的是,您不知道身份验证肯定会失败 - iOS 看起来一切都是 运行 正确,甚至提示用户插入他们的身份验证器,同时知道没有这样的身份验证器存在(凭据 ID 指向 iOS 知道的 FaceID)。
上述问题的解决方案是添加一个额外的步骤并通过要求用户在调用 WebAuthn 代码之前按下按钮来中断身份验证流程。
对我来说,来自 .Net 的 WebAuthn 是一个完整的编码转换噩梦!然而,我终于让它工作了,但后来遇到了 iOS 的问题。最后,一旦我弄清楚 Mac 和 iOS 在我设置 AuthenticatorAttachment 时都不喜欢它是怎么回事,就我而言,修复是一个简单的修复。因此,我最终不得不使用从这里获得的函数来检测 OS:
然后我编码出来如下:
var os = getOS();
if (os == 'iOS' || os =='Mac OS') {
credentialOptions.authenticatorSelection.authenticatorAttachment = undefined;
}