Xamarin.Forms Image.Source 使用 SSL

Xamarin.Forms Image.Source with SSL

我正在使用一个在线商店来存储使用我们的受 SSL 保护的应用程序上传的用户图片。上传工作正常,因为我使用的是附带证书的 WebClient。但是当我尝试使用 Xamarin.Forms.Image 组件时,例如将源设置为“https://blabla.com/upload/image123.jpg”时,无法在 Android 上加载图像。在 iOS 上,这是有效的,因为我有一个处理 SSL 连接的自定义 NSUrlProtocol。

var image = new Image();

//will use ImageLoaderSourceHandler 
image.Source = "https://blabla.com/upload/image123.jpg";

如果是 WebClient,我将 X509Certificate2(私钥和密码)附加到 HttpWebRequest.ClientCertificates 并且它可以工作。但是我不知道如何向 ImageLoaderSourceHandler 背后的任何加载机制提供该证书。

如何在 Android 上进行这项工作?

所以我最终设置了自己的 SecuredUriImageSource:

var image = new Image();

//will use SecuredImageLoaderSourceHandler  
image.Source = new SecuredUriImageSource ("https://blabla.com/upload/image123.jpg");

它使用此自定义处理程序加载图像,而 WebClientEx 将实际证书附加到连接。

[assembly: ExportImageSourceHandler(typeof(SecuredUriImageSource), typeof(SecuredImageLoaderSourceHandler))]
namespace Helpers
{
    public class SecuredUriImageSource : ImageSource 
    {
        public readonly UriImageSource UriImageSource = new UriImageSource();

        public static SecuredUriImageSource FromSecureUri(Uri uri)
        {
            var source = new SecuredUriImageSource ();

            source.UriImageSource.Uri = uri;

            return source;
        }
    }

    public class SecuredImageLoaderSourceHandler : IImageSourceHandler
    {
        public async Task<Bitmap> LoadImageAsync(ImageSource imagesource, Android.Content.Context context, CancellationToken cancelationToken = default(CancellationToken))
        {
            var imageLoader = imagesource as SecuredUriImageSource;

            if (imageLoader != null && imageLoader.UriImageSource.Uri != null)
            {
                var webClient = new WebExtensions.WebClientEx();
                var data = await webClient.DownloadDataTaskAsync(imageLoader.UriImageSource.Uri, cancelationToken).ConfigureAwait(false);
                using (var stream = new MemoryStream(data) )
                    return await BitmapFactory.DecodeStreamAsync(stream).ConfigureAwait(false);
            }

            return null;
        }
    }
}

我按照 https://blog.xamarin.com/securing-web-requests-with-tls-1-2/ 中的设置进行操作,HTTPS 源刚刚开始加载。

编辑:

可以打开"Android project"的属性页面 --> "Android Options" --> "Advanced" and select HttpClient Implementation to be Managed code ,并为下一个选项使用本机 TLS 1.2+

我必须更新所有 Xamarin.Android 包才能正常工作

您也可以使用 StreamImageSource 或 ImageSource.FromStream(() => ...) 并提供您自己的自定义逻辑来提供图像流。

var image = new Image();

image.Source = new StreamImageSource() {
     Stream = async (CancellationToken cancellationToken) => {
         Stream stream = //...custom logic using your own HttpClient / WebClient for obtaining the data stream;

         return stream;
     }
}