Расширения аутентификации веб-приложений
API аутентификации веб-приложений имеет систему расширений — дополнительные функциональные возможности, которые могут быть запрошены во время создания учетных данных (navigator.credentials.create()) или операций аутентификации (navigator.credentials.get()). Эта статья объясняет, как запрашивать расширения WebAuthn, получать информацию о ответах от этих запросов и доступные расширения — включая поддержку браузера, ожидаемые входные и выходные данные.
Как использовать расширения WebAuthn
При вызове navigator.credentials.create() или navigator.credentials.get(), параметр объекта publicKey, необходимый для запуска потока WebAuthn, может включать свойство extensions. Значение extensions само по себе является объектом, свойства которого являются входными значениями для всех расширений, использование которых желательно для стороны, запрашивающей аутентификацию, в вызываемом методе.
За кулисами входные данные обрабатываются пользовательским агентом и/или аутентификатором.
Например, в объекте publicKey для вызова create(), мы можем захотеть запросить использование двух расширений:
- Расширение
credProps. Стороны, запрашивающие аутентификацию, устанавливаютcredProps, чтобы запросить, сообщит ли браузер стороне, запрашивающей аутентификацию, является ли учетная запись постоянной/доступной после регистрации. Это полезно при вызовеcreate()сpublicKey.authenticatorSelection.residentKey = "preferred". Для его запроса также необходимо установитьpublicKey.extensions.credProps = trueпри создании учетной записи браузером и, в зависимости от типа используемого аутентификатора, она будет доступной (например, аутентификатор FIDO2 обычно делает её доступной; FIDO1/U2F-ключ безопасности не будет доступным).credPropsобрабатывается только пользовательским агентом. - Расширение
minPinLengthпозволяет сторонам, запрашивающим аутентификацию, запросить минимальную длину PIN-кода аутентификатора. Для этого требуется установитьextensions.minPinLengthна значениеtrue.minPinLengthобрабатывается аутентификатором, а пользовательский агент только передает входные данные ему.
const publicKey = {
challenge: new Uint8Array([117, 61, 252, 231, 191, 241, ...]),
rp: { id: "acme.com", name: "ACME Corporation" },
user: {
id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]),
name: "jamiedoe",
displayName: "Jamie Doe"
},
pubKeyCredParams: [ {type: "public-key", alg: -7} ],
authenticatorSelection: {
residentKey: "preferred"
},
extensions: {
credProps: true,
minPinLength: true
}
}
Затем мы можем передать объект publicKey в вызов create() для запуска потока создания учетной записи:
navigator.credentials.create({ publicKey });
Получение результатов запроса расширений
При успешном выполнении вызова create() будет возвращен Promise, который разрешается с объектом PublicKeyCredential. После завершения обработки расширений результаты обработки передаются в ответ (хотя это не всегда так — возможно, что у расширений нет выходных данных).
navigator.credentials
.create({ publicKey })
.then((publicKeyCred) => {
const myClientExtResults = publicKeyCred.getClientExtensionResults();
// myClientExtResults will contain the output of processing
// the "credProps" extension
const authData = publicKeyCred.response.getAuthenticatorData();
// authData will contain authenticator data, which will include
// authenticator extension processing results, i.e., minPinLength
})
.catch((err) => {
console.error(err);
});
Как показано в приведенном выше фрагменте кода, результаты выходных данных расширений можно найти в двух разных местах:
-
Результаты обработки расширений клиента (пользовательского агента) можно получить, вызвав метод
PublicKeyCredential.getClientExtensionResults(). Он возвращаетmap, где каждый элемент — строка идентификатора расширения в качестве ключа и результат обработки расширения клиентом в качестве значения. В приведенном выше примере, если браузер поддерживает расширениеcredPropsи оно было обработано правильно, объект картыmyClientExtResultsбудет содержать один элемент"credProps", со значением{ rk: true }. Это подтвердит, что созданная учетная запись действительно доступна. -
Результаты обработки расширений аутентификатора можно найти в данных аутентификатора для операции:
- В случае
PublicKeyCredentialвозвращаемых успешными вызовамиcreate(), это можно получить с помощью вызоваpublicKeyCredential.response.getAuthenticatorData(). - В случае
PublicKeyCredentialвозвращаемых успешными вызовамиget(), это можно найти в свойствеpublicKeyCredential.response.authenticatorData.
Данные аутентификатора представляют собой
ArrayBufferс согласованной структурой — см. данные аутентификатора. Данные о результатах расширений аутентификатора всегда находятся в последнем разделе в виде карты CBOR, представляющей результаты. См.AuthenticatorAssertionResponse.authenticatorDataдля подробного описания полной структуры данных аутентификатора.Вернемся к нашему примеру, если сторона, запрашивающая аутентификацию, имеет разрешение на получение значения
minPinLength, данные аутентификатора будут содержать его представление в следующем формате:"minPinLength": uint. - В случае
Доступные расширения
Нижеприведенные расширения не являются исчерпывающим списком всех доступных расширений. Мы выбрали для документирования те расширения, которые, как мы знаем, являются стандартными и поддерживаются, по крайней мере, одним движком рендеринга.
appid
- Используется в: Аутентификация (
get()) - Обрабатывается: Пользовательский агент
- Спецификация: Расширение FIDO AppID (appid)
Позволяет стороне, запрашивающей аутентификацию, запросить утверждение для учетной записи, ранее зарегистрированной с помощью устаревшего JavaScript API FIDO U2F, избежав необходимости повторной регистрации учетной записи. appid соответствует эквиваленту rpId в WebAuthn (хотя имейте в виду, что appid представлены в виде URL-адресов, а rpId — в виде доменов).
Входные данные
Свойство publicKey объекта extensions должно содержать свойство appid, значение которого — идентификатор приложения, используемый в устаревшем API. Например:
extensions: {
appid: "https://accounts.example.com";
}
Также необходимо перечислить идентификаторы учетных записей FIDO U2F в свойстве publicKey объекта allowCredentials, например:
allowCredentials: {
[
id: arrayBuffer, // needs to contain decoded binary form of id
transports: ["nfc", "usb"]
type: "public-key"
]
}
Выходные данные
Выводит appid: true, если appid успешно использовалось для утверждения, или appid: false в противном случае.
appidExclude
- Используется в: Регистрация (
create()) - Обрабатывается: Пользовательский агент
- Спецификация: Расширение исключения FIDO AppID (appidExclude)
Позволяет стороне, запрашивающей аутентификацию, исключить аутентификаторы, содержащие указанные учетные записи, ранее зарегистрированные с помощью устаревшего JavaScript API FIDO U2F, во время регистрации. Это необходимо, поскольку по умолчанию предполагается, что содержимое поля excludeCredentials представляет собой учетные записи WebAuthn. При использовании этого расширения вы можете включить учетные записи FIDO U2F устаревшего API в excludeCredentials, и они будут распознаны как таковые.
Входные данные
Свойство publicKey объекта extensions должно содержать свойство appidExclude, значение которого — идентификатор стороны, запрашивающей аутентификацию, которая хочет исключить аутентификаторы по устаревшим учетным записям FIDO U2F. Например:
extensions: {
appidExclude: "https://accounts.example.com";
}
Затем вы можете перечислить учетные записи FIDO U2F в свойстве publicKey объекта excludeCredentials, например:
excludeCredentials: {
[
id: arrayBuffer, // needs to contain decoded binary form of id
transports: ["nfc", "usb"]
type: "public-key"
]
}
Выходные данные
Выводит appidExclude: true, если расширение было обработано, или appidExclude: false в противном случае.
credProps
- Используется в: Регистрация (
create()) - Обрабатывается: Пользовательский агент
- Спецификация: Расширение свойств учетных данных (credProps)
Позволяет стороне, запрашивающей аутентификацию, запросить дополнительную информацию/свойства о созданной учетной записи. В настоящее время это полезно только при вызове create() с publicKey.authenticatorSelection.residentKey = "preferred"; запрашивается информация о том, является ли созданная учетная запись доступной.
Входные данные
Свойство publicKey объекта extensions должно содержать свойство credProps со значением true:
extensions: {
credProps: true;
}
Также необходимо установить authenticatorSelection.requireResidentKey на значение true, что указывает на необходимость постоянного ключа.
authenticatorSelection: {
requireResidentKey: true;
}
Выходные данные
Выводит следующее, если зарегистрированная PublicKeyCredential является клиентской открытой учетной записью:
credProps: {
rk: true;
}
Если rk установлено на значение false в выводе, учетная запись является серверной. Если rk отсутствует в выводе, то неизвестно, является ли учетная запись клиентской открытой или серверной.
credProtect
- Используется в: Регистрация (
create()) - Обрабатывается: Аутентификатор
- Спецификация: Защита идентификационных данных (credProtect)
Позволяет доверенной стороне указать минимальные требования к защите идентификационных данных при создании идентификатора.
Входные данные
Свойство publicKey объекта extensions должно содержать свойство credentialProtectionPolicy, указывающее уровень защиты создаваемого идентификатора, и булевое свойство enforceCredentialProtectionPolicy, указывающее, должно ли вызывать неудачу create() вместо создания идентификатора, не соответствующего заданной политике:
extensions: {
credentialProtectionPolicy: "userVerificationOptional",
enforceCredentialProtectionPolicy: true
}
Доступные значения credentialProtectionPolicy:
"userVerificationOptional"Экспериментальная-
Проверка пользователя необязательна. Эквивалентное значение
credProtectдля отправки аутентификатору равно0x01. "userVerificationOptionalWithCredentialIDList"-
Проверка пользователя необязательна только в том случае, если идентификатор обнаруживается (т.е., обнаруживается на стороне клиента). Эквивалентное значение
credProtectдля отправки аутентификатору равно0x02. "userVerificationRequired"-
Проверка пользователя всегда обязательна. Эквивалентное значение
credProtectдля отправки аутентификатору равно0x03.
Примечание: По умолчанию Chromium использует userVerificationOptionalWithCredentialIDList или userVerificationRequired, в зависимости от типа запроса:
- Chromium запросит уровень защиты
userVerificationOptionalWithCredentialIDListпри создании идентификатора, еслиresidentKeyустановлено вpreferredилиrequired. (УстановкаrequireResidentKeyобрабатывается как обязательная.) Это гарантирует, что простое физическое владение ключом безопасности не позволит запросить наличие обнаруживаемого идентификатора для заданногоrpId. - Кроме того, если
residentKeyравноrequiredиuserVerificationпредпочтительно, уровень защиты будет повышен доuserVerificationRequired. Это гарантирует, что физическое владение ключом безопасности не позволит выполнить вход на сайт, не требующий проверки пользователя. (Это не полная защита; сайты должны все же тщательно учитывать безопасность своих пользователей.) - Если сайт запросит явный уровень
credProtect, это переопределит эти значения по умолчанию. Эти значения по умолчанию никогда не приведут к снижению уровня защиты ниже значения по умолчанию для ключа безопасности, если оно выше.
Если значение enforceCredentialProtectionPolicy равно true, вызов create() завершится ошибкой, если политика не может быть соблюдена (например, требуется проверка пользователя, но аутентификатор не поддерживает проверку пользователя). Если оно равно false, система предпримет все возможное для создания идентификатора, соответствующего политике, но по-прежнему создаст идентификатор, насколько это возможно.
Выходные данные
Если вызов create() успешен, данные аутентификатора будут содержать представление значения credProtect, представляющего заданную политику в следующем формате:
{ "credProtect": 0x01 }
largeBlob
- Используется в: Регистрация (
create()) и аутентификация (get()) - Обрабатывается: Пользовательский агент
- Спецификация: Расширение для хранения больших блоков данных (largeBlob)
Позволяет доверенной стороне хранить связанные с идентификатором блоки данных на аутентификаторе — например, может напрямую хранить сертификаты вместо использования централизованной службы аутентификации.
Входные данные
Во время вызова create(), свойство publicKey объекта extensions должно содержать свойство largeBlob, имеющее следующую структуру объекта:
extensions: {
largeBlob: {
support: "required";
}
}
Значение свойства support — строка, которая может быть одной из следующих:
-
"preferred": Идентификатор будет создан с аутентификатором, способным хранить блоки данных, если возможно, но он будет создан и в случае невозможности. Свойство output'supported' сообщает о возможности аутентификатора хранить блоки данных. -
"required": Идентификатор будет создан с аутентификатором для хранения блоков данных. Вызовcreate()завершится ошибкой, если это невозможно.
Во время вызова get(), свойство publicKey объекта extensions должно содержать свойство largeBlob, имеющее одно из двух подсвойств — read или write (get() завершится ошибкой, если оба присутствуют):
Свойство read является булевым. Значение true указывает, что доверенная сторона хочет получить ранее записанный блок данных, связанный с утверждаемым идентификатором:
extensions: {
largeBlob: {
read: true;
}
}
Свойство write принимает в качестве значения ArrayBuffer, TypedArray или DataView, представляющие блок данных, который доверенная сторона хочет сохранить вместе с существующим идентификатором:
extensions: {
largeBlob: {
write: arrayBuffer;
}
}
Примечание: Для успешного выполнения операции записи аутентификации publicKey.allowCredentials должно содержать только один элемент, представляющий идентификатор, с которым нужно сохранить блок данных.
Выходные данные
Успешный вызов create() предоставляет следующие выходные данные расширения, если зарегистрированный идентификатор способен хранить блоки данных:
largeBlob: {
supported: true; // false if it cannot store blobs
}
Вызов get() чтения делает доступным блок данных в виде ArrayBuffer в выходных данных расширения при успешном выполнении:
largeBlob: {
blob: arrayBuffer;
}
Примечание: В случае неудачи объект largeBlob будет возвращен, но blob не будет присутствовать.
Вызов get() записи указывает, была ли операция записи успешной, с помощью булевого значения written в выходных данных расширения. Значение true означает, что запись была успешно выполнена на связанном аутентификаторе, а false — что запись не удалась.
largeBlob: {
written: true;
}
minPinLength
- Используется в: Регистрация (
create()) - Обрабатывается: Аутентификатор
- Спецификация: Расширение минимальной длины PIN (minPinLength)
Позволяет доверенной стороне запросить минимальную длину PIN на аутентификаторе.
Входные данные
Свойство publicKey объекта extensions должно содержать свойство minPinLength со значением true:
extensions: {
minPinLength: true;
}
Выходные данные
Если доверенная сторона имеет право получить значение minPinLength (если ее rpId присутствует в списке авторизованных доверенных сторон аутентификатора), данные аутентификатора будут содержать его представление в следующем формате:
{"minPinLength": uint}
Если доверенная сторона не авторизована, расширение игнорируется, и значение "minPinLength" не предоставляется.
payment
- Применимо к: Регистрация (
create()) - Обрабатывается: Пользовательский агент
- Спецификация: Безопасное подтверждение платежа
Позволяет стороне, полагающейся на неё, запросить создание учетных данных WebAuthn, которые могут быть использованы — как стороной, полагающейся на них, так и другими сторонами — с безопасным подтверждением платежа; см. Использование безопасного подтверждения платежа.
Входные данные
Входные данные для расширения payment определены в словаре AuthenticationExtensionsPaymentInputs.
isPayment-
Булево значение, указывающее, что расширение активно.
rpID-
Идентификатор стороны, полагающейся на неё для используемых учетных данных. Используется только при аутентификации; не используется при регистрации.
topOrigin-
Происхождение верхнего уровня фрейма. Используется только при аутентификации; не используется при регистрации.
payeeName-
Имя получателя, если оно присутствует, которое было отображено пользователю. Используется только при аутентификации; не используется при регистрации.
payeeOrigin-
Происхождение получателя, если оно присутствует, которое было отображено пользователю. Используется только при аутентификации; не используется при регистрации.
total-
Сумма транзакции, которая была отображена пользователю. Используется только при аутентификации; не используется при регистрации. Сумма имеет тип PaymentCurrencyAmount.
instrument-
Детали инструмента, которые были отображены пользователю. Используется только при аутентификации; не используется при регистрации. Инструмент имеет тип PaymentCredentialInstrument.
Выходные данные
Нет
Спецификации
Существует ряд мест, где указаны расширения WebAuthn. Реестр всех расширений предоставляет IANA's WebAuthn Extension Identifiers, но имейте в виду, что некоторые из них могут быть устаревшими.
Места, где указаны расширения:
Совместимость с браузерами
| Рабочий стол | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
WebAuthn_extensions |
67 | 18 | 60 | 54 | 13 | 70 | 60 | 49 | 13 | 10.0 | Нет |
appid |
67 | 18 | 60 | 54 | 13 | 70 | 60 | 49 | 13 | 10.0 | Нет |
largeBlob |
113 | 113 | Нет | 99 | Нет | 113 | Нет | 76 | Нет | 23.0 | Нет |
| Рабочий стол | Мобильные устройства | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox для Android | Opera Android | Safari на iOS | Samsung Internet | WebView Android | |
WebAuthn_extensions |
67 | 18 | 60 | 54 | 13 | 70 | 60 | 49 | 13 | 10.0 | Нет |
appidExclude |
67 | 18 | 60 | 54 | 13 | 70 | 60 | 49 | 13 | 10.0 | Нет |
credProps |
89 | 89 | 119 | 75 | Нет | 108 | 119 | 73 | Нет | 21.0 | Нет |
credProtect |
76 | 79 | Нет | 63 | Нет | 76 | Нет | 54 | Нет | 12.0 | Нет |
largeBlob |
113 | 113 | Нет | 99 | 17 | 113 | Нет | 76 | 17 | 23.0 | Нет |
minPinLength |
98 | 98 | 120 | 84 | Нет | 98 | 120 | 68 | Нет | 18.0 | Нет |
payment |
95 | 95 | Нет | 81 | Нет | 95 | Нет | 67 | Нет | 17.0 | Нет |
api.CredentialsContainer.create.publicKey_option.extensions
Таблицы BCD загружаются только в браузере
api.CredentialsContainer.get.publicKey_option.extensions
Таблицы BCD загружаются только в браузере
© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API/WebAuthn_extensions