JXBrowser 7.37.0 API 中的证书验证问题

问题描述 投票:0回答:1

我是新来的,有一个问题。

首先介绍一下环境。

我的前同事将 JXBrowser 版本 7.37.0 集成到我们的软件中(= 基于 Java) 为了通过链接建立与文档管理系统 (DMS) 的连接。 DMS 在客户的内联网上运行。 用户使用其 Windows 用户登录 DMS。 DMS 在客户端上安装了所谓的“WEB 客户端”和证书。 这些 WEB 客户端在客户端上启动 Outlook,以便通过电子邮件发送文档。

仅出现应重新加载浏览器的消息。 DMS 已从 http 切换为 https。

现在出现的问题是WEB客户端不再工作,因此无法启动Outlook。

如果有人能为我的问题提供建议,我将非常高兴和感激。

这是我的测试程序的源代码:

package demon;

import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.event.EngineClosed;
import com.teamdev.jxbrowser.engine.event.EngineCrashed;
import com.teamdev.jxbrowser.view.swing.BrowserView;
import com.teamdev.jxbrowser.net.callback.AuthenticateCallback;
import com.teamdev.jxbrowser.net.callback.VerifyCertificateCallback;
import com.teamdev.jxbrowser.net.callback.VerifyCertificateCallback.Response;
import com.teamdev.jxbrowser.net.tls.CertVerificationError;
import com.teamdev.jxbrowser.net.tls.Certificate;
import com.teamdev.jxbrowser.browser.callback.CertificateErrorCallback;
import com.teamdev.jxbrowser.browser.callback.OpenExternalAppCallback;
import com.teamdev.jxbrowser.browser.callback.SelectClientCertificateCallback;

import static com.teamdev.jxbrowser.engine.RenderingMode.HARDWARE_ACCELERATED;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.Properties;

public class JxBrowserApp {

