Xamarin .Net Core HttpClientHandler方法未实现(适用于Mac的VS)

时间:2017-09-22 18:10:14

标签: xamarin .net-core

我正在编写一个连接到我的WebAPI的.net核心(标准1.6)库。 WebApi需要客户端证书。

.net核心库是从Xamarin iOS应用程序调用的。

我无法终身发送带有客户端证书标头的HTTP请求。

我可以使用该库并在Windows机器上使用Visual Studio 2017中的客户端证书发布到API。

当我使用VS for Mac将同一个项目移动到我的Xamarin iOS应用程序时,我得到: 设置SslProtocol或添加客户端证书时“方法未实现”:

var handler = new HttpClientHandler();
            handler.ClientCertificateOptions =     ClientCertificateOption.Manual;
            handler.SslProtocols = SslProtocols.Tls12;
            handler.ClientCertificates.Add(new X509Certificate2(certificate));

相关图书馆:

using System.Net;
using System.Net.Http;
using System.Security;
using System.Security.Cryptography.X509Certificates;

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

好吧,这花了我很长一段时间,但我能够在Web请求中发送客户端证书,以便在我们的服务器上用于客户端身份验证。

首先,正如Xamarin和.netCore一样令人敬畏,他们缺少很多方法.net开发人员习惯了。我无法构建可在Android和ios上运行的跨平台请求,例如HttpWebRequest。

对于ios,我创建了一个继承自以下的自定义类:NSUrlConnectionDataDelegate

然后我覆盖:

   public override void WillSendRequestForAuthenticationChallenge(NSUrlConnection 
 connection, NSUrlAuthenticationChallenge challenge)
    {                 
        byte[] cert = System.IO.File.ReadAllBytes("clientCertificate.pfx");

        NSUrlCredential credential = iSecurity.ImportPK12File(cert, "certPassword");

        challenge.Sender.UseCredential(credential, challenge);          
    }

然后我创建了一个返回凭证的类:

//cert is a byte array of a .pfx file included in the resource file

//iSecurity Custom class

    NSUrlCredential credential = iSecurity.ImportPK12File(cert, "certpassword");

        public static NSUrlCredential ImportPK12File(byte[] fileBytes, string passPhrase)
        {

        var cert = new X509Certificate2(fileBytes, passPhrase);

        var options = NSDictionary.FromObjectAndKey(NSObject.FromObject(passPhrase), SecImportExport.Passphrase);

        NSDictionary[] importStatus;
        SecStatusCode statusCode = SecImportExport.ImportPkcs12(fileBytes, options, out importStatus);

        if(statusCode != SecStatusCode.Success){
            throw new Exception("Error importing certificate. ");
        }

        NSObject obj = importStatus[0]["trust"];
        IntPtr secTrustRef = obj.Handle;

        var identityHandle = importStatus[0][SecImportExport.Identity];
        var identity = new SecIdentity(identityHandle.Handle);
        var certificate = new SecCertificate(cert.GetRawCertData());

        SecCertificate[] certificates = { certificate };

        return NSUrlCredential.FromIdentityCertificatesPersistance(identity, certificates, NSUrlCredentialPersistence.ForSession);

    }

您也可以覆盖此方法并发送信用: public override void ReceivedAuthenticationChallenge(NSUrlConnection连接,NSUrlAuthenticationChallenge挑战)         {             base.ReceivedAuthenticationChallenge(连接,挑战);         }

我可以将它移到那里但是为了解决这个问题,你创建了继承自的类的委托:NSUrlConnectionDataDelegate 并将其添加到您的连接。通过此连接触发的任何请求都将覆盖该方法并传递证书。