Měl jsem přehledy od uživatelů s Androidem 8, že moje aplikace (která používá back-end feed) nezobrazuje obsah. Po vyšetřování jsem zjistil následující výjimku v systému Android 8:
08-29 12:03:11.246 11285-11285/ E/: [12:03:11.245, main]: Exception: IOException Java.io.IOException: Cleartext HTTP traffic to * not permitted
at com.Android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.Java:115)
at com.Android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.Java:458)
at com.Android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.Java:127)
at com.deiw.Android.generic.tasks.AbstractHttpAsyncTask.doConnection(AbstractHttpAsyncTask.Java:207)
at com.deiw.Android.generic.tasks.AbstractHttpAsyncTask.extendedDoInBackground(AbstractHttpAsyncTask.Java:102)
at com.deiw.Android.generic.tasks.AbstractAsyncTask.doInBackground(AbstractAsyncTask.Java:88)
at Android.os.AsyncTask$2.call(AsyncTask.Java:333)
at Java.util.concurrent.FutureTask.run(FutureTask.Java:266)
at Android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.Java:245)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1162)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:636)
at Java.lang.Thread.run(Thread.Java:764)
(Odstranil jsem název balíčku, adresu URL a další možné identifikátory)
V systému Android 7 a nižším vše funguje, nemám Android:usesCleartextTraffic
v Manifestu (a nastavení na true
nepomůže, to je výchozí hodnota stejně), ani nepoužívám Network Security Information. Pokud zavolám NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()
, vrátí false
pro Android 8, true
pro starší verzi pomocí stejného souboru apk. Snažil jsem se najít nějaké zmínky o tom na Google info o Android O, ale bez úspěchu.
Podle Konfigurace zabezpečení sítě -
Počínaje systémem Android 9 (úroveň API 28) je ve výchozím nastavení zakázána podpora Cleartext.
Podívejte se také na --- https://koz.io/Android-m-and-the-war-on-cleartext-traffic/
Možnost 1 -
Vytvořit soubor res/xml/network_security_config.xml -
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
</domain-config>
</network-security-config>
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission Android:name="Android.permission.INTERNET" />
<application
...
Android:networkSecurityConfig="@xml/network_security_config"
...>
...
</application>
</manifest>
Možnost 2 -
Android: usesCleartextTraffic Doc
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission Android:name="Android.permission.INTERNET" />
<application
...
Android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
Také jako @ david.s 'odpověď poukázal Android:targetSandboxVersion
může být také problém -
Podle Manifest Docs -
Android:targetSandboxVersion
Cílová karanténa pro tuto aplikaci pro použití. Čím vyšší je číslo verze karantény, tím vyšší je úroveň zabezpečení. Výchozí hodnota je 1; můžete jej také nastavit na 2. Nastavení tohoto atributu na 2 přepne aplikaci do jiné karantény SELinux. Následující omezení platí pro karanténu úrovně 2:
- Výchozí hodnota
usesCleartextTraffic
v Config sítě zabezpečení je false.- Sdílení uid není povoleno.
Takže možnost 3 -
Pokud máte Android:targetSandboxVersion
v <manifest>
, pak jej zmenšete na 1
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest Android:targetSandboxVersion="1">
<uses-permission Android:name="Android.permission.INTERNET" />
...
</manifest>
V aplikaci AndroidManifest jsem zjistil tento parametr:
Android:networkSecurityConfig="@xml/network_security_config"
a @ xml/network_security_config je definováno v network_security_config.xml jako:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!--Set application-wide security config using base-config tag.-->
<base-config cleartextTrafficPermitted="false"/>
</network-security-config>
jen jsem změnil cleartextTrafficPermitted na true
Změňte adresu URL z HTTP
NA HTTPS
;
Funguje to !!!
Při ladění můžete chtít povolit pouze text, ale zachovat výhody zabezpečení odmítnutím jasného textu ve výrobě. To je pro mě užitečné, protože testuji aplikaci proti vývojovému serveru, který nepodporuje protokol https. Zde je návod, jak vynutit https ve výrobě, ale povolit v textovém režimu ladění:
V build.gradle:
// Put this in your buildtypes debug section:
manifestPlaceholders = [usesCleartextTraffic:"true"]
// Put this in your buildtypes release section
manifestPlaceholders = [usesCleartextTraffic:"false"]
V tagu aplikace v AndroidManifest.xml
Android:usesCleartextTraffic="${usesCleartextTraffic}"
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">***Your URL(ex: 127.0.0.1)***</domain>
</domain-config>
</network-security-config>
Ve výše uvedeném návrhu jsem poskytl/a adresu URL http://xyz.abc.com/mno/
Změnil jsem to na xyz.abc.com , pak to začalo fungovat.
Můj problém v Android 9 procházel webovým prohlížečem přes domény pomocí http Řešení z tato odpověď
<application
Android:networkSecurityConfig="@xml/network_security_config"
...>
a:
res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
To by mohlo být pro někoho užitečné.
Nedávno jsme měli stejný problém pro Android 9, ale potřebujeme pouze zobrazit některé adresy URL v rámci WebView, nic zvláštního. Takže přidání Android:usesCleartextTraffic="true"
do Manifestu fungovalo, ale nechtěli jsme pro to ohrozit bezpečnost celé aplikace. Oprava tedy spočívala ve změně odkazů z http
na https
Ok, to je ⇒⇒ NOT ⇐⇐ tisíce opakování přidejte do svého Manifestu . toto, ale dejte vám další Benefit (a možná nějaké informace o pozadí).
Android má druh přepsání funkce pro src-Directory.
Ve výchozím nastavení máte
/app/src/hlavní
Můžete však přidat další adresáře pro přepsání souboru AndroidManifest.xml. Jak to funguje:
Uvnitř tohoto souboru musíte ne dát všechna pravidla dovnitř, ale pouze ty, které chcete přepsat z/app/src/main/AndroidManifest.xml
Zde je příklad, jak to vypadá pro požadované oprávnění CLEARTEXT:
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.yourappname">
<application
Android:usesCleartextTraffic="true"
Android:name=".MainApplication"
Android:label="@string/app_name"
Android:icon="@mipmap/ic_launcher"
Android:allowBackup="false"
Android:theme="@style/AppTheme">
</application>
</manifest>
S těmito znalostmi je nyní snadné, aby 1,2,3 pro vás přetížení oprávnění v závislosti na vašem debug | main | release prostředí.
Velkou výhodou je, že ve své produkci nemáte ladění - Manifest a udržujete přímou a snadno udržovatelnou strukturu
Dobře, přišel jsem na to. Je to díky parametru Manifest Android:targetSandboxVersion="2"
, který jsem přidal, protože máme také verzi Instant App - mělo by se ujistit, že jakmile uživatel upgraduje z Instant App na běžnou aplikaci, neztratí data s přenosem. Jak však vágní popis naznačuje:
Určuje cílovou karanténu, kterou chce tato aplikace používat. Vyšší verze sanboxů budou mít stále vyšší úroveň zabezpečení.
Výchozí hodnota tohoto atributu je 1.
To samozřejmě také přidává novou úroveň bezpečnostní politiky, alespoň na Android 8.
Pro reaktivní nativní projekty
Bylo to již stanoveno na 0,59 RN. Můžete najít na pgrade diff od 0,58,6 do 0,59 Můžete ji použít bez upgradu, který jste provedli podle následujících kroků:
Vytvořit soubory:
Android/app/src/ ladění /res/xml/reag_native_config.xml -
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">10.0.2.2</domain>
<domain includeSubdomains="false">10.0.3.2</domain>
</domain-config>
</network-security-config>
Android/app/src/ ladění /AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools">
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW"/>
<application tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning"
Android:networkSecurityConfig="@xml/react_native_config" />
</manifest>
Zkontrolujte přijatou odpověď, abyste znali příčinu.
Změňte adresu URL z protokolu HTTP na protokol HTTPS;
Chcete-li použít tyto různé odpovědi na Xamarin.Android
, můžete použít atributy třídy a úrovně sestavy vs. ruční úpravy souboru AndroidManifest.xml
Samozřejmostí je povolení k internetu (duh ..):
[Assembly: UsesPermission(Android.Manifest.Permission.Internet)]
Poznámka: Atributy úrovně sestav jsou obvykle přidány do souboru AssemblyInfo.cs
, ale do souboru, pod using
a nad namespace
prací.
Pak na vaší podtřídě Application (vytvořte ji v případě potřeby) můžete přidat NetworkSecurityConfig
s odkazem na soubor Resources/xml/ZZZZ.xml
:
#if DEBUG
[Application(AllowBackup = false, Debuggable = true, NetworkSecurityConfig = "@xml/network_security_config")]
#else
[Application(AllowBackup = true, Debuggable = false, NetworkSecurityConfig = "@xml/network_security_config"))]
#endif
public class App : Application
{
public App(IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer) { }
public App() { }
public override void OnCreate()
{
base.OnCreate();
}
}
Vytvořte soubor ve složce Resources/xml
(v případě potřeby vytvořte složku xml
).
Příklad souboru xml/network_security_config
, podle potřeby upravte (viz další odpovědi)
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">www.example.com</domain>
<domain includeSubdomains="true">notsecure.com</domain>
<domain includeSubdomains="false">xxx.xxx.xxx</domain>
</domain-config>
</network-security-config>
Parametr UsesCleartextTraffic
můžete také použít v ApplicationAttribute
:
#if DEBUG
[Application(AllowBackup = false, Debuggable = true, UsesCleartextTraffic = true)]
#else
[Application(AllowBackup = true, Debuggable = false, UsesCleartextTraffic = true))]
#endif
Při vývoji mé aplikace jsem také dostal chybu "Cleartext HTTP není povolen". Používám Retrofit2 pro síťová volání v mé aplikaci a mám dvě projektová prostředí (dev & production). Doména My Production má certifikát SSL s hovory HTTPS a dev nebude mít https. Konfigurace je přidána v sestavení chutí. Ale když se změním na dev, tento problém se spustí. Tak jsem k tomu přidal níže uvedené řešení.
Do manifestu jsem přidal provoz typu cleartext
Android:usesCleartextTraffic="true"
Pak jsem přidal spec připojení v retrofit třídy konfigurace OKHttp vytvoření času.
.connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
Úplné vytvoření OkHttpClient je uvedeno níže
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.cache(null)
.connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
.addInterceptor(new NetworkInterceptor(context))
.addInterceptor(createLoggingInterceptor())
.addInterceptor(createSessionExpiryInterceptor())
.addInterceptor(createContextHeaderInterceptor())
.build();
Upgrade na React Native 0.58.5 nebo vyšší verzi. Mají includeSubdomain
ve svých konfiguračních souborech v RN 0.58.5.
V Rn 0.58.5 deklarovali network_security_config
s jejich doménou serveru. Konfigurace zabezpečení sítě umožňuje aplikaci povolit provoz z textové oblasti z určité domény. Takže není třeba klást zvýšené úsilí deklarováním Android:usesCleartextTraffic="true"
v tagu aplikace vašeho manifestu. Bude automaticky vyřešen po upgradu verze RN.