ionic-team / cordova-plugin-ionic-webview

Web View plugin for Cordova, specialized for Ionic apps.
Apache License 2.0
484 stars 390 forks source link

Per app VPN support #33

Closed DanWard closed 5 years ago

DanWard commented 6 years ago

Hey guys,

We're trying to use this plugin over the standard Cordova based one for one of our corporate internal apps. These apps use iOS per-app VPN settings (https://blogs.vmware.com/euc/2017/04/vmware-airwatch-101-per-app-vpn.html) to connect to internal resources. The unintended consequence is that it tries to route 'http://localhost:8080' over the tunnel, and fails. Log from start up:

2017-10-27 10:49:45.773958+1100 MyApp[1080:347066] Apache Cordova native platform version 4.5.0 is starting. 2017-10-27 10:49:45.774990+1100 MyApp[1080:347066] Multi-tasking -> Device: YES, App: YES 2017-10-27 10:49:45.791655+1100 MyApp[1080:347066] CDVWKWebViewEngine: trying to inject XHR polyfill 2017-10-27 10:49:45.878184+1100 MyApp[1080:347066] CDVWKWebViewEngine will reload WKWebView if required on resume 2017-10-27 10:49:45.878321+1100 MyApp[1080:347066] Using Ionic WKWebView 2017-10-27 10:49:45.879179+1100 MyApp[1080:347066] [CDVTimer][console] 0.180006ms 2017-10-27 10:49:45.879478+1100 MyApp[1080:347066] [CDVTimer][handleopenurl] 0.135958ms 2017-10-27 10:49:45.883067+1100 MyApp[1080:347066] [CDVTimer][intentandnavigationfilter] 3.506005ms 2017-10-27 10:49:45.883273+1100 MyApp[1080:347066] [CDVTimer][gesturehandler] 0.120997ms 2017-10-27 10:49:45.897891+1100 MyApp[1080:347066] [CDVTimer][splashscreen] 14.567018ms 2017-10-27 10:49:45.906098+1100 MyApp[1080:347066] [CDVTimer][statusbar] 8.054018ms 2017-10-27 10:49:45.908837+1100 MyApp[1080:347066] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2017-10-27 10:49:45.909380+1100 MyApp[1080:347066] [MC] Filtering mail sheet accounts for bundle ID: ****, source account management: 1 2017-10-27 10:49:45.913228+1100 MyApp[1080:347066] [MC] Result: NO 2017-10-27 10:49:45.913339+1100 MyApp[1080:347066] [CDVTimer][socialsharing] 7.135987ms 2017-10-27 10:49:45.914745+1100 MyApp[1080:347066] [CDVTimer][keyboard] 1.254022ms 2017-10-27 10:49:45.914878+1100 MyApp[1080:347066] [CDVTimer][TotalPluginStartup] 35.980046ms 2017-10-27 10:50:46.967100+1100 MyApp[1080:347066] Failed to load webpage with error: The request timed out.

Any help or ideas would be greatly appreciated.

Thanks, Daniel

EDIT: By changing 'http://localhost:8080/' to 'http://127.0.0.1:8080' in the config + source it allows me through and loads the page fine. Is it possible to make this change to your branch?

AlexKolesnik commented 6 years ago

Hi Daniel,

I suffer a very similar problem, in my case with Blackberry UEM.

But shouldn't that be addressed by the WKWebView, that is the cordova plugin itself rather than the Ionic integration or shouldn't this by solved by the VPN?

Where exactly did you have to make changes? I am very keen on using a workaround.

Thanks in advance

DanWard commented 6 years ago

Hey Alex,

One of the differences between the standard Cordova WKWebView plugin and the Ionic one is that it creates a webserver to serve content from. In iOS with a per-app VPN, the VPN tunnel handles all of the DNS lookups, bypassing hosts. As an unintended consequence of enterprise level security, it also looks up localhost, which fails on most DNS servers as it is usually in the hosts file.

To fix this, we just tell the plugin to listen on 127.0.0.1 and the javascript side of the plugin to call 127.0.0.1 instead of localhost.

It's 2 very simple changes:

  1. plugins/cordova-plugin-ionic-webview/src/ios/CDVWKWebViewEngine.m, line 31. #define CDV_LOCAL_SERVER @"http://localhost:8080" to #define CDV_LOCAL_SERVER @"http://127.0.0.1:8080"

  2. plugins/cordova-plugin-ionic-webview/src/ios/wk-plugin.js, line 22: return 'http://localhost:8080' + url; to return 'http://127.0.0.1:8080' + url;

This stops iOS from calling the VPN tunnel with the DNS lookup for localhost, and has the same effect as writing localhost. Thus enabling the plugin to work fine in enterprise environments. I hope this helps!

