Splunk Dev

Java client using REST API getting 400 error

jantona
Engager

I looked at all the CURL and Python examples of using the REST API. I am able to successfully use the CURL command to get a sessionKey. But when I try to emulate this behavior in Java code, I keep getting error 400 "Login Failed".

Here is my Java code that sets up the HTTP Header

public String postPull(String value) {
        String r = null;
        Set<Integer> valid = new HashSet<>();
        valid.add(200);
        valid.add(201);

        TrustStrategy trustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) {
                return true;
            }
        };

        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30 * 1000).setConnectionRequestTimeout(30*1000).setSocketTimeout(30*1000).build();
        CloseableHttpClient httpClient = null;
        try {
            httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setSSLSocketFactory(new SSLConnectionSocketFactory(
                    new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(),
                    hostnameVerifier)).build();

            HttpPost postRequest = new HttpPost(url);
            postRequest.addHeader("Content-Type", contentType);
            postRequest.addHeader("Accept", accept);
            if (this.authorize) {
                String basicAuth = "Splunk " + this.session;
                postRequest.addHeader("Authorization", basicAuth);
            } else {
                String userCredentials = this.user + ":" + this.token;
                String basicAuth = "Basic " + new String(new Base64().encode(userCredentials.getBytes()));
                postRequest.addHeader("Authorization", basicAuth);
            }

            postRequest.setEntity(new StringEntity(value));
            HttpResponse response = httpClient.execute(postRequest);
            if (!valid.contains(response.getStatusLine().getStatusCode())) {
                throw new RuntimeException(String.format("Failed request = %s, error code = %d : %s", url, response.getStatusLine().getStatusCode(), IOUtils.toString(response.getEntity().getContent(),"UTF-8")));
            }
            r = getStringFromInputStream(response.getEntity().getContent());
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                httpClient.close();
            } catch ( Exception ieie) {};
        }
        return r;
    }

and the body that I pass is formatted this way:

public String connect() throws Exception {
        String r = null;
        try {
            HttpInsecureConnector connector = null;
            logger.info("insecure url " + this.surl + "/services/auth/login?output_mode=json");
            connector = new HttpInsecureConnector(this.surl + "/services/auth/login?output_mode=json", 
                        HEADER_CONTENT_TYPE, HEADER_ACCEPT, System.getProperty("splunk.user.name"), this.token);
            StringBuilder mockJson = new StringBuilder();
            mockJson = mockJson.append("{");
                mockJson = mockJson.append("\"username\" : \"" + System.getProperty("splunk.user.name") + "\",");
                mockJson = mockJson.append("\"password\" : \"" + this.token  + "\"");
            mockJson = mockJson.append("}");
            logger.info(mockJson.toString());
//          String pp = "username=" + System.getProperty("splunk.user.name") + "&" + this.token;
            r = connector.postPull(mockJson.toString());
//          r = connector.pull();

        } catch ( Exception e) {
            logger.error(this.surl);
            logger.error(e.getMessage());
            throw e;
        }
        return r;
    }

and this is the output I receive:

12:01:34.502 [main] INFO  metric.Main - Splunk2Wave ETL container starting
12:01:34.505 [main] INFO  metrics.connector.SplunkConnector - insecure url https://xxxxxx-wsl1.internal.salesforce.com:8089/services/auth/login?output_mode=json
12:01:35.286 [main] ERROR metrics.connector.SplunkConnector - https://xxxxx-wsl1.internal.salesforce.com:8089
12:01:35.286 [main] ERROR metrics.connector.SplunkConnector - java.lang.RuntimeException: Failed request = https://pteyer-wsl1.internal.salesforce.com:8089/services/auth/login?output_mode=json, error code = 400 : {"messages":[{"type":"WARN","text":"Login failed"}]}
12:01:35.287 [main] ERROR metric.Main - error java.lang.RuntimeException: Failed request = https://xxxxxxx-wsl1.internal.salesforce.com:8089/services/auth/login?output_mode=json, error code = 400 : {"messages":[{"type":"WARN","text":"Login failed"}]}

