'HTTPS POST Request from Java Application to OData-Service in S/4HANA System with valid CSRF-Token

The situation is as follows: On the one side I have created an OData-Service which should create an entry when it receives a POST-Request. The Service is created in an S/4HANA System and is reachable via the SAP-Gateway.

On the other hand I have a Java Application (OpenJDK 11) which does essentially a loop and must issue every loop a POST-Request to the OData-Service.

I'm using IntelliJ IDEA Community Edition and OpenJDK 11. Also this is my first time using OData both with Java and SAP.

At first I tried the following:

private static void postRequest() throws IOException {
        //Setting authenticator needed for login
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, password.toCharArray());
            }
        };
        Authenticator.setDefault(authenticator);
        
        //Creating the connection
        URL url = new URL("<my_service_link>");
        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json; utf-8");
        con.setRequestProperty("Accept", "application/json");
        con.setDoOutput(true);
        try(OutputStream os = con.getOutputStream()) {
            byte[] input = this.getJsonRequest().getBytes("utf-8");
            os.write(input, 0, input.length);
        }

        //Reading response
        int status = con.getResponseCode();

        Reader streamReader = null;

        if (status > 299) {
            streamReader = new InputStreamReader(con.getErrorStream());
        } else {
            streamReader = new InputStreamReader(con.getInputStream());
        }

        BufferedReader in = new BufferedReader(streamReader);
        String inputLine;
        StringBuffer content = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            content.append(inputLine);
        }
        in.close();
        con.disconnect();
        System.out.println(content.toString());
    }

But I got the error, that my CSRF-Token is invalid.

So after googling to find out what an CSRF-Token is I tried to create a GET-Request first with its own HttpsURLConnection:

private static String getRequest() {
        //Setting authenticator needed for login
        Authenticator authenticator = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, password.toCharArray());
            }
        };
        Authenticator.setDefault(authenticator);
        
        //Creating the connection
        URL url = new URL("<my_service_link>");
        HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("Content-Type", "application/json; utf-8");
        con.setRequestProperty("X-CSRF-Token","fetch");
        con.connect();
        return con.getHeaderField("x-csrf-token").toString();
}

Then I would issue the actual POST-Request to the same URL and set the previous X-CSRF-Token into the HTTPS-Header with

con.setRequestProperty("X-CSRF-Token",theGETToken); in postRequest()

But I still got the same error.

What am I doing wrong?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source