javajavafxdiscordjavafx-webenginediscord-jda

Discord OAuth2 redirect url fails to display with JavaFX WebView JDK12


I am trying to get the following site: link to discord OAuth2 URL (hover me to see link) to load with JavaFX WebView in JDK12. When I try loading that site, all that is shown is a white page. The following code is what is used to display, and handle the WebView. I am using the library OAuth2Discord to handle the code and authorization.

DiscordAuth.java:
DiscordAuth()

This method initializes the OAuthBuilder used in the rest of the code below.

public DiscordAuth() {
        CLIENT_SECRET = [REDACTED];
        CLIENT_ID = [REDACTED];
        REDIRECT_URL = "https://temperlesergal.github.io/NuBot/discordWebPage/success.html";
         builder = new OAuthBuilder(CLIENT_ID, CLIENT_SECRET)
                .setScopes(new String[]{"connections", "guilds", "email"})
                .setRedirectURI(REDIRECT_URL);
    }


getUser(WebView webView, Thread thread)

This is meant to start the process of retrieving the code applied to the URL when redirected from the Auth url.

public void getUser(WebView webView, Thread thread) {
    startOAuth2Flow(webView, thread);
}


startOAuth2Flow(WebView webView, Thread thread)

This method handles the site redirection as well as breaking up the URL to retrieve the code.
P.S. https://temperlesergal.github.io/NuBot/discordWebPage/index.html redirects to the Auth URL listed above

