首页 > 解决方案 > Java 8 - 下载需要通过 HTTPS 进行身份验证的文件时遇到问题。在卷曲中工作正常

问题描述

我是我工作的这家小公司的唯一开发人员。我继承了很多遗留代码。与此问题相关的代码在带有 SpringBoot 的 Java 8 中。

我们从最近更新的一个实体中获取重要数据,它如何使用 REST API 提供数据。REST API 只能通过 HTTPS 访问,并且需要有效的用户名和密码。该实体以多种编码语言提供了有关如何使用其新 API 的示例代码。他们推荐curl作为下载数据的默认方法,但提供了 Java 8 中的示例。我可以使用我的凭据和curl*NIX 中的命令成功下载文件。我无法使用 Java 下载文件。我有理由确定代码在身份验证级别失败。我发现这个 StackOverflow 帖子表明它可能是 TLS 版本的问题,但我无法让它工作。

我的老板出于“安全原因”禁止我发布该实体的文件,即使文件是公开的。同样,我必须稍微掩盖一下我的代码。我将尽我所能将更改降至最低。

这是有效的两部分curl命令:

首先获取令牌:

 curl --request POST --header "X-OpenAM-Username: username" --header "X-OpenAM-password: password" --header "Content-Type:application/json" --data "{}" https://sso.entityname.com/access/authenticate

我得到一个包含令牌的 JSON。按照实体的示例代码,我在下一个curl命令中传递令牌,然后我成功获取文件:

curl --request GET --header "Cookie: entityauth=longgibberishstringofencryptioncharaters" --header Content-Type:text/csv "https://entityname.com/rest/secure/download/reports?shortName=awesomereport&version=L&format=C&start=01/01/2018&stop=01/15/2018"

现在这是我的 Java 代码。这几乎直接从实体提供的文档中复制而来。代码编译和运行没有问题,但每次它只是创建一个名为“testOuput.txt”的空文件。

   public static void downloadReport() throws IOException {
        String webUrl = "https://entityname.com/rest/secure/download/reports?shortName=awesomereport&version=L&format=C&start=01/01/2018&stop=01/15/2018";
        URL url = new URL(webUrl);
        String username = "username";
        String password = "password";
        String authString = username + ":" + password;
        String basicAuth = "Basic " + javax.xml.bind.DatatypeConverter.printBase64Binary(authString.getBytes());
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setRequestProperty("Authorization", basicAuth);
        InputStream inputStream = urlConnection.getInputStream();
        try {
            OutputStream out = new FileOutputStream("testOutput.txt");
            byte[] buf = new byte[1024];
            int len;
            while ((len = inputStream.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.close();
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

我也尝试过curl使用该类简单地将 Java 包装在 shell 命令周围Process,但无济于事。下面是我的尝试。再次,它编译并成功运行,但每次都会创建一个名为“testOuput.txt”的空文件。

    public static void downloadReportWithCurl() throws IOException {
        String authentication = "curl --request POST --header X-OpenAM-Username: username --header X-OpenAM-password: password --header Content-Type:application/json --data {} https://sso.entityname.com/access/authenticate";
        ProcessBuilder processBuilder = new ProcessBuilder(authentication.split(" "));
        Process process = processBuilder.start();
        InputStream inputStream = process.getInputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> jsonMap = objectMapper.readValue(inputStream, Map.class);
        String authToken = jsonMap.get("authId").toString().replace(".", ".*") + ".*";
        String authHeader = "Cookie: entityauth=" + authToken;
        System.out.println(authHeader);
        String downloadCommand = "curl --request GET --header "Cookie: entityauth=longgibberishstringofencryptioncharaters" --header Content-Type:text/csv "https://entityname.com/rest/secure/download/reports?shortName=awesomereport&version=L&format=C&start=01/01/2018&stop=01/15/2018"
        System.out.println(downloadCommand);
        ProcessBuilder processBuilder2 = new ProcessBuilder(downloadCommand.split(" "));
        Process process2 = processBuilder2.start();
        InputStream dataStream = process2.getInputStream();
        try {
            OutputStream out = new FileOutputStream("testOutput.txt");
            byte[] buf = new byte[1024];
            int len;
            while ((len = dataStream.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.close();
            dataStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

如果有人能帮我解决这个问题,我将不胜感激。

标签: javacurlhttps

解决方案


推荐阅读