`Failed integrity metadata check.` in JavaFX WebVi

2019-08-09 22:54发布

问题:

I am trying to open a webview to Microsoft's auth v2. Loads fine in a browser, but in JavaFX's WebView (JDK 8) the page is blank. Once I turned on console output, I see many lines such as for both CSS and JS.

[null:0] Cannot load stylesheet https://secure.aadcdn.microsoftonline-p.com/ests/2.1.8148.16/content/cdnbundles/converged.v2.login.min_t7iocdq0wq2qh0nv233jig2.css. Failed integrity metadata check.

I am relatively sure that the issue is with CORS (I am loading microsoftonline.com and the resources are on microsoftonline-p.com). I've tried every possible fix that I can think of, or find online.

I have tried setting all of these

engine.setJavaScriptEnabled(true)

engine.setUserAgent("AppleWebKit/537.44")

System.setProperty("sun.net.http.allowRestrictedHeaders", "true")

I've also set the Property via -Dsun.net.http.allowRestrictedHeaders=true in VMOptions ( as seen here ) and from the JavaFX issue JDK-8096797

The property shows up as set:

println(System.getProperty("sun.net.http.allowRestrictedHeaders"))

yields true on the console printout.

Still no change, ever in the page output, it is always a white, blank screen, and the same errors from the web console.

I think I found the trouble lines in WebKit(see matchIntegrityMetadata) even, but that didn't help me solve the problem any, because I don't know how to disable the integrityCheck.

This really, really has me stumped. Any help is very appreciated.

For reference, here is the entire method:

private fun WebView.authWindow(provider: Oath2Account){
    engine.setUserAgent("AppleWebKit/537.44")
    engine.setJavaScriptEnabled(true)
    URLPermission("https://*.com")
    System.setProperty("sun.net.http.allowRestrictedHeaders", "true")

    Platform.runLater {
        engine.userDataDirectory = File("C:\\users\\eric\\javafx_tmp")
        engine.setOnError { println("IN PAGE ERROR --> $it") }
        engine.setOnAlert { println("IN PAGE ALERT --> $it") }
        engine.setConfirmHandler { println("IN PAGE CONFIRM HANDLER --> $it")
        true
        }
        engine.setCreatePopupHandler { println("IN PAGE POPUP --> $it")
        engine}
        engine.setOnResized {   println("IN PAGE RESIZED --> $it") }
        engine.setOnStatusChanged {   println("IN PAGE STATUS CHANGED --> $it")
            println("\t${it.data}")
            println("\t${it.source}")
            println("\t${it.eventType}")
            println("\t${it.target}")
            println("\t${it.isConsumed}")

        }
        engine.setOnVisibilityChanged { println("IN PAGE VISIBILITY CHANGED --> $it") }
        engine.setPromptHandler { println("IN PAGE PROMPTED --> $it")
        "HELLO"}
        println("JavaScript engine status: ${engine.isJavaScriptEnabled}")

        println("engine is loading $loadURL")
        engine.locationProperty().addListener { observable, oldLocation, newLocation->
            println("observable=$observable\noldLocation=$oldLocation\nnewLocation=$newLocation")
            //          if (newLocation.startsWith("urn:ietf:wg:oauth:2.0:oob")) {
            //              val code:get
            //              val title:from
            //              val accessToken = service.getAccessToken(verifier)
            //              doSomething(accessToken.getAccessToken())
            //          }
        }
        com.sun.javafx.webkit.WebConsoleListener.setDefaultListener { webview, message, lineNumber, sourceId -> println("Console: [$sourceId:$lineNumber] $message") }
        engine.setOnError({ event -> System.out.println(event.getMessage()) })
        try{
        engine.load(loadURL )
    } catch (e: IOException) {
        println("caught error:")
        e.printStackTrace();
    }
}

回答1:

This confirms my answer at:Javafx - open login.microsoftonline.com page in webview component

The critical point is external script/link integrity fails. This is not a platform browser issue, JavaFX (OpenJFK) relies on an embedded webkit engine.

The regression happened between version 40 and version 172 on windows JDK 8. It's working fine with Oracle JDK 9.0.4 It's not working with Oracle JDK 11

More details at: https://github.com/mguessan/davmail/issues/12

=> Update: issue confirmed by OpenJFX team on Windows and Linux, see: https://github.com/javafxports/openjdk-jfx/issues/230 and [WebView] Sub-resource integrity check fails on Windows and Linux https://bugs.openjdk.java.net/browse/JDK-8219917

=> Updated answer: implemented to override Microsoft form content and disable integrity check. This is not a fix of the webkit bug, just a workaround

try {
    URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory() {
        @Override
        public URLStreamHandler createURLStreamHandler(String protocol) {
            if ("https".equals(protocol)) {
                return new sun.net.www.protocol.https.Handler() {
                    @Override
                    protected URLConnection openConnection(URL url, Proxy proxy) throws IOException {
                        System.out.println("openConnection " + url);

                        if (url.toExternalForm().endsWith("/common/handlers/watson")) {
                            System.out.println("Failed: form calls watson");
                        }
                        final HttpsURLConnectionImpl httpsURLConnection = (HttpsURLConnectionImpl) super.openConnection(url, proxy);
                        if ("login.microsoftonline.com".equals(url.getHost())
                                && "/common/oauth2/authorize".equals(url.getPath())) {

                            return new URLConnection(url) {
                                @Override
                                public void connect() throws IOException {
                                    httpsURLConnection.connect();
                                }

                                public InputStream getInputStream() throws IOException {
                                    byte[] content = readFully(httpsURLConnection.getInputStream());
                                    String contentAsString = new String(content, "UTF-8");
                                    System.out.println(contentAsString);
                                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                    baos.write(contentAsString.replaceAll("integrity", "integrity.disabled").getBytes("UTF-8"));
                                    return new ByteArrayInputStream(baos.toByteArray());
                                }

                                public OutputStream getOutputStream() throws IOException {
                                    return httpsURLConnection.getOutputStream();
                                }

                            };

                        } else {
                            return httpsURLConnection;
                        }
                    }

                };
            }
            return null;
        }
    });
} catch (Throwable t) {
    System.out.println("Unable to register custom protocol handler");
}


回答2:

I found out that web view is using webkit engine for mac os/ linux os and IE engine for windows machines. I have similar issue Javafx - open login.microsoftonline.com page in webview component. WebView on mac os is working fine but there is problem on windows machines. When I was investigating this issue I find out that there is problem in this IE engine. I have access to few machines with different version of IE 11 installed on. On machines with update version 11.0.85 I wasn't able to open this site, but when I tried on machine with update version 11.0.90 the problem doesn't exist anymore. So if you are using Windows OS please try to update IE version maybe it will solve your problem.