我已经看到了很多关于这个的问题,我想我写了一个完整的答案和例子,因为我可以。
注意:使用
WKWebView
使用自签名证书,请参见此
answer
HttpClient实现
注意:使用
badssl.com
在本例中
托管(默认)
系统网Http。HttpRequestException:发送请求时出错--->
系统网WebException:错误:TrustFailure(发生了一个或多个错误。)---&燃气轮机;
系统AggregateException:发生了一个或多个错误---&燃气轮机;
系统安全身份验证。AuthenticationException:调用SSPI失败,请参阅内部异常---&燃气轮机;
单声道。安全界面Tl
原始单声道
Managed
提供商正在获取
真正地
长在牙齿上,仅支持TLS1.0,在安全和;性能我将转而使用NSUrlSession实现。
CFNetwork(iOS 6以上)
注意:由于这个iOS版本现在已经相当旧了,我个人不再瞄准它,所以我将此留空。。。(除非有人真的需要我查找笔记;-)
NSUrlSession(iOS 7以上)
Xamarin提供了
HttpMessageHandler
子类(
NSUrlSessionHandler
)这是基于iOS的
NSUrlSession
.
对自签名证书单独使用它将导致:
系统网WebException:出现SSL错误,无法与服务器建立安全连接---&燃气轮机;
地基N错误异常:
“基础”类型的例外。引发了“NSErrorException”。
问题是,iOS认为自签名证书不安全且不受信任,因此你必须对你的应用程序应用ATS例外,以便iOS知道你的应用程序在
Info.plist
.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>self-signed.badssl.com</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
既然iOS知道你的应用程序正在进行不受信任的呼叫,一个
HttpClient
请求现在将导致此错误:
系统网WebException:此服务器的证书无效。您可能正在连接一个假装是自签名的服务器。Badsl。com–这可能会使您的机密信息处于风险之中---&燃气轮机;
地基N错误异常:“Foundation”类型的异常。引发了“NSErrorException”。
此错误是由于即使允许ATS异常,但
违约
NSUrlSession
iOS提供的将应用其标准
NSUrlAuthenticationChallenge
由于自签名证书永远无法进行真正的身份验证(即使通过客户端固定),因为它在其链中不包括受iOS信任的根证书颁发机构(CA),因此它将失败。
因此,您需要拦截并绕过iOS提供的证书安全检查(是的,一个大的安全警报、闪烁的红灯等)
但是
,您可以通过创建
NSUrlSessionDataDelegate
执行旁路的子类。
public class SelfSignedSessionDataDelegate : NSUrlSessionDataDelegate, INSUrlSessionDelegate
{
const string host = "self-signed.badssl.com";
public override void DidReceiveChallenge(NSUrlSession session, NSUrlAuthenticationChallenge challenge, Action<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
{
switch (challenge.ProtectionSpace.Host)
{
case host:
using (var cred = NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust))
{
completionHandler.Invoke(NSUrlSessionAuthChallengeDisposition.UseCredential, cred);
}
break;
default:
completionHandler.Invoke(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, null);
break;
}
}
}
现在你需要应用它
NSUrlSessionDataDelegate
到a
NSUrlSession
并使用该新会话创建您的
NSUrlSessionHandler
将在
HttpClient
.
var url = "https://self-signed.badssl.com";
using (var selfSignedDelegate = new SelfSignedSessionDataDelegate())
using (var session = NSUrlSession.FromConfiguration(NSUrlSession.SharedSession.Configuration, (INSUrlSessionDelegate)selfSignedDelegate, NSOperationQueue.MainQueue))
using (var handler = new NSUrlSessionHandler(session))
using (var httpClient = new HttpClient(handler))
using (var response = await httpClient.GetAsync(url))
using (var content = response.Content)
{
var result = await content.ReadAsStringAsync();
Console.WriteLine(result);
}
注:
仅举个例子,通常您会创建一个委托、NSUrlSession、HttpClient、NSUrlSessionHandler,并将其重新用于所有请求(即单例模式)
您的请求现在生效:
<html>
<head>
<title>self-signed.badssl.com</title>
</head>
<body><div id="content"><h1 style="font-size: 12vw;">
self-signed.<br>badssl.com
</h1></div>
</body>
</html>
注:
提供您自己定制的选项
NSUrlSession
到Xamarin的
NSUrlSessionHandler
真的是
新
(2017年11月),目前尚未发布版本(alpha、beta或stable),但当然,可从以下网址获取来源:
使用
NSUrlSession
而不是
HttpClient
:
您也可以直接使用
NSUrlSession
而不是
HttpClient
针对自签名证书。
var url = "https://self-signed.badssl.com";
using (var selfSignedDelegate = new SelfSignedSessionDataDelegate())
using (var session = NSUrlSession.FromConfiguration(NSUrlSession.SharedSession.Configuration, (INSUrlSessionDelegate)selfSignedDelegate, NSOperationQueue.MainQueue))
{
var request = await session.CreateDataTaskAsync(new NSUrl(url));
var cSharpString = NSString.FromData(request.Data, NSStringEncoding.UTF8).ToString();
Console.WriteLine(cSharpString);
}
注:
仅举个例子,通常您会创建一个委托和NSUrlSession,并将其重新用于所有请求,即单例模式
真正的解决方案?使用免费安全证书:
IHMO,避免所有自签名证书,甚至在开发环境中,使用免费证书服务之一,避免应用ATS异常、自定义代码拦截/绕过iOS安全等所有令人头痛的事情。。。并使你的应用程序web服务真正安全。
我个人使用Lets加密: