Atualizações do FedCM: API Login Status, API Error e API Flag selecionada automaticamente

O Chrome 120 está enviando a API Status do login para a FedCM. A API Login Status (anteriormente conhecida como API Status de login do IdP) permite que sites, principalmente provedores de identidade, sinalizem ao navegador quando os usuários estão fazendo login e saindo. Esse sinal é usado pelo FedCM para resolver um problema de ataque de sincronização silenciosa. Dessa forma, o FedCM pode operar sem cookies de terceiros. Essa atualização aborda as últimas mudanças de incompatibilidade com versões anteriores que identificamos na Intent to Ship original do FedCM, como parte do nosso escopo de trabalho.

Embora a API de status de login melhore a propriedade de privacidade e a usabilidade, ela é incompatível com versões anteriores após o envio. Se você já tiver uma implementação da FedCM, atualize-a usando as instruções a seguir.

Além disso, o Chrome está lançando dois novos recursos de gerenciamento de credenciais federadas (FedCM):

  • API de erro: notifique os usuários quando a tentativa de login falhar com uma interface nativa com base na resposta do servidor do endpoint de declaração de ID, se houver.
  • API Auto-Selected Flag: notifica o provedor de identidade (IdP) e a parte confiável (RP) se uma credencial foi selecionada automaticamente no fluxo.

API Login Status

A API Login Status é um mecanismo em que um site, especialmente um IdP, informa ao navegador o status de login do usuário no IdP. Com essa API, o navegador pode reduzir solicitações desnecessárias ao IdP e reduzir possíveis ataques de sincronização.

Informar o navegador sobre o status de login do usuário

Os IdPs podem sinalizar o status de login do usuário para o navegador enviando um cabeçalho HTTP ou chamando uma API JavaScript quando o usuário faz login no IdP ou quando ele faz logout de todas as contas do IdP. Para cada IdP (identificado pelo URL de configuração), o navegador mantém uma variável de três estados que representa o estado de login com os valores possíveis logged-in, logged-out e unknown. O estado padrão é unknown.

Para indicar que o usuário fez login, envie um cabeçalho HTTP Set-Login: logged-in em uma navegação de nível superior ou uma solicitação de subrecurso de mesma origem:

Set-Login: logged-in

Como alternativa, chame a API JavaScript navigator.login.setStatus('logged-in') da origem do provedor de identidade:

navigator.login.setStatus('logged-in');

Essas chamadas registram o status de login do usuário como logged-in. Quando o status de login do usuário está definido como logged-in, o RP que chama o FedCM faz solicitações para o endpoint de lista de contas do provedor de identidade e exibe as contas disponíveis para o usuário na caixa de diálogo do FedCM.

Para indicar que o usuário saiu de todas as contas, envie o cabeçalho HTTP Set-Login: logged-out em uma navegação de nível superior ou uma solicitação de subrecurso de mesma origem:

Set-Login: logged-out

Também é possível chamar a API JavaScript navigator.login.setStatus('logged-out') da origem do provedor de identidade:

navigator.login.setStatus('logged-out');

Essas chamadas registram o status de login do usuário como logged-out. Quando o status de login do usuário é logged-out, a chamada da FedCM falha silenciosamente sem fazer uma solicitação para o endpoint da lista de contas do IdP.

O status unknown é definido antes que o IdP envie um sinal usando a API Status de login. Introduzimos esse status para uma transição melhor, porque um usuário pode já ter feito login no IdP quando enviamos essa API. O IdP pode não ter a chance de sinalizar isso para o navegador até que a FedCM seja invocada pela primeira vez. Nesse caso, fazemos uma solicitação para o endpoint da lista de contas do IdP e atualizamos o status com base na resposta do endpoint da lista de contas:

  • Se o endpoint retornar uma lista de contas ativas, atualize o status para logged-in e abra a caixa de diálogo FedCM para mostrar essas contas.
  • Se o endpoint não retornar nenhuma conta, atualize o status para logged-out e falha na chamada FedCM.