Daniel

AlexKolesnik commented 6 years ago

Thanks for the help.

I only have a superficial understanding of VPN but I strongly believe there should be a mechanism to define exclusions or inclusions to what domains the VPN would be allowed to handle.

Your workaround with patching also is not applicable for instance to Ionic View or any other app already built with an unpatched version of WkWebView. The workaround is also not very compatible with reproducible builds across multiple machines as the patch is it not easily distributed and acknowledged by the dependency managment.

But thank you very much, if there is really no other way to go I will use this as well.

Tankatronic commented 6 years ago

We ran into this exact issue as well with our internal app that uses a Per App VPN. Thank you for resolving it!

Please support this. Changing from localhost to 127.0.0.1 resolved it for us as well, but I do not like the idea of having to edit plugin files as part of our ios build process.

AlexKolesnik commented 6 years ago

After trying the patch, my locally stored images could not be loaded anymore.

Tankatronic commented 6 years ago

After trying this on a new project that was also using per app VPN, I ran into an issue where on start up my app would instead open up in Safari. The configurations between the two projects were the same, but adding <allow-navigation href="http:127.0.0.1:8080/*" /> to config.xml fixed the issue.

@AlexKolesnik Maybe this will also resolve your images failing to load.

cfmjohn commented 6 years ago

I've run into the exact same issue with a client using MobileIron Tunnel per app VPN (https://www.mobileiron.com/en/products/tunnel)

I agree that this should be sorted by the VPN provider. However, it would be appreciated if the CDV_LOCAL_SERVER value could be overridden via configuration for those of us caught out by this issue.

Edited to add: Looks like #41 comes close to allowing this to be configured.

wilk-polarny commented 6 years ago

Hello,

It seems we ran into the same issues after moving to VMware Airwatch, which creates a network extension tunneling the traffic to the enterprise network. Unfortunately, no connections to localhost are possible once the VPN kicks in, although we only resolve and forward specific hostnames. We will try to use the workaround mentioned within this issue and apply it using a cordova hook until we hear back from VMware regarding this issue (this might take a few weeks).

We would appreciate being able to adjust those values by using the configuration xml, including the port.

wilk-polarny commented 6 years ago