Any ideas?

Tags (4)
0 Karma

jantona
Engager

I eventually just settled on making it work with CURL embedded into Java:

public String curlConnect() throws Exception {
        String r = null;
        try {
            List<String> theCommand = new ArrayList<String>();
            theCommand.add("curl");
            theCommand.add("-sk");
            theCommand.add(this.surl + "/services/auth/login?output_mode=json");
            logger.debug(this.surl+ "/services/auth/login?output_mode=json");
            logger.debug("-d username=" + this.user + " password=XXXXXX");
            theCommand.add("-d");
            theCommand.add("username=" + this.user);
            theCommand.add("-d");
            theCommand.add("password=" + this.token);

            ProcessBuilder pb = new ProcessBuilder(theCommand);

            pb.directory(new File(System.getProperty("input.file.path")));
            pb.redirectErrorStream(true);
            Process p = pb.start();
            InputStream is = p.getInputStream();

            r = IOUtils.toString(is);
            r = r.substring(r.indexOf("{\"sessionKey\":\""), r.length());
            JSONObject jsonResponse = new JSONObject(r);
            this.sessionKey = jsonResponse.getString("sessionKey");
            r = this.sessionKey;
            logger.debug(r);

        } catch ( Exception e ) {
            logger.error(this.surl);
            logger.error(e.getMessage());
            throw e;
        }
        return r;
    }

    public String query(String splunkQuery) throws Exception {
        String r = null;
        try {
            List<String> theCommand = new ArrayList<String>();
            theCommand.add("curl");
            theCommand.add("-sku");
            theCommand.add(this.user+":"+this.token);
            //theCommand.add("-H");
            //theCommand.add("\"Authorization: Splunk " + this.sessionKey + "\"");
            theCommand.add(this.surl + "/services/search/jobs?output_mode=json");
            logger.debug(this.surl+ "/services/search/jobs?output_mode=json");
            theCommand.add("-d");
            theCommand.add("search=" + URLEncoder.encode(splunkQuery, "UTF-8"));
            logger.info("search=" + URLEncoder.encode(splunkQuery, "UTF-8"));
            //theCommand.add("-d");
            //theCommand.add("output_mode=json");

            ProcessBuilder pb = new ProcessBuilder(theCommand);

            pb.directory(new File(System.getProperty("input.file.path")));
            pb.redirectErrorStream(true);
            Process p = pb.start();
            InputStream is = p.getInputStream();

            String theResult = IOUtils.toString(is);
            logger.info(theResult);

            theResult = theResult.substring(theResult.indexOf("{\"sid\":\""), theResult.length());
            JSONObject jsonResponse = new JSONObject(theResult);
            r = jsonResponse.getString("sid");

            while ( !resultsReady(r)) {
                logger.info("waiting 30 seconds for async report to finish running sid " + r);
                java.util.concurrent.TimeUnit.SECONDS.sleep(30);
            }
        } catch ( Exception e) {
            logger.error(this.surl);
            logger.error(e.getMessage());
            throw e;
        }
        return r;
    }
0 Karma

marcellodesales
Path Finder

Having the same problem... I can get a curl working to query the REST API... but I get a 400 in Java... Is it related to encoding the request?

0 Karma
Get Updates on the Splunk Community!

Introduction to Splunk Observability Cloud - Building a Resilient Hybrid Cloud

Introduction to Splunk Observability Cloud - Building a Resilient Hybrid Cloud  In today’s fast-paced digital ...

Observability protocols to know about

Observability protocols define the specifications or formats for collecting, encoding, transporting, and ...

Take Your Breath Away with Splunk Risk-Based Alerting (RBA)

WATCH NOW!The Splunk Guide to Risk-Based Alerting is here to empower your SOC like never before. Join Haylee ...