E se a sessão do usuário expirar? Permita que o usuário faça login usando um fluxo dinâmico.

Mesmo que o IdP continue informando o status de login do usuário ao navegador, o status pode estar desincronizado, por exemplo, quando a sessão expira. O navegador tenta enviar uma solicitação de credenciais para o endpoint da lista de contas quando o status de login é logged-in, mas o servidor não retorna nenhuma conta porque a sessão não está mais disponível. Nesse cenário, o navegador pode permitir que o usuário faça login no IdP dinamicamente por uma caixa de diálogo.

A caixa de diálogo FedCM mostra uma mensagem sugerindo um login, conforme mostrado na imagem a seguir.

Uma caixa de diálogo do FedCM sugerindo fazer login no IdP.
Uma caixa de diálogo do FedCM sugerindo o login no IdP.

Quando o usuário clica no botão Continuar, o navegador abre uma caixa de diálogo para a página de login do IdP.

Exemplo de caixa de diálogo.
Exemplo de caixa de diálogo mostrada após clicar no botão de login no IdP.

O URL da página de login é especificado com login_url como parte do arquivo de configuração do IdP.

{
  "accounts_endpoint": "/auth/accounts",
  "client_metadata_endpoint": "/auth/metadata",
  "id_assertion_endpoint": "/auth/idtokens",
  "login_url": "/login"
  }
}

A caixa de diálogo é uma janela de navegador normal com cookies primários. O que acontecer na caixa de diálogo fica a critério do IdP, e nenhum identificador de janela está disponível para fazer uma solicitação de comunicação entre origens para a página de RP. Depois que o usuário fizer login, o IdP precisará:

  • Envie o cabeçalho Set-Login: logged-in ou chame a API navigator.login.setStatus("logged-in") para informar ao navegador que o usuário fez login.
  • Chame IdentityProvider.close() para fechar a caixa de diálogo.
Um usuário faz login em um RP depois de fazer login no IdP usando o FedCM.
Um usuário faz login em um RP depois de fazer login no IdP usando o FedCM.

Teste o comportamento da API Status de login na nossa demonstração.

  1. Toque no botão Acessar o IdP e fazer login.
  2. Faça login com uma conta arbitrária.
  3. Selecione Sessão expirada no menu suspenso Status da conta.
  4. Pressione o botão Atualizar informações pessoais.
  5. Toque no botão Visitar o RP para testar a FedCM.

Você poderá observar o login no IdP pelo comportamento do módulo.

API Error

Quando o Chrome envia uma solicitação para o endpoint de declaração de ID (por exemplo, quando um usuário clica no botão Continuar como na interface do FedCM ou quando a reautorização automática é acionada), o IdP pode não conseguir emitir um token por motivos legítimos. Por exemplo, se o cliente não tiver autorização, o servidor estiver temporariamente indisponível e assim por diante. Atualmente, o Chrome falha na solicitação silenciosamente em caso de esses erros e só notifica o RP rejeitando a promessa.

Com a API Error, o Chrome notifica o usuário mostrando uma interface nativa com as informações de erro fornecidas pelo IdP.

Caixa de diálogo do FedCM mostrando a mensagem de erro após a tentativa de login do usuário falhar. A string está associada ao tipo de erro.
Uma caixa de diálogo do FedCM mostrando a mensagem de erro após a tentativa de login do usuário falhar. A string está associada ao tipo de erro.

API HTTP do provedor de identidade

Na resposta id_assertion_endpoint, o IdP pode retornar um token para o navegador se ele puder ser emitido mediante solicitação. Nesta proposta, caso um token não possa ser emitido, o IdP pode retornar uma resposta de "erro", que tem dois novos campos opcionais:

  1. code
  2. url
// id_assertion_endpoint response
{
  "error": {
     "code": "access_denied",
     "url": "https://idp.example/error?type=access_denied"
  }
}

Para o código, o IdP pode escolher um dos erros conhecidos da lista de erros especificados do OAuth 2.0 [invalid_request, unauthorized_client, access_denied, server_error e temporarily_unavailable] ou usar qualquer string arbitrária. Se for o último caso, o Chrome renderizará a interface do erro com uma mensagem de erro genérica e transmitirá o código para o RP.

Para url, ele identifica uma página da Web legível por humanos com informações sobre o erro para fornecer mais informações aos usuários. Esse campo é útil para os usuários porque os navegadores não podem fornecer mensagens de erro avançadas em uma interface nativa. Por exemplo, links para próximas etapas, dados de contato do atendimento ao cliente e assim por diante. Se um usuário quiser saber mais sobre os detalhes do erro e como corrigi-lo, ele poderá acessar a página fornecida na interface do navegador para mais detalhes. O URL precisa ser do mesmo site do configURL do IdP.

try {
  const cred = await navigator.credentials.get({
    identity: {
      providers: [
        {
          configURL: 'https://idp.example/manifest.json',
          clientId: '1234',
        },
      ],
    }
  });
} catch (e) {
  const code = e.code;
  const url = e.url;
}

API Auto-Selected Flag

mediation: optional é o comportamento padrão de mediação do usuário na API Credential Management e aciona a re-autenticação automática quando possível. No entanto, a reautorização automática pode estar indisponível por motivos que só o navegador conhece. Quando ela está indisponível, o usuário pode ser solicitado a fazer login com a mediação explícita do usuário, que é um fluxo com propriedades diferentes.

  • Do ponto de vista de um autor da chamada de API, quando ele recebe um token de ID, ele não tem visibilidade sobre se foi o resultado de um fluxo de reautorização automática. Isso dificulta a avaliação do desempenho da API e a melhoria da UX.
  • Do ponto de vista do IdP, ele não consegue dizer se uma reautorização automática ocorreu ou não para a avaliação de performance. Além disso, saber se uma mediação explícita do usuário estava envolvida poderia ajudar a oferecer suporte a mais recursos relacionados à segurança. Por exemplo, alguns usuários podem preferir um nível de segurança mais alto, que exige a mediação explícita do usuário na autenticação. Se um IDP receber uma solicitação de token sem essa mediação, ele poderá processar a solicitação de maneira diferente. Por exemplo, retorne um código de erro para que o RP possa chamar a API FedCM novamente com mediation: required.

Portanto, fornecer visibilidade ao fluxo de reautorização automática seria benéfico para os desenvolvedores.

Com a API Flag selecionada automaticamente, o Chrome compartilha se uma permissão explícita do usuário foi obtida tocando no botão Continue as com o IdP e o RP, sempre que a reautorização automática ocorreu ou uma mediação explícita ocorreu. O compartilhamento só acontece depois que a permissão do usuário é concedida para a comunicação do IdP/RP.

Compartilhamento de IdP

Para compartilhar as informações com a permissão do usuário do IdP, o Chrome inclui is_auto_selected=true na solicitação POST enviada ao id_assertion_endpoint:

POST /fedcm_assertion_endpoint HTTP/1.1
Host: idp.example
Origin: https://rp.example/
Content-Type: application/x-www-form-urlencoded
Cookie: 0x23223
Sec-Fetch-Dest: webidentity

account_id=123&client_id=client1234&nonce=Ct0D&disclosure_text_shown=true&is_auto_selected=true

Compartilhamento de RP

O navegador pode compartilhar as informações com o RP em isAutoSelected por meio de IdentityCredential:

const cred = await navigator.credentials.get({
  identity: {
    providers: [{
      configURL: 'https://idp.example/manifest.json',
      clientId: '1234'
    }]
  }
});

if (cred.isAutoSelected !== undefined) {
  const isAutoSelected = cred.isAutoSelected;
}

Engajamento e compartilhamento de feedback

Se você tiver feedback ou encontrar algum problema durante o teste, compartilhe-o em crbug.com.

Foto de Girl with red hat no Unsplash (links em inglês)