Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin way to open self signed certificate webpage in UIWebView

As the question title described, I want to open a self signed webpage within an UIWebview (Xamarin.iOS) By default, self signed webpages do not load in an UIWebView.

Important requirements for the solution:

  • It should be accepted by Apple when I want to submit the app to the Apple app store (so a custom NSUrlRequest does not fit).
  • It should load css and javascript properly.

I found a possible solution on stackoverflow but this is for native iOS. https://stackoverflow.com/a/11664147 I was also wondering if the solution described above requires to login using a NSUrlConnectionDelegate.

The desired solution should be that the user can fill-in the credentials by himself using the UIWebView.

Could someone provide the Xamarin solution for this? I tried it by myself but couldn't get it work.

Thanks in advance for your help.

like image 786
StackFlower Avatar asked Sep 17 '14 13:09

StackFlower


1 Answers

I know this is quite an old post, but it was quite an interesting question, so I had to take a go at at. So if you still need it (most likely not) or if anyone finds this post, here are a ported version of the native UIWebView with support for self signed. It can be used as a regular UIWebView with the exception that it takes a hostname as additional parameter, which should be the hostname of the page where certificate check should be disabled.

public class InsecureWebView : UIWebView, INSUrlConnectionDataDelegate, IUIWebViewDelegate
{
    public InsecureWebView(string baseUrl) : base()
    {
        Setup (baseUrl);
    }

    public InsecureWebView(CoreGraphics.CGRect rect, string baseUrl) : base(rect)
    {
        Setup (baseUrl);
    }

    public InsecureWebView(NSCoder coder, string baseUrl) : base(coder)
    {
        Setup (baseUrl);
    }

    public InsecureWebView(NSObjectFlag t, string baseUrl) : base(t)
    {
        Setup (baseUrl);
    }

    public InsecureWebView(IntPtr handler, string baseUrl) : base(handler)
    {
        Setup (baseUrl);
    }

    string baseUrl = null;
    bool authenticated;
    NSUrlRequest failedRequest;

    private void Setup(string baseUrl)
    {
        this.Delegate = this;
        this.baseUrl = baseUrl;
    }


    [Foundation.Export ("webView:shouldStartLoadWithRequest:navigationType:")]
    public bool ShouldStartLoad (UIKit.UIWebView webView, Foundation.NSUrlRequest request, UIKit.UIWebViewNavigationType navigationType)
    {
        var result = authenticated;
        if (!authenticated) {
            failedRequest = request;
            NSUrlConnection.FromRequest (request, this);
        }
        return result;
    }

    [Foundation.Export ("connection:willSendRequestForAuthenticationChallenge:")]
    public void WillSendRequestForAuthenticationChallenge (NSUrlConnection connection, NSUrlAuthenticationChallenge challenge)
    {
        if (challenge.ProtectionSpace.AuthenticationMethod == NSUrlProtectionSpace.AuthenticationMethodServerTrust) {
            var baseUrl = new NSUrl (this.baseUrl);
            if (challenge.ProtectionSpace.Host == baseUrl.Host) {
                challenge.Sender.UseCredential (NSUrlCredential.FromTrust (challenge.ProtectionSpace.ServerSecTrust), challenge);
            }
        }
        challenge.Sender.ContinueWithoutCredential (challenge);
    }

    [Foundation.Export ("connection:didReceiveResponse:")]
    public void DidReceivedResponse(NSUrlConnection connection, NSUrlResponse response)
    {
        authenticated = true;
        connection.Cancel ();
        LoadRequest (failedRequest);
    }
}
like image 180
Morten Olsen Avatar answered Sep 24 '22 03:09

Morten Olsen