Permitir a reutilização da chave de acesso nos seus sites com solicitações de origem relacionadas

Maud Nalpas
Maud Nalpas

As chaves de acesso são vinculadas a um site específico e só podem ser usadas para fazer login no site em que foram criadas.

Isso é especificado no ID da parte confiável (RP ID), que, para chaves de acesso criadas para o domínio example.com, pode ser www.example.com ou example.com.

Embora os IDs de RP impeçam que as chaves de acesso sejam usadas como uma única credencial para autenticação em todos os lugares, eles criam problemas para:

  • Sites com vários domínios: os usuários não podem usar a mesma chave de acesso para fazer login em diferentes domínios específicos de países (por exemplo, example.com e example.co.uk) gerenciados pela mesma empresa.
  • Domínios de marca: os usuários não podem usar a mesma credencial em diferentes domínios usados por uma única marca (por exemplo, acme.com e acmerewards.com).
  • Apps para dispositivos móveis: geralmente, os apps para dispositivos móveis não têm um domínio próprio, o que dificulta o gerenciamento de credenciais.

Há soluções alternativas baseadas na federação de identidade e outras baseadas em iframes, mas elas são inconvenientes em alguns casos. As solicitações de origem relacionadas oferecem uma solução.

Solução

Com as solicitações de origem relacionada, um site pode especificar as origens permitidas para usar o ID de terceiros confiáveis.

Isso permite que os usuários reutilizem a mesma chave de acesso em vários sites que você opera.

Para usar solicitações de origem relacionada, é necessário veicular um arquivo JSON especial em um URL específico https://{RP ID}/.well-known/webauthn. Se example.com quiser permitir que as origens adicionais o usem como um ID de RP, ele precisará veicular o seguinte arquivo em https://example.com/.well-known/webauthn::

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example-rewards.com"
  ]
}

Na próxima vez que um desses sites fizer uma chamada para criação (navigator.credentials.create) ou autenticação (navigator.credentials.get) que use example.com como um ID de RP, o navegador vai notar um ID de RP que não corresponde à origem da solicitação. Se o navegador oferecer suporte a solicitações de origem relacionada, ele primeiro procurará um arquivo webauthn em https://{RP ID}/.well-known/webauthn. Se o arquivo existir, o navegador vai verificar se a origem que está fazendo a solicitação está na allowlist. Em caso afirmativo, o processo continua com as etapas de criação ou autenticação da chave de acesso.

Se o navegador não for compatível com solicitações de origem relacionada, ele vai gerar um SecurityError.

Suporte ao navegador

Browser Support

  • Chrome: 133.
  • Edge: 133.
  • Firefox: 135.
  • Safari: 17.4.

Source

A demonstração a seguir usa dois sites, https://ror-1.glitch.me e https://ror-2.glitch.me. Para permitir que os usuários façam login com a mesma chave de acesso nos dois sites, ele usa solicitações de origem relacionada para permitir que ror-2.glitch.me use ror-1.glitch.me como ID do RP.

Demonstração

https://ror-2.glitch.me implementa solicitações de origem relacionadas para usar ror-1.glitch.me como um ID de RP. Assim, ror-1 e ror-2 usam ror-1.glitch.me como um ID de RP ao criar ou autenticar com uma chave de acesso. Também implementamos um banco de dados de chaves de acesso compartilhadas nesses sites.

Observe a seguinte experiência do usuário:

  • É possível criar uma chave de acesso e fazer a autenticação com ela no ror-2, mesmo que o ID do RP seja ror-1 (e não ror-2).
  • Depois de criar uma chave de acesso em ror-1 ou ror-2, você poderá fazer a autenticação com ela em ambos os dispositivos.ror-1ror-2 Como ror-2 especifica ror-1 como um ID de RP, fazer uma solicitação de criação ou autenticação de chave de acesso em qualquer um desses sites é o mesmo que fazer a solicitação em ror-1. O ID do RP é a única coisa que vincula uma solicitação a uma origem.
  • Depois de criar uma chave de acesso no ror-1 ou no ror-2, ela pode ser preenchida automaticamente pelo Chrome nos dois sistemas.ror-1ror-2
  • Uma credencial criada em qualquer um desses sites terá um ID de RP de ror-1.
