Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xamarin Android-使用带证书的HttpClient调用API_Xamarin_Xamarin.android - Fatal编程技术网

Xamarin Android-使用带证书的HttpClient调用API

Xamarin Android-使用带证书的HttpClient调用API,xamarin,xamarin.android,Xamarin,Xamarin.android,我们正在尝试与我们的API通信,该API在请求中需要一个证书,但它不能正常工作 通常我们只是通过在请求头中传递SubscriptionKey来使用外部服务或Azure API管理API,但这一次我们有一个证书(.cer),我们需要将其注入AndroidHttpClientHandler中,但该功能似乎不受支持,或者我们可能使用错了 你知道这种情况是否真的有可能,如果有,我们应该如何实现?我尝试了很多方法,比如创建一个定制的AndroidHttpClientHandler,允许在其中放入一个Cli

我们正在尝试与我们的API通信,该API在请求中需要一个证书,但它不能正常工作

通常我们只是通过在请求头中传递SubscriptionKey来使用外部服务或Azure API管理API,但这一次我们有一个证书(.cer),我们需要将其注入AndroidHttpClientHandler中,但该功能似乎不受支持,或者我们可能使用错了


你知道这种情况是否真的有可能,如果有,我们应该如何实现?我尝试了很多方法,比如创建一个定制的AndroidHttpClientHandler,允许在其中放入一个ClientCertificate,但没有成功

最终成功地让它工作起来:D对于那些感兴趣的人,下面是我实现它的方法:

TL;DR:升级到VisualStudio2019,HttpWebRequest得到了帮助(您可以在下面找到代码示例);-)

背景:我们的项目由一个PCL和一个Android项目组成。在团队中,我们知道必须将PCL迁移到.NET标准项目中,但这需要时间,尤其是当您需要处理大量库(未更新到.NET标准的库)时

  • 当您想调用API时,首先想到的是使用HttpClient/HttpRequestHandler对,我们只需在HttpRequestHandler中传递证书,如下所示:

            private Task<string> ExecuteRequest(Uri uri, X509Certificate2 certificate)
            {
                // Create a web request that points to our secured Backend API
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
    
                if (certificate != null)
                {
                    // Associate the certificates with the request
                    request.ClientCertificates.Add(certificate);
                }
    
                // Launch the web request
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    
                // Output the stream to a jsonTextReader or anything else depending on your needs
                using (Stream stream = response.GetResponseStream())
                using (StreamReader sr = new StreamReader(stream))
                using (var jsonTextReader = new JsonTextReader(sr))
                {
                    // Do whatever you want
                }
            }
    
    httpRequestHandler.ClientCertificates.Add(新的X509Certificate2(..)

为什么它不起作用?因为我们使用的是Xamarin.Android,它使用的是引擎盖下的Mono.Droid,所以我们遇到了不受欢迎的NotImplementedException()!那么WebRequestHandler呢?同样的命运:P

希望能从HttpWebRequest中获得如下救赎:

        private Task<string> ExecuteRequest(Uri uri, X509Certificate2 certificate)
        {
            // Create a web request that points to our secured Backend API
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);

            if (certificate != null)
            {
                // Associate the certificates with the request
                request.ClientCertificates.Add(certificate);
            }

            // Launch the web request
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            // Output the stream to a jsonTextReader or anything else depending on your needs
            using (Stream stream = response.GetResponseStream())
            using (StreamReader sr = new StreamReader(stream))
            using (var jsonTextReader = new JsonTextReader(sr))
            {
                // Do whatever you want
            }
        }
私有任务执行器请求(Uri、X509Certificate2证书)
{
//创建指向我们的安全后端API的web请求
HttpWebRequest请求=(HttpWebRequest)HttpWebRequest.Create(uri);
如果(证书!=null)
{
//将证书与请求关联
request.ClientCertificates.Add(证书);
}
//启动web请求
HttpWebResponse=(HttpWebResponse)request.GetResponse();
//根据需要,将流输出到jsonTextReader或任何其他文件
使用(Stream=response.GetResponseStream())
使用(StreamReader sr=新StreamReader(stream))
使用(var jsonTextReader=new jsonTextReader(sr))
{
//你想干什么就干什么
}
}
这段代码在我的机器(Visual Studio 2019)上运行,但在我的同事(Visual Studio 2017)上不起作用:确实遇到了以下例外情况:

System.Security.Authentication.AuthenticationException:调用SSPI失败,请参阅内部异常

我的机器上也安装了VS2017,所以我试图用它执行相同的代码,尽管听起来很奇怪,我还是收到了错误


当然,证书必须是“嵌入式资源”

您使用的是公共证书还是私有证书(自证书)?如果您使用私有证书,您将遇到
javax.net.ssl.SSLException:不受信任的服务器证书例外。
我不知道您想要实现哪些特定功能,如果您想通过SSL连接服务器,这是可以实现的。到目前为止,我们尝试的方法不起作用,因为当我们想使用经典的WebRequestHandler时,它不起作用,因为抛出了一个异常“NotImplementedException”-->我们的项目仍然是一个PCL(针对.NET 4.5)