    public static void main(String[] args) {

        // Load settings from App.config
        Properties props = new Properties();

        try (FileInputStream fis = new FileInputStream(Paths.get("config", "App.config").toString())) {

            props.load(fis);

        } catch (IOException e) {

            System.err.println("Error loading App.config: " + e.getMessage());
            System.exit(0);

        }

        String dateDir = Paths.get(System.getProperty("user.dir"), "directory").toString();

        File dir = new File(dateDir);

        if (!(dir.exists() && dir.isDirectory())) {

            try {
                Files.createDirectories(Paths.get(dateDir));
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {

            deleteDirectory(dateDir);

        }

        String userDataDir = Paths.get(dateDir, "user").toString() + System.getProperty("file.separator");
        String chromiumDir = Paths.get(dateDir, "chromium").toString() + System.getProperty("file.separator");
        String crashDumpDir = Paths.get(dateDir, "CrashReports").toString() + System.getProperty("file.separator");

        dir = new File(userDataDir);

        if (!(dir.exists() && dir.isDirectory())) {

            try {
                Files.createDirectories(Paths.get(userDataDir));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        dir = new File(chromiumDir);

        if (!(dir.exists() && dir.isDirectory())) {

            try {
                Files.createDirectories(Paths.get(chromiumDir));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        dir = new File(crashDumpDir);

        if (!(dir.exists() && dir.isDirectory())) {

            try {
                Files.createDirectories(Paths.get(crashDumpDir));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.setProperty("jxbrowser.crash.dump.dir", crashDumpDir);

        String url = "https://dmssrv";

        boolean devTools = (props.getProperty("devTools", "false").toLowerCase().equals("true") ? true : false);

        String authenticateUsername = props.getProperty("authenticateUsername", "");
        String authenticatePassword = props.getProperty("authenticatePassword", "");

        // Initialize Chromium.
        EngineOptions options = null;

        options = EngineOptions.newBuilder(HARDWARE_ACCELERATED)
                               .treatInsecureOriginAsSecure("https://dmsrv")
                               .userDataDir(Paths.get(userDataDir))
                               .chromiumDir(Paths.get(chromiumDir))
                               .build();

        Engine engine = Engine.newInstance(options);

        engine.network().httpAuthPreferences().serverWhitelist("dmssrv");

        engine.network().httpAuthPreferences().delegateWhitelist("dmssrv");

        engine.on(EngineClosed.class, event -> {
            System.out.println("CLOSE ENGINE\n");
        });

        engine.on(EngineCrashed.class, event -> {
            System.out.println("CRASHED ENGINE: ExitCode = " + event.exitCode() + "\n");
        });

        // Create a Browser instance.
        Browser browser = engine.newBrowser();

        // Allows JavaScript code on the web pages loaded in the browser to
        // access clipboard.
        browser.settings().allowJavaScriptAccessClipboard();

        // Allows JavaScript code on the web pages loaded in the browser to
        // read/write cookies in the cookies storage using the document.cookie
        // property.
        browser.settings().allowJavaScriptAccessCookies();

        // Allows running an insecure content in the browser.
        browser.settings().allowRunningInsecureContent();

        // Enables the local storage in the browser.
        browser.settings().enableLocalStorage();

        // Enables all plugins on the web pages loaded in the browser.
        browser.settings().enablePlugins();

        // Enables JavaScript on the web pages loaded in the browser.
        browser.settings().enableJavaScript();

        browser.set(OpenExternalAppCallback.class, (param, tell) -> {

            System.out.println("ExternalApp.title: " + param.title());
            System.out.println("ExternalApp.message: " + param.message());
            tell.open();
        });

        engine.network().set(AuthenticateCallback.class, (param, tell) -> {

            System.out.println("AuthenticateCallback.browser: " + param.browser());
            System.out.println("AuthenticateCallback.hostPort: " + param.hostPort());
            System.out.println("AuthenticateCallback.isProxy: " + param.isProxy());
            System.out.println("AuthenticateCallback.url: " + param.url());
            System.out.println("AuthenticateCallback.scheme: " + param.scheme());

            if (authenticateUsername.toLowerCase().equals("none") &&
                authenticatePassword.toLowerCase().equals("none")) {
                
            } else if (authenticateUsername.equals("") && authenticatePassword.equals("")) {
                tell.authenticate("<username>", "<password>");
            } else {
                tell.authenticate(authenticateUsername, authenticatePassword);
            }
        });

        browser.set(SelectClientCertificateCallback.class, (params, tell) -> {

            String host = params.hostPort().toString();
            System.out.println("useSystemCertificateStore for " + host + "...");

            // The list of the installed and available client certificates.
            java.util.List<Certificate> certificates = params.certificates();

            certificates.forEach(e -> {
                System.out.println("useSystemCertificateStore:\n" + e);
            });

            // Select the all client certificate in the list of available
            // client certificates.
            tell.select(certificates.size());

        });

        browser.settings().disallowJavaScriptAccessCookies();

        // Load the required web page.
        //browser.navigation().loadUrlAndWait(url);
        browser.navigation().loadUrl(url);

        if (devTools) {
            System.out.println("devTools: eingestellt\n");
            browser.devTools().show();
        } else {
            System.out.println("devTools: nicht eingestellt\n");
        }

        engine.network().set(VerifyCertificateCallback.class, params -> {

            String host = params.host().value();
            System.out.println("VerifyCertificateCallback: Verifying certificate for " + host);
            System.out.println("VerifyCertificateCallback.certificate = " + params.certificate());
            System.out.println("VerifyCertificateCallback.host = " + params.host());
            System.out.println("VerifyCertificateCallback.intermediateCertificates = " + params.intermediateCertificates());

            // SSL Certificate to verify.
            Certificate certificates = params.certificate();

            // The results of the verification performed by default verifier.
            java.util.List<Certificate> certs = params.intermediateCertificates();

            for (Certificate cert : certs) {
                System.out.println("IntermediateCertificates: " + cert);
            }

            // The results of the verification performed by default verifier.
            java.util.List<CertVerificationError> errors = params.verificationErrors();

            for (CertVerificationError error : errors) {
                System.out.println("VerifyCertificateCallback (Error): " + host);
                System.out.println("Status = " + error.status());
                System.out.println("Short Description = " + error.shortDescription());
                System.out.println("Detailed Description = " + error.detailedDescription());
            }

            return Response.valid();
        });

        browser.set(CertificateErrorCallback.class, (params, tell) -> {

            System.out.println("CertificateErrorCallback.url = " + params.url());
            System.out.println("CertificateErrorCallback.error = " + params.error());
            System.out.println("CertificateErrorCallback.isMainFrame = " + params.isMainFrame());
            System.out.println("CertificateErrorCallback.certificate = " + params.certificate());
            tell.allow();
        });

        SwingUtilities.invokeLater(() -> {

            JFrame frame = new JFrame("JxBrowser AWT/Swing");

            frame.addWindowListener(new WindowAdapter() {

                @Override
                public void windowClosing(WindowEvent e) {

                    // Shutdown Chromium and release allocated resources.
                    engine.close();
                    System.exit(0);

                }

            });

            // Create and embed Swing BrowserView component to display web content.
            frame.add(BrowserView.newInstance(browser), BorderLayout.CENTER);
            frame.setSize(1280, 800);
            frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
            frame.setUndecorated(false);
            frame.setVisible(true);

        });

    }

    public static void deleteDirectory(String directoryPath) {

        Path path = Paths.get(directoryPath);

        try {

            Files.walk(path)
                 .sorted(Comparator.reverseOrder())
                 .map(Path::toFile)
                 .forEach(File::delete);

        } catch (IOException ex) {

            ex.printStackTrace();

        }

    }

}

在网上研究之后,我发现了一些东西并将它们实现在测试程序中,以便我和客户可以事先测试它们。

我已经实现了以下方法:

  • 验证证书回调
  • 证书错误回调
  • 禁止JavaScriptAccessCookies
  • 选择客户端证书回调
  • 验证回调
  • 打开外部应用程序回调
  • 启用插件
  • 启用JavaScript
  • 启用本地存储
  • 允许运行不安全内容
  • 允许JavaScriptAccessCookies
  • 允许JavaScriptAccessClipboard

测试时发现VerifyCertificateCallback一直执行,无法验证DMS服务器证书。

certificate jxbrowser
1个回答
0
投票

每次 Chromium 决定检查 TLS 证书的有效性时都会执行

VerifyCertificateCallback
。通过返回
Reponse.valid()
,您告诉 Chromium 一切正常,因此这不是网站无法运行的原因。

仅出现应重新加载浏览器的消息。

不是 JxBrowser 就错误和异常情况进行通信的方式。所以我断定这是来自服务器的响应。如果是这样,这看起来有点像机器人保护措施。

我建议咨询 DMS 开发人员,了解他们对用户代理的要求。您还可以联系 JxBrowser 支持。

© www.soinside.com 2019 - 2024. All rights reserved.