Представляем подсказки, запросы связанного происхождения и сериализацию JSON для WebAuthn в Chrome.

В Chrome 128 и 129 представлены новые интересные функции WebAuthn — базового API для создания систем аутентификации на основе паролей.

  • Подсказки . Подсказки позволяют проверяющим сторонам (RP) лучше контролировать пользовательский интерфейс WebAuthn в браузере. Они особенно полезны для корпоративных пользователей, которые хотят использовать ключи безопасности.
  • Связанные запросы происхождения . С помощью связанных запросов происхождения RP могут сделать ключи доступа действительными на нескольких доменах. Если у вас есть несколько сайтов, теперь вы можете разрешить пользователям повторно использовать свои ключи доступа на всех ваших сайтах, устраняя трудности при входе в систему.
  • Сериализация JSON . API-интерфейсы сериализации JSON позволяют упростить внешний код RP за счет параметров кодирования и декодирования, а также учетных данных, передаваемых в API WebAuthn и из него.

Подсказки

С помощью hints проверяющие стороны (RP) теперь могут указывать предпочтения пользовательского интерфейса для создания ключа доступа или аутентификации с помощью ключа доступа.

Раньше, когда RP хотел ограничить аутентификатор, который пользователь может использовать для создания ключа доступа или для аутентификации, он мог authenticatorSelection.authenticatorAttachment , чтобы указать "platform" или "cross-platform" . Они соответственно ограничивают аутентификатор аутентификатором платформы или роуминговым аутентификатором . С помощью hints эта спецификация может быть более гибкой.

RP может использовать дополнительные hints в PublicKeyCredentialCreationOptions или PublicKeyCredentialRequestOptions чтобы указать "security-key" , "client-device" и "hybrid" в порядке предпочтения в массиве.

Ниже приведен пример запроса на создание учетных данных, в котором предпочтение отдается "cross-platform" аутентификаторам с подсказкой "security-key" . Это означает, что Chrome должен показывать пользовательский интерфейс, ориентированный на ключи безопасности, для корпоративных пользователей.

const credential = await navigator.credentials.create({
  publicKey
: {
    challenge
: *****,
    hints
: ['security-key'],
    authenticatorSelection
: {
      authenticatorAttachment
: 'cross-platform'
   
}
 
}
});
Указав «ключ безопасности» в качестве подсказки, браузер отображает диалоговое окно, ориентированное на ключ безопасности.
Указав «ключ безопасности» в качестве подсказки, браузер отображает диалоговое окно, ориентированное на ключ безопасности.

Когда RP хочет определить приоритет сценария проверки между устройствами, он может отправить запрос аутентификации, в котором предпочтение отдается "cross-platform" аутентификаторам с "hybrid" в качестве подсказки.

const credential = await navigator.credentials.create({
  publicKey
: {
    challenge
: *****,
    residentKey
: true,
    hints
: ['hybrid']
    authenticatorSelection
: {
      authenticatorAttachment
: 'cross-platform'
   
}
 
}
});
Указав «гибрид» в качестве подсказки, браузер отображает диалоговое окно, ориентированное на вход на несколько устройств.
Указав «гибрид» в качестве подсказки, браузер отображает диалоговое окно, ориентированное на вход на несколько устройств.

С помощью запросов связанного происхождения RP могут сделать ключи доступа доступными для использования из нескольких доменов. Создание централизованного входа в систему и использование протоколов федерации остается рекомендуемым решением для большинства сайтов. Но если у вас несколько доменов и федерация невозможна, решением может стать связанное происхождение.

Во всех запросах WebAuthn должен быть указан идентификатор проверяющей стороны (идентификатор RP), а все ключи доступа связаны с одним идентификатором RP. Традиционно источник мог указать идентификатор RP только на основе своего домена, поэтому в этом случае www.example.co.uk мог указать идентификатор RP example.co.uk , но не example.com . При использовании запросов связанного происхождения заявленный идентификатор RP можно проверить путем получения общеизвестного файла JSON, расположенного по адресу /.well-known/webauthn , из целевого домена. Таким образом, example.co.uk (а также example.in , example.de и т. д.) могут использовать идентификатор RP example.com , если example.com указывает их в следующем формате:

URL-адрес: https://example.com/.well-known/webauthn .