private void startOAuth2Flow(WebView webView, Thread thread) {
    String authURL = builder.getAuthorizationUrl(null);
    WebEngine webEngine = webView.getEngine();
    webEngine.setJavaScriptEnabled(true);
    webEngine.setUserAgent("Cotton Le Sergal's OAuth2 grant for app.");
    webEngine.getLoadWorker().stateProperty().addListener(
        (ov, oldState, newState) -> {
            if (webEngine.getLoadWorker().getException() != null || newState == Worker.State.FAILED){
                System.err.println(webEngine.getLoadWorker().getException().toString());
            }else{
                System.out.println(webEngine.getLoadWorker().getState());
            }
        });
        webEngine.locationProperty().addListener((observableValue, oldLocation, newLocation) -> {
        System.out.println("newLocation = " + newLocation);
        if (newLocation.startsWith(REDIRECT_URL) && newLocation.contains("code")) {
            try {
                URL url = new URL(newLocation);
                String[] params = url.getQuery().split("&");
                Map<String, String> map = new HashMap<>();
                for (String param : params) {
                    String name = param.split("=")[0];
                    String value = param.split("=")[1];
                    map.put(name, value);
                }
                code = map.get("code");
                gotTheAccessCode(code, thread);
                System.out.println("Notifying thread");
                synchronized (thread){
                    thread.notify();
                    thread.start();
                    System.out.println("Thread Notified!");
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }
    });
    String url = "https://temperlesergal.github.io/NuBot/discordWebPage/index.html";
    webEngine.load(url);
}


gotTheAccessCode(String code, Thread thread)

This method exchanges the code and initializes the following:
-builder.getUser();
-builder.getGuilds();
-builder.getConnections()

private void gotTheAccessCode(String code, Thread thread) {
    System.out.println("access code: " + code);
    Response response = builder.exchange(code);
    if (response == Response.ERROR) {
        // AN ERROR HAPPENED WHILE EXCHANGING THE CODE
    } else {
        // EVERYTHING WORKED AS EXPECTED
    }
    System.out.println("Testing by printing guild info!");
    getGuildInfo().forEach(guild -> System.out.println(guild.getName()));
    System.out.println("DONE!");
    user =  builder.getUser();
    guilds = builder.getGuilds();
    connections = builder.getConnections();
}

FXMLController.java:
signIn()

This method is what is triggered when the user presses login button on the FXML scene. It is meant to allow them to sign in to discord through the JavaFX application.

@FXML
void signIn(){
    Thread thread = new Thread(() -> {
        System.out.println("Thread waking up!");
        Platform.runLater(() -> {
            usernameLabel.setText(discordAuth.getUserNameWithDiscriminator());
            setUserAvatar(discordAuth.getUserAvatarURL());
        });
    });
    try {
        if(thread.isAlive())
            thread.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    discordSigninWebView.setVisible(true);
    discordSigninWebView.setOpacity(0.0);
    FadeIn signInFade = new FadeIn(discordSigninWebView);
    signInFade.play();
    discordAuth.getUser(discordSigninWebView, thread);
}


This is what I see when I load into the app:
Bot:
URL: No URL loaded into WebEngine
Description: This is the default look when running the Application. This is the default look when running the Application URL: https://temperlesergal.github.io/NuBot/discordWebPage/index.html
Description: This is what the WebView looks like when I click log out (Which should be login, just forgot to change it). [This is what it looks like when it loads my url.[2] URL: https://discordapp.com/oauth2/authorize?client_id=569662931990478857&redirect_uri=https%3A%2F%2Ftemperlesergal.github.io%2FNuBot%2FdiscordWebPage%2Fsuccess.html&response_type=code&scope=identify%20email%20connections%20guilds
Description: This is the white screen it displays after pressing: "Authorize". This is the white screen it displays after pressing: "Authorize"

This is what I see when I load into Chrome:
Web:
URL: https://discordapp.com/oauth2/authorize?client_id=569662931990478857&redirect_uri=https%3A%2F%2Ftemperlesergal.github.io%2FNuBot%2FdiscordWebPage%2Fsuccess.html&response_type=code&scope=identify%20email%20connections%20guilds
Description: This is what the bot should display. enter image description here

This is the information printed to the console

Image size is: 800.0x800.0 with the width being the largest at: 800.0px.
Image is 8.0 times the size it should be... resizing
Image has been resized to the following: 100.0x100.0px.
Actual image size is: 100.0x100.0px.
Test
0    [OkHttp https://discordapp.com/...] DEBUG net.dv8tion.jda.internal.requests.Requester  - Received response with following cf-rays: [5176ddc69aaae202-ORD]
317  [OkHttp https://discordapp.com/...] DEBUG net.dv8tion.jda.internal.requests.Requester  - Received response with following cf-rays: [5176ddc83f13e202-ORD]
320  [Thread-3] INFO  net.dv8tion.jda.api.JDA  - Login Successful!
[0 / 3]
578  [OkHttp https://discordapp.com/...] DEBUG net.dv8tion.jda.internal.requests.Requester  - Received response with following cf-rays: [5176ddca3e3ac510-ORD]
Host Name: [REDACTED]
Host Address: [REDACTED]
693  [JDA [0 / 3] MainWS-ReadThread] INFO  net.dv8tion.jda.internal.requests.WebSocketClient  - Connected to WebSocket
693  [JDA [0 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Sending Identify-packet...
734  [JDA [0 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Got HELLO packet (OP 10). Initializing keep-alive.
754  [OkHttp https://discordapp.com/...] DEBUG net.dv8tion.jda.internal.requests.Requester  - Received response with following cf-rays: [5176ddcaaf3dc510-ORD]
754  [Thread-3] INFO  net.dv8tion.jda.api.JDA  - Login Successful!
[1 / 3]
832  [JDA [0 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.handle.GuildSetupController  - Setting incomplete count to 0
832  [JDA [0 / 3] MainWS-ReadThread] INFO  net.dv8tion.jda.api.JDA  - Finished Loading!
Shard: 1 out of: 3 is ready.
842  [JDA [0 / 3] Gateway-Worker 1] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Sending normal message {"op":3,"d":{"game":{"name":"Type owo.help","type":0},"afk":false,"status":"online","since":1568679123052}}
883  [OkHttp https://discordapp.com/...] DEBUG net.dv8tion.jda.internal.requests.Requester  - Received response with following cf-rays: [5176ddcc2a44c56c-ORD]
998  [OkHttp https://discordapp.com/...] DEBUG net.dv8tion.jda.internal.requests.Requester  - Received response with following cf-rays: [5176ddccab8dc56c-ORD]
998  [Thread-3] INFO  net.dv8tion.jda.api.JDA  - Login Successful!
[2 / 3]
5952 [JDA [1 / 3] MainWS-ReadThread] INFO  net.dv8tion.jda.internal.requests.WebSocketClient  - Connected to WebSocket
5953 [JDA [1 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Sending Identify-packet...
5955 [JDA [1 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Got HELLO packet (OP 10). Initializing keep-alive.
6047 [JDA [1 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.handle.GuildSetupController  - Setting incomplete count to 1
6082 [JDA [1 / 3] MainWS-ReadThread] INFO  net.dv8tion.jda.api.JDA  - Finished Loading!
Shard: 2 out of: 3 is ready.
6084 [JDA [1 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.handle.GuildSetupController  - Finished setup for guild 530802775530012672 firing cached events 0
6246 [JDA [1 / 3] Gateway-Worker 1] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Sending normal message {"op":3,"d":{"game":{"name":"Type owo.help","type":0},"afk":false,"status":"online","since":1568679128295}}
11239 [JDA [2 / 3] MainWS-WriteThread] INFO  net.dv8tion.jda.internal.requests.WebSocketClient  - Connected to WebSocket
11240 [JDA [2 / 3] MainWS-WriteThread] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Sending Identify-packet...
11241 [JDA [2 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Got HELLO packet (OP 10). Initializing keep-alive.
11368 [JDA [2 / 3] MainWS-ReadThread] DEBUG net.dv8tion.jda.internal.handle.GuildSetupController  - Setting incomplete count to 0
11368 [JDA [2 / 3] MainWS-ReadThread] INFO  net.dv8tion.jda.api.JDA  - Finished Loading!
Shard: 3 out of: 3 is ready.
11504 [JDA [2 / 3] Gateway-Worker 1] DEBUG net.dv8tion.jda.internal.requests.WebSocketClient  - Sending normal message {"op":3,"d":{"game":{"name":"Type owo.help","type":0},"afk":false,"status":"online","since":1568679133581}}
newLocation = https://temperlesergal.github.io/NuBot/discordWebPage/index.html
SCHEDULED
RUNNING
SUCCEEDED
newLocation = https://discordapp.com/api/oauth2/authorize?client_id=569662931990478857&redirect_uri=https%3A%2F%2Ftemperlesergal.github.io%2FNuBot%2FdiscordWebPage%2Fsuccess.html&response_type=code&scope=identify%20email%20connections%20guilds
SCHEDULED
RUNNING
newLocation = https://discordapp.com/oauth2/authorize?client_id=569662931990478857&redirect_uri=https%3A%2F%2Ftemperlesergal.github.io%2FNuBot%2FdiscordWebPage%2Fsuccess.html&response_type=code&scope=identify%20email%20connections%20guilds
SUCCEEDED


Reproducibility: 100%
Simply trying to load the Auth url in a WebView will cause this issue.
Any and all thoughts upon this matter will be greatly appreciated, thank you.


Solution

  • I have found the issue to be that [WebView Sub-resource integrity check fails on Windows and Linux.

    This can be seen and proven here in the following links:

    1. https://bugs.openjdk.java.net/browse/JDK-8219917
    2. https://github.com/javafxports/openjdk-jfx/issues/230

    How to fix the issue at hand

        Please view link no.1 for more in depth details
    

    In short, the issue was that OpenJDK 12 for JavaFX had a bug that failed sub-resource integrity checks on Windows and Linux platforms that caused an issue when it did not provide a cryptographic hash that matched the hash from the fetched resource. As such, the content of the web page would not be displayed properly. The way to solve it is listed in link no.1. The bug is patched in JavaFX 13, so all that was needed to solve this issue was to update the JavaFX modules in my maven pom file.