Adicionar mais cabeçalhos de solicitação HTTP

Solicitações HTTP contêm cabeçalhos como User-Agent ou Content-Type. Além dos cabeçalhos anexados por navegadores, os apps Android podem adicionar cabeçalhos extras, como Cookie ou Referrer, usando o EXTRA_HEADERS Extra de intent. Por motivos de segurança, o Chrome filtra alguns dos cabeçalhos extras dependendo de como e onde uma intent é iniciada.

As solicitações de origem cruzada exigem uma camada adicional de segurança, já que o cliente e o servidor são ou que não sejam da mesma parte. Este guia discute o lançamento dessas solicitações pelo Chrome guias personalizadas, ou seja, intents iniciadas por apps que abrem um URL na guia do navegador. Até o Chrome 83, os desenvolvedores podiam adicionar quaisquer cabeçalhos ao iniciar uma Guia personalizada. A partir da versão 83, o Chrome começou a filtrar todos, exceto cabeçalhos de origem cruzada aprovados, já que os cabeçalhos não aprovados representa um risco para a segurança. A partir do Chrome 86, é possível anexar cabeçalhos não aprovados na lista de permissões a solicitações de origem cruzada, quando o servidor e o cliente estão relacionados usando um Digital Asset Link Esse comportamento é resumido na tabela a seguir:

Versão do Chrome Cabeçalhos CORS permitidos
antes do Chrome 83 lista de aprovação, não aprovada
Chrome 83 ao Chrome 85 lista de aprovação
do Chrome 86 em diante na lista de aprovação ou na lista não aprovada quando um link de recurso digital é configurado

Tabela 1: Filtragem de cabeçalhos CORS não aprovados na lista.

Este artigo mostra como configurar uma conexão verificada entre o servidor e o cliente e usar essa conexão para enviar cabeçalhos HTTP aprovados e não aprovados. Você pode pular para Adicionar mais cabeçalhos às intents de guias personalizadas para o código.

Contexto

Cabeçalhos de solicitação CORS da lista de aprovação e não aprovada

O Compartilhamento de recursos entre origens (CORS) permite que um aplicativo da Web de uma origem solicite recursos com origens diferentes. A lista de cabeçalhos CORS-approve natureza é mantida na seção HTML padrão. Confira exemplos de cabeçalhos aprovados na próxima tabela:

Cabeçalho Descrição
accept-language anuncia linguagens naturais que o cliente entende
idioma do conteúdo descreve a linguagem destinada ao público-alvo atual
content-type indica o tipo de mídia do recurso

Tabela 2: Exemplos de cabeçalhos CORS aprovados.

Os cabeçalhos da lista de aprovação são considerados seguros porque não contêm dados informações do usuário e é improvável que faça com que o servidor execute operações potencialmente prejudiciais.

Exemplos de cabeçalhos não aprovados são mostrados na tabela a seguir:

Cabeçalho Descrição
bearer-token autentica o cliente em um servidor
origem indica a origem da solicitação
biscoito contém cookies definidos pelo servidor

Tabela 3: Exemplos de cabeçalhos CORS não aprovados na lista.

O padrão HTML e os servidores não recomendam anexar cabeçalhos não aprovados na lista de solicitações CORS presumem que as solicitações entre origens contêm apenas cabeçalhos da lista de aprovação. Como enviar cabeçalhos não aprovados de domínios de origem cruzada permitiria que apps maliciosos de terceiros criassem cabeçalhos que usam o cookies que o Chrome (ou outro navegador) armazena e anexa às solicitações. Os biscoitos poderiam autenticar transações maliciosas de servidores que, de outra forma, não seriam possíveis.

Como anexar cabeçalhos da lista de aprovação do CORS a solicitações de guias personalizadas

As guias personalizadas são uma maneira especial de abrir páginas da Web em uma guia personalizada do navegador. Guia Personalizada intents podem ser criadas usando CustomTabsIntent.Builder(). Também é possível anexar cabeçalhos a esses intents usando um Bundle com a sinalização Browser.EXTRA_HEADERS:

CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();

Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");   
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);

intent.launchUrl(Activity.this, Uri.parse("http://www.google.com"));

Sempre podemos anexar cabeçalhos da lista de aprovação a solicitações CORS de guias personalizadas. No entanto, os filtros do Chrome cabeçalhos não aprovados por padrão. Embora outros navegadores possam ter um comportamento diferente, os desenvolvedores devem esperar que os cabeçalhos não aprovados sejam bloqueados em geral.

A maneira compatível de incluir cabeçalhos não aprovados na guia personalizada é verificar primeiro o conexão de origem cruzada usando um link de acesso digital. A próxima seção mostra como definir e iniciar uma intent de guias personalizadas com os cabeçalhos necessários.

Adicionar mais cabeçalhos a intents de guia personalizada

Para permitir que cabeçalhos não aprovados sejam transmitidos por intents da guia personalizada, é necessário definir um link de ativo digital entre o aplicativo Android e o da Web que verifica se o autor tem os dois aplicativos.

Siga o guia oficial para configurar um Digital Asset Link. Para a relação de vinculação, use "delegate_permission/common.use_as_origin", que indica que os dois aplicativos pertencem ao mesmo origem depois que o link for verificado.

Criar intent de guia personalizada com cabeçalhos extras

Há várias maneiras de criar uma intent de guias personalizadas. Você pode usar o builder disponível no androidX adicionando a biblioteca às dependências de build:

MULTI_LINE_CODE_PLACEHOLDER_1

Crie a intent e adicione mais cabeçalhos:

MULTI_LINE_CODE_PLACEHOLDER_2

Uma conexão de guias personalizadas é usada para configurar um CustomTabsSession entre o app e o Guia do Chrome. Precisamos da sessão para verificar se o app e o da Web pertencem à mesma origem. A verificação só será aprovada se os Digital Asset Links tiverem sido configurados corretamente.

É recomendável chamar CustomTabsClient.warmup(). Ele permite que o aplicativo do navegador pré-inicializar em segundo plano e acelerar o processo de abertura do URL.

MULTI_LINE_CODE_PLACEHOLDER_3

Configurar um callback que lance a intent após a validação

O CustomTabsCallback foi transmitido para a sessão. Configuramos seus onRelationshipValidationResult() para iniciar o CustomTabsIntent criado anteriormente. quando a verificação da origem for concluída.

MULTI_LINE_CODE_PLACEHOLDER_4

Vincular a conexão do serviço de guias personalizadas

A vinculação do serviço inicia o serviço e o onCustomTabsServiceConnected() da conexão será chamado. Não se esqueça de desvincular o serviço da maneira adequada. Vinculação e desvinculação geralmente é feito nos métodos do ciclo de vida da atividade onStart() e onStop().

// Bind the custom tabs service connection.
// Call this in onStart()
CustomTabsClient.bindCustomTabsService(this,
    CustomTabsClient.getPackageName(MainActivity.this, null), connection);

// …
// Unbind the custom tabs service.
// Call this in onStop().
unbindService(connection);

Código do aplicativo de demonstração

Clique aqui para mais detalhes sobre o serviço de guias personalizadas. Consulte a android-browser-helper: repositório do GitHub para um app de exemplo funcional.

Resumo

Este guia demonstrou como adicionar cabeçalhos arbitrários a solicitações CORS de guias personalizadas. cabeçalhos da lista de aprovação podem ser anexados a cada solicitação CORS de guias personalizadas. Os cabeçalhos não aprovados são geralmente são consideradas inseguras nas solicitações do CORS e o Chrome as filtra por padrão. Para fazer isso, permitido somente para clientes e servidores da mesma origem, verificados por um Digital Asset Link.