{
 
"origins": [
   
"https://example.co.uk",
   
"https://example.de",
   
"https://example.sg",
   
"https://example.net",
   
"https://exampledelivery.com",
   
"https://exampledelivery.co.uk",
   
"https://exampledelivery.de",
   
"https://exampledelivery.sg",
   
"https://myexamplerewards.com",
   
"https://examplecars.com"
 
]
}

Узнайте, как настроить запросы связанного происхождения, в разделе «Разрешить повторное использование пароля на ваших сайтах с помощью запросов связанного происхождения» .

Сериализация JSON

Объекты запроса и ответа WebAuthn имеют несколько полей, которые содержат необработанные двоичные данные в ArrayBuffer, такие как идентификатор учетных данных, идентификатор пользователя или запрос. Если веб-сайт хочет использовать JSON для обмена этими данными со своим сервером, двоичные данные сначала необходимо закодировать, например, с помощью Base64URL. Это добавляет ненужную сложность для разработчиков, которые хотят начать использовать ключи доступа на своих веб-сайтах.

WebAuthn теперь предлагает API для анализа объектов запроса PublicKeyCredentialCreationOptions и PublicKeyCredentialRequestOptions WebAuthn непосредственно из JSON и сериализации ответа PublicKeyCredential непосредственно в JSON. Все поля со значениями ArrayBuffer, содержащие необработанные двоичные данные, автоматически преобразуются из или в значения, закодированные в Base64URL. Эти API доступны в Chrome 129.

Прежде чем создавать ключ доступа, получите объект PublicKeyCredentialCreationOptions в кодировке JSON с сервера и декодируйте его с помощью PublicKeyCredential.parseCreationOptionsFromJSON() .

Поддержка браузера

  • Хром: 129.
  • Край: 129.
  • Фаерфокс: 119.
  • Сафари: не поддерживается.

Источник

export async function registerCredential() {

 
// Fetch encoded `PublicKeyCredentialCreationOptions`
 
// and JSON decode it.
 
const options = await fetch('/auth/registerRequest').json();

 
// Decode `PublicKeyCredentialCreationOptions` JSON object
 
const decodedOptions = PublicKeyCredential.parseCreationOptionsFromJSON(options);  

 
// Invoke the WebAuthn create() function.
 
const cred = await navigator.credentials.create({
    publicKey
: decodedOptions,
 
});
 
...

После создания ключа доступа закодируйте полученные учетные данные с помощью toJSON() , чтобы их можно было отправить на сервер.

Поддержка браузера

  • Хром: 129.
  • Край: 129.
  • Фаерфокс: 119.
  • Сафари: не поддерживается.

Источник

  ...
 
const cred = await navigator.credentials.create({
    publicKey
: options,
 
});

 
// Encode the credential to JSON and stringify
 
const credential = JSON.stringify(cred.toJSON());

 
// Send the encoded credential to the server
  await fetch
('/auth/registerResponse', credential);
 
...

Перед аутентификацией с помощью ключа доступа получите PublicKeyRequestCreationOptions в кодировке JSON с сервера и декодируйте его с помощью PublicKeyCredential.parseRequestOptionsFromJSON() .

Поддержка браузера

  • Хром: 129.
  • Край: 129.
  • Фаерфокс: 119.
  • Сафари: не поддерживается.

Источник

export async function authenticate() {

 
// Fetch encoded `PublicKeyCredentialRequestOptions`
 
// and JSON decode it.
 
const options = await fetch('/auth/signinRequest').json();

 
// Decode `PublicKeyCredentialRequestOptions` JSON object
 
const decodedOptions = PublicKeyCredential.parseRequestOptionsFromJSON(options);

 
// Invoke the WebAuthn get() function.
 
const cred = await navigator.credentials.get({
    publicKey
: options
 
});
 
...

После аутентификации с помощью ключа доступа закодируйте полученные учетные данные с помощью метода toJSON() , чтобы их можно было отправить на сервер.

Поддержка браузера

  • Хром: 129.
  • Край: 129.
  • Фаерфокс: 119.
  • Сафари: не поддерживается.

Источник

  ...
 
const cred = await navigator.credentials.get({
    publicKey
: options
 
});

 
// Encode the credential to JSON and stringify
 
const credential = JSON.stringify(cred.toJSON());

 
// Send the encoded credential to the server
  await fetch
(`/auth/signinResponse`, credential);
 
...

Узнать больше

Чтобы узнать больше о WebAuthn и ключах доступа, посетите следующие ресурсы: