Le richieste HTTP contengono intestazioni come User-Agent o Content-Type. Oltre alle intestazioni allegate dai browser, le app per Android possono aggiungere intestazioni aggiuntive, come Cookie o Referrer, tramite l'extra Intent EXTRA_HEADERS. Per motivi di sicurezza, Chrome filtra alcune intestazioni aggiuntive
a seconda di come e dove viene avviato un intent.
Le richieste multiorigine richiedono un ulteriore livello di sicurezza poiché il client e il server non appartengono alla stessa parte. Questa guida illustra l'avvio di queste richieste tramite le schede personalizzate di Chrome, ovvero intent avviati da app che aprono un URL nella scheda del browser. Fino a Chrome 83, gli sviluppatori potevano aggiungere qualsiasi intestazione all'avvio di una scheda personalizzata. A partire dalla versione 83, Chrome ha iniziato a filtrare tutte le intestazioni multiorigine, ad eccezione di quelle approvelisted, poiché le intestazioni non approvelisted rappresentavano un rischio per la sicurezza. A partire da Chrome 86, è possibile allegare intestazioni non incluse nell'elenco approvato alle richieste multiorigine quando il server e il client sono correlati tramite un link di asset digitali. Questo comportamento è riassunto nella tabella seguente:
| Versione di Chrome | Intestazioni CORS consentite |
|---|---|
| prima di Chrome 83 | approvelisted, non-approvelisted |
| Chrome 83 a Chrome 85 | approvelisted |
| A partire da Chrome 86 | approvelisted, non-approvelisted quando viene configurato un link all'asset digitale |
Tabella 1: Filtro delle intestazioni CORS non incluse nell'elenco approvati.
Questo articolo mostra come configurare una connessione verificata tra il server e il client e come utilizzarla per inviare intestazioni HTTP approvate e non approvate. Puoi passare direttamente alla sezione Aggiunta di intestazioni extra agli intent delle schede personalizzate per il codice.
Sfondo
Intestazioni delle richieste CORS approvelisted e non approvelisted
La condivisione delle risorse tra origini (CORS) consente a un'applicazione web di un'origine di richiedere risorse di un'origine diversa. L'elenco delle intestazioni CORS-approvelisted viene gestito nello standard HTML. Le intestazioni approvelisted di esempio sono riportate nella tabella seguente:
| Header | Descrizione |
|---|---|
| accept-language | pubblicizza le lingue naturali che il client comprende |
| content-language | descrive il linguaggio destinato al pubblico attuale |
| content-type | indica il tipo di media della risorsa |
Tabella 2: Esempio di intestazioni CORS approvate.
Le intestazioni incluse nell'elenco approvato sono considerate sicure perché non contengono informazioni utente sensibili ed è improbabile che il server esegua operazioni potenzialmente dannose.
Nella tabella seguente sono riportati esempi di intestazioni non incluse nell'elenco approvati:
| Header | Descrizione |
|---|---|
| bearer-token | autentica il client su un server |
| origine | indica l'origine della richiesta |
| biscotto | contiene cookie impostati dal server |
Tabella 3: Esempio di intestazioni CORS non incluse nell'elenco approvato.
L'allegato di intestazioni non approvate alle richieste CORS è sconsigliato dallo standard HTML e i server presuppongono che le richieste multiorigine contengano solo intestazioni approvate. L'invio di intestazioni non incluse nell'elenco di approvazione da domini cross-origin consentirebbe ad app di terze parti malintenzionate di creare intestazioni che utilizzano in modo improprio i cookie dell'utente che Chrome (o un altro browser) memorizza e allega alle richieste. I cookie potrebbero autenticare transazioni server dannose che altrimenti non sarebbero possibili.
Allegare intestazioni approvate da CORS alle richieste di schede personalizzate
Le schede personalizzate sono un modo speciale per avviare pagine web in una scheda del browser personalizzata. Gli intent delle schede personalizzate
possono essere creati utilizzando CustomTabsIntent.Builder(). Puoi anche allegare intestazioni a questi
intent utilizzando Bundle con il flag 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"));
Possiamo sempre allegare le intestazioni approvate alle richieste CORS delle schede personalizzate. Tuttavia, Chrome filtra le intestazioni non incluse nell'elenco approvati per impostazione predefinita. Sebbene altri browser possano avere un comportamento diverso, gli sviluppatori devono aspettarsi che le intestazioni non approvate vengano bloccate in generale.
Il modo supportato per includere intestazioni non approvate nelle schede personalizzate è verificare prima la connessione multiorigine utilizzando un link di accesso digitale. La sezione successiva mostra come configurare questi elementi e avviare un intent Schede personalizzate con le intestazioni richieste.
Aggiungere intestazioni aggiuntive agli intent delle schede personalizzate
Configurare i link agli asset digitali
Per consentire il passaggio di intestazioni non incluse nell'elenco approvato tramite gli intent della scheda personalizzata, è necessario configurare un collegamento di asset digitali tra l'applicazione web e quella Android che verifichi che l'autore sia proprietario di entrambe le applicazioni.
Segui la guida ufficiale per configurare un collegamento alle risorse digitali. Per la relazione tra link, utilizza "delegate_permission/common.use_as_origin", che indica che entrambe le app appartengono alla stessa origine una volta verificato il link.
Crea un intent scheda personalizzata con intestazioni aggiuntive
Esistono diversi modi per creare un intent Schede personalizzate. Puoi utilizzare il builder disponibile in AndroidX aggiungendo la libreria alle dipendenze di build:
implementation 'androidx.browser:browser:1.2.0'
Crea l'intent e aggiungi intestazioni aggiuntive:
CustomTabsIntent constructExtraHeadersIntent(CustomTabsSession session) {
CustomTabsIntent intent = new CustomTabsIntent.Builder(session).build();
// Example non-cors-approvelisted headers.
Bundle headers = new Bundle();
headers.putString("bearer-token", "Some token");
headers.putString("redirect-url", "Some redirect url");
intent.intent.putExtra(Browser.EXTRA_HEADERS, headers);
return intent;
}
Configurare una connessione schede personalizzate per convalidare Asset Link
Una connessione Schede personalizzate viene utilizzata per configurare un CustomTabsSession tra l'app e la
scheda Chrome. Abbiamo bisogno della sessione per verificare che l'app e l'app web appartengano alla stessa origine.
La verifica viene superata solo se i link alle risorse digitali sono stati configurati correttamente.
Ti invitiamo a chiamare il numero CustomTabsClient.warmup(). Consente all'applicazione browser di
pre-inizializzarsi in background e velocizzare la procedura di apertura dell'URL.
// Set up a connection that warms up and validates a session.
CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
@Override
public void onCustomTabsServiceConnected(@NonNull ComponentName name,
@NonNull CustomTabsClient client) {
// Create session after service connected.
mSession = client.newSession(callback);
client.warmup(0);
// Validate the session as the same origin to allow cross origin headers.
mSession.validateRelationship(CustomTabsService.RELATION_USE_AS_ORIGIN,
Uri.parse(url), null);
}
@Override
public void onServiceDisconnected(ComponentName componentName) { }
};
Configurare un callback che avvii l'intent dopo la convalida
Il CustomTabsCallback è stato passato alla sessione. Abbiamo configurato il relativo
onRelationshipValidationResult() per avviare CustomTabsIntent creato in precedenza
una volta verificata l'origine.
// Set up a callback that launches the intent after session validated.
CustomTabsCallback callback = new CustomTabsCallback() {
@Override
public void onRelationshipValidationResult(int relation, @NonNull Uri requestedOrigin,
boolean result, @Nullable Bundle extras) {
// Launch custom tabs intent after session was validated as the same origin.
CustomTabsIntent intent = constructExtraHeadersIntent(mSession);
intent.launchUrl(MainActivity.this, Uri.parse(url));
}
};
Collega la connessione del servizio delle schede personalizzate
L'associazione del servizio avvia il servizio e alla fine verrà chiamato il onCustomTabsServiceConnected()
della connessione. Non dimenticare di dissociare il servizio in modo appropriato. Il binding e l'unbinding
vengono eseguiti comunemente nei metodi del ciclo di vita delle attività 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);
Codice dell'applicazione demo
Puoi trovare maggiori dettagli sul servizio Schede personalizzate qui. Per un'app di esempio funzionante, consulta il repository GitHub android-browser-helper.
Riepilogo
Questa guida mostra come aggiungere intestazioni arbitrarie alle richieste CORS delle schede personalizzate. Le intestazioni approvate possono essere allegate a ogni richiesta CORS delle schede personalizzate. Le intestazioni non incluse nell'elenco approvato sono generalmente considerate non sicure nelle richieste CORS e Chrome le filtra per impostazione predefinita. L'allegato è consentito solo per client e server della stessa origine, verificati da un collegamento asset digitale.