Android P禁止http明文传输

一、前言

从Android P(即Android 9)开始,Android系统会限制了http明文流量的网络请求,若是使用http访问都会抛出java.io.IOException: Cleartext HTTP traffic to ... not permitted异常,使用https就可以正常进行网络请求
官方说明

二、异常现象

1、若是targetSdkVersion >= 28的应用发起http网络请求,会抛出类似以下的异常:

 Caused by: java.io.IOException: Cleartext HTTP traffic to a.gdt.qq.com not permitted
        at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:124)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:462)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:262)
        at com.qq.gdt.action.a.a.e.a(Unknown Source:65)
        at com.qq.gdt.action.a.a.e.a(Unknown Source:65)
        at com.qq.gdt.action.a.a.a.a.a(Unknown Source:10)
        at com.qq.gdt.action.a.a.a.c.a(Unknown Source:43)
        at com.qq.gdt.action.a.a.a.e.a(Unknown Source:8)
        at com.qq.gdt.action.a.a.a.c.a(Unknown Source:43)
        at com.qq.gdt.action.a.a.a.f.a(Unknown Source:4)
        at com.qq.gdt.action.a.a.a.c.a(Unknown Source:43)
        at com.qq.gdt.action.a.a.a.d.a(Unknown Source:34)
        at com.qq.gdt.action.a.a.a.c.a(Unknown Source:43)
        at com.qq.gdt.action.a.a.a.b(Unknown Source:36)
        at com.qq.gdt.action.a.a.a.a(Unknown Source:0)
        at com.qq.gdt.action.a.a.a$1.run(Unknown Source:2) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:919) 

三、异常分析

1、面向 Android 9(API 级别 28)及更高版本应用的网络安全默认配置如下所示:

<base-config cleartextTrafficPermitted="false">
    <trust-anchors>
        <certificates src="system" />
    </trust-anchors>
</base-config>

也就是说,Android 9之后,系统默认是限制明文传输,而且也只信任系统级别的证书,用户自定义的证书默认是不会信任的

2、面向 Android 7.0(API 级别 24)到 Android 8.1(API 级别 27)的应用的网络安全默认配置如下所示:


    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>

也就是说,Android 7.0-Android 8.1系统默认是允许明文传输,但是也是只信任系统级别的证书,用户自定义的证书默认是不会信任的
3、面向 Android 6.0(API 级别 23)及更低版本应用的默认网络安全配置如下所示:

    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
    

也就是说,Android 6.0以及以下版本,系统默认是允许明文传输,同时信任系统级别的证书与用户自定义的证书

四、解决方案

1、方案一:设置安全网络配置
1)在res/xml目录下新建文件:network_security_config.xml,内容设置如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <!-- 设置允许http明文传输-->
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <!-- 设置信任系统级别证书-->
            <certificates src="system" />
            <!-- 设置信任用户自定义证书,设置之后才能用fiddler之类的抓取https请求,出包最好不要设置,防止被抓包-->
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

2)在AndroidManifest.xml的application标签下增加以下属性声明:

android:networkSecurityConfig="@xml/network_security_config"

2、方案二:设置targetSdkVersion <= 28亦可

发布了36 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43278826/article/details/103090904