O Chrome preenche automaticamente os dois sites.
Com as solicitações de origem relacionada, os usuários podem usar a mesma credencial de chave de acesso em ror-1 e ror-2. O Chrome também vai preencher automaticamente as credenciais.

Confira o código:

Etapa 1: implementar um banco de dados de contas compartilhadas

Se quiser que seus usuários façam login com a mesma chave de acesso em site-1 e site-2, implemente um banco de dados de contas compartilhado entre esses dois sites.

Etapa 2: configurar o arquivo JSON .well-known/webauthn no site-1

Primeiro, configure site-1.com para permitir que site-2.com o use como um ID de RP. Para isso, crie o arquivo JSON webauthn:

{
    "origins": [
        "https://site-2.com"
    ]
}

O objeto JSON precisa conter uma chave chamada "origins", cujo valor é uma matriz de uma ou mais strings que contêm origens da Web.

Limitação importante: máximo de cinco marcadores

Cada elemento dessa lista será processado para extrair o rótulo eTLD + 1. Por exemplo, os rótulos eTLD + 1 de example.co.uk e example.de são example. Mas o rótulo eTLD + 1 de example-rewards.com é example-rewards. No Chrome, o número máximo de rótulos é 5.

Etapa 3: veicule o JSON .well-known/webauthn no site 1

Em seguida, disponibilize o arquivo JSON em site-1.com/.well-known/webauthn.

Por exemplo, em express:

app.get("/.well-known/webauthn", (req, res) => {
  const origins = {
    origins: ["https://site-2.com"],
  };
  return res.json(origins);
});

Aqui, estamos usando o res.json do Express, que já define o content-type correto ('application/json');

Etapa 4: especificar o ID do RP no site 2

Na base de código site-2, defina site-1.com como o ID do RP em todos os lugares necessários:

  • Na criação da credencial:
    • Defina site-1.com como o ID do RP na criação de credenciais options, que são transmitidas para a chamada de frontend navigator.credentials.create e normalmente geradas do lado do servidor.
    • Defina site-1.com como o ID da RP esperado ao executar verificações de credenciais antes de salvar no banco de dados.
  • Após a autenticação:
    • Defina site-1.com como o ID do RP na autenticação options transmitida para a chamada de front-end navigator.credentials.get e gerada normalmente no lado do servidor.
    • Defina site-1.com como o ID da RP esperado a ser verificado no servidor, conforme você executa as verificações de credenciais antes de autenticar o usuário.

Solução de problemas

Pop-up de mensagem de erro no Chrome.
Mensagem de erro no Chrome ao criar credenciais. Esse erro é gerado se o arquivo `.well-known/webauthn` não for encontrado em `https://{RP ID}/.well-known/webauthn`.
Pop-up de mensagem de erro no Chrome.
Mensagem de erro no Chrome ao criar credenciais. Esse erro é gerado se o arquivo `.well-known/webauthn` for encontrado, mas não listar a origem de que você está tentando criar uma credencial.

Outras considerações

Compartilhar chaves de acesso em sites e apps para dispositivos móveis

Com as solicitações de origem relacionadas, os usuários podem reutilizar uma chave de acesso em vários sites. Para permitir que os usuários reutilizem uma chave de acesso em um site e um app para dispositivos móveis, use as seguintes técnicas:

Compartilhar senhas entre sites

Com as solicitações de origem relacionadas, os usuários podem reutilizar uma chave de acesso em vários sites. As soluções para compartilhar senhas em sites variam entre os gerenciadores de senhas. Para o Gerenciador de senhas do Google, use o Digital Asset Links . O Safari tem um sistema diferente.

Função dos gerenciadores de credenciais e user agents

Isso vai além do seu escopo como desenvolvedor de sites, mas observe que, a longo prazo, o ID da RP não deve ser um conceito visível para o usuário no user agent ou no gerenciador de credenciais que seus usuários estão usando. Em vez disso, os user agents e os gerenciadores de credenciais precisam mostrar aos usuários onde as credenciais foram usadas. Essa mudança vai levar tempo para ser implementada. Uma solução temporária seria mostrar o site atual e o site de registro original.