Skip to content

Instantly share code, notes, and snippets.

@rdavisau
Created December 3, 2015 00:34
Show Gist options
  • Save rdavisau/9c6bb7d42b0b1e5dd9a9 to your computer and use it in GitHub Desktop.
Save rdavisau/9c6bb7d42b0b1e5dd9a9 to your computer and use it in GitHub Desktop.
A UIWebView subclass for Xamarin iOS that accepts self-signed certificates. Note the caveats at https://ryandavis.io/allowing-uiwebview-to-accept-self-signed-certificates
public class AcceptSelfSignedCertificateWebView : UIWebView
{
private NSUrlRequest _failedRequest;
private bool _authenticated;
private bool OnShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
{
var result = _authenticated;
if (!_authenticated)
{
_failedRequest = request;
var urlConnection = NSUrlConnection.FromRequest(request, new AcceptsSelfSignedCertificateUrlConnectionDelegate(this));
urlConnection.Start();
}
return result;
}
public AcceptSelfSignedCertificateWebView(RectangleF frame) : base(frame)
{
AcceptSelfSignedInit();
}
public AcceptSelfSignedCertificateWebView(IntPtr handle) : base(handle)
{
AcceptSelfSignedInit();
}
public AcceptSelfSignedCertificateWebView()
{
AcceptSelfSignedInit();
}
private void AcceptSelfSignedInit()
{
ShouldStartLoad = OnShouldStartLoad;
}
public class AcceptsSelfSignedCertificateUrlConnectionDelegate : NSUrlConnectionDelegate
{
private readonly AcceptSelfSignedCertificateWebView _webView;
private NSUrlRequest _failedRequest => _webView._failedRequest;
private bool _authenticated { set { _webView._authenticated = value; } }
public AcceptsSelfSignedCertificateUrlConnectionDelegate(AcceptSelfSignedCertificateWebView parent)
{
_webView = parent;
}
public override void WillSendRequestForAuthenticationChallenge(NSUrlConnection connection,
NSUrlAuthenticationChallenge challenge)
{
if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodServerTrust)
{
var challengeHost = challenge.ProtectionSpace.Host;
var baseUrlHost = _failedRequest.Url.Host;
if (challengeHost == baseUrlHost)
challenge.Sender.UseCredentials(NSUrlCredential.FromTrust(challenge.ProtectionSpace.ServerSecTrust), challenge);
}
challenge.Sender.ContinueWithoutCredentialForAuthenticationChallenge(challenge);
}
public override void ReceivedResponse(NSUrlConnection connection, NSUrlResponse response)
{
_authenticated = true;
connection.Cancel();
_webView.LoadRequest(_failedRequest);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment