iOS9的UIWebView中阻止了来自cdnjs.cloudflare.com的文件
我正在使用iOS9的UIWebView中阻止了来自cdnjs.cloudflare.com的文件,ios,uiwebview,ios9,cdn,app-transport-security,Ios,Uiwebview,Ios9,Cdn,App Transport Security,我正在使用UIWebView在iOS应用程序中加载网站。更新到iOS 9并相应构建应用程序后,网站仍然可以从我的服务器上正常加载,但无法从cdnjs加载引导的css和js文件(例如) 我假设这与新的ATS有关,但到目前为止,我没有弄清楚为什么它无法从cdnjs加载文件(它们支持TLS 1.2和大量现代密码),而且我没有一个带有nscurl的El Capitan可用于测试cdnjs(请参阅)。我在El Capitan上为您运行了一个nscurl。根据结果,问题在于cdnjs不支持前向保密,因此您必
UIWebView
在iOS应用程序中加载网站。更新到iOS 9并相应构建应用程序后,网站仍然可以从我的服务器上正常加载,但无法从cdnjs加载引导的css和js文件(例如)
我假设这与新的ATS有关,但到目前为止,我没有弄清楚为什么它无法从cdnjs加载文件(它们支持TLS 1.2和大量现代密码),而且我没有一个带有nscurl的El Capitan可用于测试cdnjs(请参阅)。我在El Capitan上为您运行了一个
nscurl
。根据结果,问题在于cdnjs不支持前向保密,因此您必须为cdnjs.cloudflare.com添加一个异常,并将NSAppTransportSecurity
设置为false
更新:以下几行就足够了:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>cdnjs.cloudflare.com</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key><false/>
</dict>
</dict>
</dict>
NSAppTransportSecurity
NSExceptionDomains
cdnjs.cloudflare.com
NSExceptionRequiresForwardSecretary
有关详细信息,请参阅下面的日志:
nscurl --ats-diagnostics --verbose https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css
Starting ATS Diagnostics
Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================
Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
2015-09-29 14:59:16.983 nscurl[490:10186] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrust 0x7f7f89e052f0 [0x7fff7c50f890]>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<SecCertificate 0x7f7f89e04570 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f89e04950 [0x7fff7c50f890]>"
), NSUnderlyingError=0x7f7f8b8059b0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrust 0x7f7f89e052f0 [0x7fff7c50f890]>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<SecCertificate 0x7f7f89e04570 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f89e04950 [0x7fff7c50f890]>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorFailingURLStringKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorClientCertificateStateKey=0}
---
================================================================================
Allowing Arbitrary Loads
---
Allow All Loads
ATS Dictionary:
{
NSAllowsArbitraryLoads = true;
}
Result : PASS
---
================================================================================
Configuring TLS exceptions for cdnjs.cloudflare.com
---
TLSv1.2
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
};
};
}
2015-09-29 14:59:17.140 nscurl[490:10186] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrust 0x7f7f89f136f0 [0x7fff7c50f890]>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<SecCertificate 0x7f7f89f12b20 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f89f12d60 [0x7fff7c50f890]>"
), NSUnderlyingError=0x7f7f8b804160 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrust 0x7f7f89f136f0 [0x7fff7c50f890]>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<SecCertificate 0x7f7f89f12b20 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f89f12d60 [0x7fff7c50f890]>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorFailingURLStringKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorClientCertificateStateKey=0}
---
---
TLSv1.1
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
};
};
}
2015-09-29 14:59:17.170 nscurl[490:10186] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrust 0x7f7f89c2a2a0 [0x7fff7c50f890]>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<SecCertificate 0x7f7f89c47750 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f89c45c90 [0x7fff7c50f890]>"
), NSUnderlyingError=0x7f7f8b9029d0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrust 0x7f7f89c2a2a0 [0x7fff7c50f890]>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<SecCertificate 0x7f7f89c47750 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f89c45c90 [0x7fff7c50f890]>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorFailingURLStringKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorClientCertificateStateKey=0}
---
---
TLSv1.0
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
};
};
}
2015-09-29 14:59:17.206 nscurl[490:10186] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
Result : FAIL
Error : Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrust 0x7f7f8b905230 [0x7fff7c50f890]>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
"<SecCertificate 0x7f7f8b904590 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f8b9047d0 [0x7fff7c50f890]>"
), NSUnderlyingError=0x7f7f89d5fce0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrust 0x7f7f8b905230 [0x7fff7c50f890]>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
"<SecCertificate 0x7f7f8b904590 [0x7fff7c50f890]>",
"<SecCertificate 0x7f7f8b9047d0 [0x7fff7c50f890]>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorFailingURLStringKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css, NSErrorClientCertificateStateKey=0}
---
================================================================================
Configuring PFS exceptions for cdnjs.cloudflare.com
---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring PFS exceptions and allowing insecure HTTP for cdnjs.cloudflare.com
---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled for cdnjs.cloudflare.com
---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for cdnjs.cloudflare.com
---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"cdnjs.cloudflare.com" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
nscurl--ats诊断--verbosehttps://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css
启动ATS诊断
配置ATS Info.plist键并将HTTPS加载结果显示给https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css.
如果URLSession:task:didCompleteWithError:返回零错误,则测试将“通过”。
================================================================================
默认ATS安全连接
---
ATS默认连接
ATS字典:
{
}
2015-09-29 14:59:16.983 nscurl[490:10186]NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)
结果:失败
错误:Error Domain=NSURERRORDOMAIN Code=-1200“发生SSL错误,无法建立到服务器的安全连接。”UserInfo={NSURERRORFAILLINGURLPERTRETERRORKEY=,NSLocalizedRecoverysSuggestion=是否仍要连接到服务器?,\u kCFStreamErrorDomainKey=3,\u kCFStreamErrorCodeKey=-9802,NSERROPERCertificateChainKey==(
"",
""
),NSUnderlyingError=0x7f7f8b8059b0{Error Domain=KCFerrorDomain=KCF网络代码=-1200“(null)”用户信息={{kCFStreamPropertySSLClientCertificateState=0,kCFStreamPropertySSLPeerTrust=,[KCFnetworkCfsstreamsLerOriginalValue=-9802,[kCFStreamErrorDomainKey=3,[kCFStreamErrorCodeKey=-9802,KCFStreamPropertySSLpeertificates=(
"",
""
)}},NSLocalizedDescription=发生SSL错误,无法与服务器建立安全连接。NSErrorFailingURLKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css,NSErrorFailingURLStringKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css,NSerrorClientCertificateeStateKey=0}
---
================================================================================
允许任意载荷
---
允许所有负载
ATS字典:
{
NSAllowsArbitraryLoads=true;
}
结果:通过
---
================================================================================
为cdnjs.cloudflare.com配置TLS异常
---
TLSv1.2
ATS字典:
{
NSExceptionDomains={
“cdnjs.cloudflare.com”={
NSExceptionMinimumTLSVersion=“TLSv1.2”;
};
};
}
2015-09-29 14:59:17.140 nscurl[490:10186]NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)
结果:失败
错误:Error Domain=NSURERRORDOMAIN Code=-1200“发生SSL错误,无法建立到服务器的安全连接。”UserInfo={NSURERRORFAILLINGURLPERTRETERRORKEY=,NSLocalizedRecoverysSuggestion=是否仍要连接到服务器?,\u kCFStreamErrorDomainKey=3,\u kCFStreamErrorCodeKey=-9802,NSERROPERCertificateChainKey==(
"",
""
),NSUnderlyingError=0x7f7f8b804160{Error Domain=KCFerrorDomain=KCF网络代码=-1200“(null)”用户信息={{kCFStreamPropertySSLClientCertificateState=0,kCFStreamPropertySSLPeerTrust=,[KCFnetworkCfsstreamsLerOriginalValue=-9802,[KCFStreamerDomainKey=3,[KCFStreamerCodeKey=-9802,kCFStreamPropertySSLPeerCertificates=(
"",
""
)}},NSLocalizedDescription=发生SSL错误,无法与服务器建立安全连接。NSErrorFailingURLKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css,NSErrorFailingURLStringKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css,NSerrorClientCertificateeStateKey=0}
---
---
TLSv1.1
ATS字典:
{
NSExceptionDomains={
“cdnjs.cloudflare.com”={
NSExceptionMinimumTLSVersion=“TLSv1.1”;
};
};
}
2015-09-29 14:59:17.170 nscurl[490:10186]NSURLSession/NSURLConnection HTTP加载失败(kCFStreamErrorDomainSSL,-9802)
结果:失败
错误:Error Domain=NSURERRORDOMAIN Code=-1200“发生SSL错误,无法建立到服务器的安全连接。”UserInfo={NSURERRORFAILLINGURLPERTRETERRORKEY=,NSLocalizedRecoverysSuggestion=是否仍要连接到服务器?,\u kCFStreamErrorDomainKey=3,\u kCFStreamErrorCodeKey=-9802,NSERROPERCertificateChainKey==(
"",
""
),NSUnderlyingError=0x7f7f8b9029d0{Error Domain=kCFErrorDomainCFNetwork Code=-1200“(null)”用户信息={{kCFStreamPropertySSLClientCertificateState=0,kCFStreamPropertySSLPeerTrust=,[KCFnetworkCfsstreamsLerOriginalValue=-9802,[kCFStreamErrorDomainKey=3,[kCFStreamErrorCodeKey=-9802,KCFStreamPropertySlPeerCertificates=-9802=(
"",
""
)}},NSLocalizedDescription=发生SSL错误,无法与服务器建立安全连接。NSErrorFailingURLKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css,NSErrorFailingURLStringKey=https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.min.css,NSerrorClientCertificateeStateKey=0}
---
---
TLSv1.0
言语