We were able to hot fix the issues with VMware Airwatch by applying the patches mentioned by @DanWard and @Tankatronic. Thank you! As a temporary solution, we use a cordova hook to manipulate the local plugin directory (which we don't check out into the SCM), as simply overriding the values within platform_www of the ios platform folder won't work.

mannsudhir commented 6 years ago

We are able to run the application using per-app VPN after changing localhost:8080 to 127.0.0.1:8080 but the app is not able to load the local images once there is no connectivity(For testing purpose we switch to airplane mode). We have functionality that user can take picture while offline and upload to backend once network is available. We are storing images in Document folder but user is not able to preview the image in airplane mode using per-app VPN. Any suggestion is really appreciated. Thanks.

cfmjohn commented 6 years ago

@mannsudhir Same here - once the VPN tunnel is established all connections to 127.0.0.1 are being captured and re-routed. We've not managed to find a workaround yet.

wilk-polarny commented 6 years ago

@mannsudhir , did you already add an additional <allow-navigation href="http:127.0.0.1:8080/*" /> line to your config.xml after patching the plugin?

This also may be related to #76

mannsudhir commented 6 years ago

@wilk-polarny, yes we changed in config.xml . Only solution that is working is switching back to UIWebview. UIWebview use file:// protocol to access the local resources where WKWebview use http:// protocol. So that's the reason the local resource call are not tunneled through VPN. So we change the value of CDV_LOCAL_SERVER @"http://localhost:8080" to @"file:///" after that everything works fine but now app is not able to access the images stored inside the document folder. If any other suggestion please let me know. Thanks.

wilk-polarny commented 6 years ago

@mannsudhir Did you try removing file:// as suggested by the ionic team?

See: https://ionicframework.com/docs/wkwebview/#my-local-resources-do-not-load

If you’re working with local files (text files, images, videos), you’ll need to make sure that the path of file does not have file:// in front of it.

For example:

file:///usr/home/dev/app/index.html
Should be rewritten to:

/usr/home/dev/app/index.html
mannsudhir commented 6 years ago

@wilk-polarny, We are not using file:// for any local resource (file:// protocol used in UIWebview to access the local files). App was working fine just to get it working with per-app VPN we change the value of CDV_LOCAL_SERVER to file:// .

alain-sarti commented 6 years ago

We are having the same problem. The mentioned workaround isn't really working for us, since we have an automated build pipeline which starts in an empty directory and installs all the required plugins via npm install. Is there any news yet if this will be configurable in the future?

We are also working with our clients to see if there is a chance to tell the vpn that localhost is a valid target.

mlynch commented 6 years ago

Just to confirm, using the IP address instead of localhost works?

As for supporting file:// going forward, it has too many problems with modern web APIs and waning support across webviews, so we've decided to not support it going forward and try to make it easier to use local resources easier. You can access any file by rewriting it to use localhost:8080/path/to/file

wilk-polarny commented 6 years ago

Just to confirm, using the IP address instead of localhost works?

Yes, but it seems to mess up loading local resources for some devs. But not for us, though. At least for temporary created (cache) files. But yea, using 127.0.0.1 instead of localhost solved the connection issues causing an ionic app to freeze when a VPN-Network-Extension is being used.

Adding localhost to the exclusion list for routing (within the VPN profile) may also help (if possible using your current VPN-solution).

alain-sarti commented 6 years ago

A small update: it seems to be impossible to configure the per app vpn to exclude localhost, so that isn't a solution for us.

ck88ger commented 6 years ago

@DanWard thx. It works for me untill tomorrow. Now this is not working anymore.... any suggestions for that?

alain-sarti commented 6 years ago

We also got the information from customers, that it doesn't work, even if we change localhost to 127.0.0.1 ... any ideas?

The mdm being used is mobile iron.

wilk-polarny commented 6 years ago

@ck88ger Which version of the plugin are you running? 1.1.16 works for us, as other issues arise with 1.1.19 and 1.2.0 (#93)

ck88ger commented 6 years ago

@wilk-polarny ive tryed it with 1.1.16 as you mentioned and it still not works... Ive tryed it also with the version 1.1.6. Same Issue with that..

alain-sarti commented 6 years ago

Is there any news on this? We are pretty much out of options right now :/

mlynch commented 6 years ago

Will look into the local IP configuration option this week

GuillaumeDK57 commented 6 years ago

@mlynch : Thanks, we have the same issue, this fix will be appreciated :)

alain-sarti commented 6 years ago

Hey, any news on this front?

menzen commented 6 years ago

Maybe its possible to replace the localhost:8080 to your external IP from VPN at runtime ? I dont know if this is possible.

  1. get the external ip after VPN is startet
  2. go to platforms/ios/.../Plugins/cordova-plugin-ionic-webview/CDVWKWebViewEngine.m and replace

If this is possible to change at runtime, its maybe too late and the first requests to localhost/127.0.0.1 are out in the VPN tunnel

Tankatronic commented 6 years ago

@menzen I'm not sure what the purpose of replacing locahost with the external IP from the VPN would be? You would not be able to load any local resources if you did that, unless I am missing your point?

mlynch commented 6 years ago

Testing something right now to try to fix this. I got side tracked before

mlynch commented 6 years ago

Hi all, just pushed some changes to allow setting 127.0.0.1 as the hostname. To do this, use the WKBind configuration option: https://github.com/ionic-team/cordova-plugin-ionic-webview#bind-hostname

This is not yet released, so can someone help test the version in master to see if this resolves the issue for you? Thanks.

Tankatronic commented 6 years ago

@mlynch I will be working on a new release likely this or next week and could test it out. Is there a beta version I should install? I would love to replace my build scripts with a configuration option.

mlynch commented 6 years ago

@Tankatronic just install directly from the repo cordova plugin add https://github.com/ionic-team/cordova-plugin-ionic-webview

wilk-polarny commented 6 years ago

@mlynch Thanks for the changes. I took a look at the commit you mentioned and noticed that you may have forgotten to edit wk-plugin.js, as injecting normalized URLs using the hardcoded "localhost:8080" will let those calls fail too.

BastiK77 commented 6 years ago

Did anyone fix that? We have now the same issue. App can't connect when using localhost, we switched to 127.0.0.1 but didn't work either. Any ideas or solution's?

wilk-polarny commented 6 years ago

@BastiK77 It seems that 2.0.0 BETA will finally provide a better solution by introducing the WKbind property which allows you to set the bind address.

When using 1.x: Did you patch and reinstall the plugin, or have you simply edited the files mentioned within this issue? Keep in mind that those get overwritten/regenerated within your platform on every ionic build. After using the ionic cli, could you run a search within the platform folder, searching for "localhost:8080"? If you find any occurences within the mentioned files, try to edit them and build again using Xcode or xcodebuild CLI.

AlexKolesnik commented 6 years ago

For me the patch suggested by DanWard works.

jcesarmobile commented 5 years ago

Closing as 4.x no longer uses the local web server, so shouldn't be an issue anymore

wilk-polarny commented 5 years ago

Regarding VMware Airwatch per app VPN, I can confirm that the issue is gone once upgrading to webview 4.x. No local web server, no problems.