Ajouter des en-têtes de requête HTTP supplémentaires

Les requêtes HTTP contiennent des en-têtes tels que User-Agent ou Content-Type. Outre les en-têtes joints par les navigateurs, les applications Android peuvent ajouter des en-têtes supplémentaires, tels que "Cookie" ou "Referrer", via l'extra d'intent EXTRA_HEADERS. Pour des raisons de sécurité, Chrome filtre certains des en-têtes supplémentaires en fonction de la manière et de l'emplacement de lancement d'un intent.

Les requêtes d'origine croisée nécessitent une couche de sécurité supplémentaire, car le client et le serveur n'appartiennent pas à la même partie. Ce guide explique comment lancer ces requêtes via des onglets personnalisés Chrome, c'est-à-dire des intents lancés à partir d'applications qui ouvrent une URL dans l'onglet du navigateur. Jusqu'à Chrome 83, les développeurs pouvaient ajouter n'importe quel en-tête lors du lancement d'un onglet personnalisé. À partir de la version 83, Chrome a commencé à filtrer tous les en-têtes multi-origines, à l'exception de ceux figurant sur la liste d'autorisation, car les en-têtes non approuvés représentaient un risque de sécurité. À partir de Chrome 86, il est possible d'associer des en-têtes non approuvés aux requêtes inter-origines lorsque le serveur et le client sont associés à l'aide d'un lien d'élément numérique. Ce comportement est résumé dans le tableau suivant:

Version de Chrome En-têtes CORS autorisés
avant Chrome 83 approuvées, non approuvées
De Chrome 83 à Chrome 85 approuvée
à partir de Chrome 86 approuvés, non approuvés lorsqu'un lien vers des composants numériques est configuré

Tableau 1 : Filtrage des en-têtes CORS non approuvés.

Cet article explique comment configurer une connexion validée entre le serveur et le client, et l'utiliser pour envoyer des en-têtes HTTP approuvés et non approuvés. Vous pouvez passer à la section Ajouter des en-têtes supplémentaires aux intents d'onglet personnalisés pour obtenir ce code.

Contexte

En-têtes de requêtes CORS approuvés par rapport aux en-têtes de requêtes CORS non approuvés

Le partage de ressources inter-origines (CORS) permet à une application Web d'une origine de demander des ressources d'une autre origine. La liste des en-têtes approuvés par CORS est gérée dans la norme HTML. Des exemples d'en-têtes de liste d'approbation sont présentés dans le tableau suivant:

Header Description
accepter-langue annonce les langues naturelles que le client comprend
langue du contenu décrit le langage destiné à l'audience actuelle ;
type-contenu Indique le type de contenu multimédia de la ressource

Tableau 2 : Exemples d'en-têtes CORS approuvés.

Les en-têtes de la liste d'approbation sont considérés comme sécurisés, car ils ne contiennent pas d'informations utilisateur sensibles et ne sont pas susceptibles de provoquer des opérations potentiellement dommageables sur le serveur.

Des exemples d'en-têtes non approuvés sont présentés dans le tableau suivant:

Header Description
jeton-de-support authentifie le client auprès d'un serveur ;
origine Indique l'origine de la requête
biscuit contient des cookies définis par le serveur

Tableau 3 : Exemples d'en-têtes CORS non approuvés.

L'ajout d'en-têtes non approuvés aux requêtes CORS est déconseillé par la norme HTML, et les serveurs supposent que les requêtes à origines multiples ne contiennent que des en-têtes approuvés. L'envoi d'en-têtes non approuvés à partir de domaines multi-origines permettrait aux applications tierces malveillantes de créer des en-têtes qui utilisent de manière abusive les cookies utilisateur que Chrome (ou un autre navigateur) stocke et associe aux requêtes. Les cookies peuvent authentifier des transactions de serveur malveillantes qui ne seraient autrement pas possibles.

Joindre des en-têtes de la liste d'approbation CORS aux requêtes d'onglets personnalisés

Les onglets personnalisés permettent d'ouvrir des pages Web dans un onglet personnalisé du navigateur. Vous pouvez créer des intents d'onglet personnalisés à l'aide de CustomTabsIntent.Builder(). Vous pouvez également associer des en-têtes à ces intents à l'aide d'un Bundle avec l'option 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"));

Nous pouvons toujours associer des en-têtes de la liste d'autorisation aux requêtes CORS des onglets personnalisés. Toutefois, Chrome filtre les en-têtes non approuvés par défaut. Bien que le comportement des autres navigateurs puisse être différent, les développeurs doivent s'attendre à ce que les en-têtes non approuvés soient bloqués en général.

Pour inclure des en-têtes non approuvés dans des onglets personnalisés, vous devez d'abord vérifier la connexion inter-origine à l'aide d'un lien d'accès numérique. La section suivante explique comment les configurer et lancer un intent Custom Tabs avec les en-têtes requis.

Ajouter des en-têtes supplémentaires aux intents d'onglet personnalisés

Pour autoriser les en-têtes non approuvés à être transmis via les intents d'onglet personnalisé, vous devez configurer un lien d'élément numérique entre l'application Android et l'application Web qui vérifie que l'auteur est propriétaire des deux applications.

Suivez le guide officiel pour configurer un lien vers des composants numériques. Pour la relation de liaison, utilisez "delegate_permission/common.use_as_origin", ce qui indique que les deux applications appartiennent à la même origine une fois la liaison validée.

Créer un intent d'onglet personnalisé avec des en-têtes supplémentaires

Il existe plusieurs façons de créer un intent d'onglets personnalisés. Vous pouvez utiliser le compilateur disponible dans AndroidX en ajoutant la bibliothèque aux dépendances de compilation:

MULTI_LINE_CODE_PLACEHOLDER_1

Créez l'intent et ajoutez des en-têtes supplémentaires:

MULTI_LINE_CODE_PLACEHOLDER_2

Une connexion aux onglets personnalisés permet de configurer un CustomTabsSession entre l'application et l'onglet Chrome. Nous avons besoin de la session pour vérifier que l'application et l'application Web appartiennent à la même origine. La validation n'est validée que si les liens vers des ressources numériques ont été correctement configurés.

Nous vous recommandons d'appeler CustomTabsClient.warmup(). Il permet à l'application du navigateur de pré-initialiser en arrière-plan et d'accélérer le processus d'ouverture de l'URL.

MULTI_LINE_CODE_PLACEHOLDER_3

Configurer un rappel qui lance l'intent après validation

Le CustomTabsCallback a été transmis à la session. Nous avons configuré son onRelationshipValidationResult() pour lancer le CustomTabsIntent créé précédemment une fois la validation de l'origine réussie.

MULTI_LINE_CODE_PLACEHOLDER_4

Lier la connexion du service des onglets personnalisés

Lier le service le lance, et le onCustomTabsServiceConnected() de la connexion sera appelé à terme. N'oubliez pas de dissocier le service de manière appropriée. La liaison et la désassociation sont généralement effectuées dans les méthodes de cycle de vie des activités onStart() et 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);

Code de l'application de démonstration

Pour en savoir plus sur le service Custom Tabs, cliquez ici. Consultez le dépôt GitHub android-browser-helper pour obtenir un exemple d'application fonctionnel.

Résumé

Ce guide explique comment ajouter des en-têtes arbitraires aux requêtes CORS pour les onglets personnalisés. Les en-têtes approuvés peuvent être joints à chaque requête CORS d'onglets personnalisés. Les en-têtes non approuvés sont généralement considérés comme dangereux dans les requêtes CORS, et Chrome les filtre par défaut. Leur association n'est autorisée que pour les clients et les serveurs de la même origine, vérifiés par un lien d'élément numérique.