在运行时将network_security_config.xml的域名设置为localhost
Posted
技术标签:
【中文标题】在运行时将network_security_config.xml的域名设置为localhost【英文标题】:Setting domain name of network_security_config.xml to localhost at runtime 【发布时间】:2020-04-28 05:17:39 【问题描述】:从 android 9 开始,Android 默认只允许通过 HTTPS 进行网络连接。然而,我正在做的唯一请求是通过本地主机(例如http://10.41.199.226:port/FooBar
)完成的,它由
(C#)HttpListener
监听那个地址:端口组合。
由于此请求是通过 HTTP 发出的,Android 默认情况下不允许它。关注this documentation by Android 关于network_security_config
文件,我可以通过添加以下network_security_config.xml
文件来允许HTTP 连接
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
<debug-overrides>
<trust-anchors>
<certificates src="user" />
</trust-anchors>
</debug-overrides>
</network-security-config>
使用 android:networkSecurityConfig="@xml/network_security_config"
从 Android 清单调用。
这允许完成 HTTP 请求,但是因为这设置了基本配置,它允许在整个应用程序中发出 HTTP 请求。这不是一个好主意,因为我将来可能想添加传出请求,我希望通过 HTTPS 并希望为此建立这个安全网。禁止这样做。
在同一个文档中,他们进一步介绍了domain-config
,它允许您根据域设置cleartextTrafficPermitted
,我尝试使用以下域集
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain>
<domain includeSubdomains="true">10.0.0.1</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
没有结果,由于不是https,请求仍然被阻止。
我查找了设备的本地地址,并将其添加到域列表中
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.41.199.226</domain> <!--assume this is my local ip -->
</domain-config>
这行得通,只有在通过 localhost 请求时才允许 HTTP,而任何传出请求都需要 HTTPS。
唯一的问题是我无法知道在应用启动之前运行应用的设备的本地 IP。
所以我的问题是,有没有办法:
-
将域名设置为会自动注册为本地 ip 的名称? (就像我尝试过的
localhost
一样,但是没有用)
添加一个“通配符”IP 地址,它将接受 10.xxx 范围内的任何 IP(我希望在添加 10.0.0.0
地址时设置 includeSubdomains="true"
会为我做这件事。但它没有)
作为最后的手段,是否可以在运行时编辑network_security_config.xml
文件,以便在启动应用程序时将其中一个域条目的域名动态更新为当前本地IP?
该应用是使用 Unity 2019.1.8 使用 .net 4.x IL2CPP 脚本运行时开发的
【问题讨论】:
【参考方案1】:实现这一点的简单方法是在您的 AndroidManifest.xml 中使用此属性,您可以在其中允许所有请求的所有 http:
android:usesCleartextTraffic="true"
但是,如果您想为不同的链接进行更多配置,例如,允许某些域使用 http 但不允许其他域使用,您必须提供 networkSecurityConfig
文件。
要在 Android 9 Pie 中执行此操作,您必须在您的 Manifest application
标签中设置一个 networkSecurityConfig
,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:networkSecurityConfig="@xml/network_security_config">
</application>
</manifest>
然后在您的 xml 文件夹中,您现在必须创建一个名为 network_security_config 的文件,就像您在清单中命名它的方式一样,从那里您的文件内容应该是这样的,以启用所有不加密的请求:
<?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>
从那里你很高兴。现在,您的应用将对所有类型的连接发出请求。有关此主题的更多信息https://developer.android.com/training/articles/security-config。
【讨论】:
非常感谢,我遇到了这个问题。【参考方案2】:试试这个
//in AndroidManifest.xml
<application
android:networkSecurityConfig="@xml/network_security_config">
.
</application>
<?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>
【讨论】:
【参考方案3】:尝试 10.0.2.2 而不是 localhost。这个对我有用。 Source
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>
【讨论】:
以上是关于在运行时将network_security_config.xml的域名设置为localhost的主要内容,如果未能解决你的问题,请参考以下文章