skip to Main Content

I have an enterprise Flutter application that needs to launch the login page for the user’s Identity Provider (IdP) inside a webview within the app. The IdP supports certificate-based authentication using a certificate present on the user’s device (through MDM) to authenticate the user without needing to provide any credentials.

When launching a safari browser to launch this page, it works fine. Safari prompts the user to select a certificate the first time from the ones available and Safari sends it to the server and page successfully proceeds to present the protected resource.

enter image description here

Another requirement is that we need to open the IdP page using a specific user-agent string so that their firewall can be configured to only allow selected apps and not any random Safari page.

Unfortunately, the Safari In-App Browser does not allow overriding user-agent. While using an in-app web view using https://pub.dev/packages/flutter_inappwebview or https://pub.dev/packages/webview_flutter we are unable to get the certificate prompt like the one we see in safari and the communication fails with the following SSL error, with code -1200

An SSL error has occurred and a secure connection to the server cannot be made

When using InAppWebView from https://pub.dev/packages/flutter_inappwebview and accessing the protected site, the onReceivedClientCertRequest handler gets invoked, but I am not sure how to pass the device certificate back in the response. The ClientCertResponse expects a path to the certificate, what should this be?

Is there a way to retrieve the appropriate certificate from the OS’s secure storage (keychain?) and send it to the web page? Either Flutter or native iOS code is ok. We are only focusing on iOS for this use case.

2

Answers


  1. i don’t have a good solution/workaround for your problem but at least i can link you what (i guess) the root problem is:

    https://developer.apple.com/library/archive/qa/qa1745/_index.html :

    Apps can only access keychain items in their own keychain access groups. This means that items in the Apple access group are only available to Apple-provided apps such as Safari or Mail.

    With that in mind you might be able to

    1. get your certificate into your app’s ‘keychain access group’
    2. use something like/ similar to https://pub.dev/packages/flutter_keychain to .get() the certificate
    3. craft your http request using flutters http (no web-view required)
    Login or Signup to reply.
  2. in case of …

    I wrote a flutter PoC that can connect to a HTTPS Server with mtls self-signed certificates on https://github.com/ysimonx/mtls-ssl-generator

    As my PoC is using Flutter’Dio package, you should be able to force the user-agent .

    And may be, you won’t need a webview anymore 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search