问题
I'm using an online store for user images uploaded with our App secured by SSL. The upload works all well as I'm using the WebClient with the certificate attached. But when I'm trying to use the Xamarin.Forms.Image component e.g. with the Source set to "https://blabla.com/upload/image123.jpg" the image can't be loaded on Android. On iOS this works as I've got a custom NSUrlProtocol which handles the SSL connection.
var image = new Image();
//will use ImageLoaderSourceHandler
image.Source = "https://blabla.com/upload/image123.jpg";
In case of a WebClient I attach the X509Certificate2 (private key and password) to HttpWebRequest.ClientCertificates and it works. But I'm lost on how I can provide that certificate to whatever loading mechanism is behind ImageLoaderSourceHandler.
How can I make this work on Android?
回答1:
So I ended up setting up my own SecuredUriImageSource:
var image = new Image();
//will use SecuredImageLoaderSourceHandler
image.Source = new SecuredUriImageSource ("https://blabla.com/upload/image123.jpg");
Which uses this custom handler to load the image, while WebClientEx attaches the actual Certificate to the connection.
[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;
}
}
}
回答2:
I followed the settings in https://blog.xamarin.com/securing-web-requests-with-tls-1-2/ and the HTTPS source just starts to load.
Edit:
You can open the property page of the "Android project" --> "Android Options" --> "Advanced" and select HttpClient Implementation to be Managed code, and use Native TLS 1.2+ for the next option
回答3:
I had to update all Xamarin.Android packages for it to work
来源:https://stackoverflow.com/questions/41160918/xamarin-forms-image-source-with-ssl