Skip to main content
17-Peridot
July 11, 2020
Solved

POST request_OData REST API

  • July 11, 2020
  • 1 reply
  • 7211 views

Hello everyone!


I try to execute a post request, but get this error:

{"error":
 {"code":
 "INVALID_NONCE","message":"A potential security problem was detected. Refresh the 
 page and try again. If the problem persists, contact your administrator."
 }
}

I found this article:

https://www.ptc.com/en/support/article/CS312447

It says that a token is needed, but I already added it and still does not work.

Here is the request that I execute to get the token:

http://server/Windchill/servlet/odata/PTC/GetCSRFToken()

Here is my code for the post request:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import org.apache.http.HttpEntity;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

public class Post {
	public static void main(String[] args) {
		try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
			HttpPost httpPost = new HttpPost("http://server/Windchill/servlet/odata/ProdMgmt/Parts");
			
			String json = "{\r\n" + 
					"\"Name\":\"TestWTPart_001\",\r\n" + 
					"\"AssemblyMode\": {\r\n" + 
					"\"Value\": \"separable\",\r\n" + 
					"\"Display\": \"Separable\"\r\n" + 
					"},\r\n" +
					"\"GatheringPart\" : false,\r\n" +
					"\"PhantomManufacturingPart\" : false,\r\n" + 
					"\"Context@odata.bind\": \"Containers('OR:wt.pdmlink.PDMLinkProduct:48507000')\",\r\n" + 
					"\"DefaultUnit\":\"kg\",\r\n" + 
					"\"DefaultTraceCode\":\"X\",\r\n" + 
					"\"Source\":\"buy\"\r\n" + 	 
					"}";
			StringEntity jsonEntity = new StringEntity(json);
			httpPost.setEntity(jsonEntity);
			
			UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("wcadmin", "123");
			
			httpPost.setHeader(new BasicScheme().authenticate(credentials, httpPost, null));
			httpPost.setHeader("Content-Type", "application/json");
			httpPost.setHeader("CSRF_NONCE",
					"MY-TOKEN");
			
			CloseableHttpResponse response = httpClient.execute(httpPost);
			HttpEntity entity = response.getEntity();
			
			if (entity != null) {
				try (InputStream stream = entity.getContent()) {
					StringBuilder textBuilder = new StringBuilder();
				 try (Reader reader = new BufferedReader(new InputStreamReader
				 (stream, Charset.forName(StandardCharsets.UTF_8.name())))) {
				 int c = 0;
				 while ((c = reader.read()) != -1) {
				 textBuilder.append((char) c);
				 }
				 }
					System.out.println(textBuilder);
				}
			}
			System.out.println("\n" + response.getStatusLine().getStatusCode());
			
			response.close();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (AuthenticationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 

Tell me, please, what am I doing wrong?
Thank you in advance!

Best Regards!

Best answer by hlafkir

ok thank you for this light.

 

Can you try that please (working fine for me). Just replace the user-agent and the PDMLinkProduct oid with your one. You will then see what is going wrong with your code :

 

private void sendPost() throws Exception {
 
 String url = "http://pdm10.de/Windchill/servlet/odata/ProdMgmt/Parts";
 
 HttpClient client = HttpClientBuilder.create().build();
 HttpPost post = new HttpPost(url);
 
 // add header
 post.setHeader("User-Agent", USER_AGENT);
 BASE64Encoder enc = new sun.misc.BASE64Encoder();
 String username="wcadmin";
 String password="ts";
 String userpassword = username + ":" + password;
 String encodedAuthorization = enc.encode( userpassword.getBytes() );
 
 
 JSONObject json = new JSONObject();
 json.put("Name", "TestWTPartFromOdata");
 json.put("PhantomManufacturingPart" , false);
 //"GatheringPart": false,
 json.put("GatheringPart", false);
 
 HashMap<String, String> am_map = new HashMap<String, String>(); 
 am_map.put("Value", "separable");
 am_map.put("Display", "Separable" );
 json.put("AssemblyMode", am_map);
 
 
 HashMap<String, String> df_map = new HashMap<String, String>(); 
 df_map.put("Value", "ea");
 df_map.put("Display", "Each" );
 json.put("DefaultUnit", df_map);
 
 HashMap<String, String> dtc_map = new HashMap<String, String>(); 
 dtc_map.put("Value", "0");
 dtc_map.put("Display", "Untraced" );
 json.put("DefaultTraceCode", dtc_map);
 
 HashMap<String, String> src_map = new HashMap<String, String>(); 
 src_map.put("Value", "make");
 src_map.put("Display", "Make" );
 json.put("Source", src_map);
 
 
 HashMap<String, String> cfm_map = new HashMap<String, String>(); 
 cfm_map.put("Value", "standard");
 cfm_map.put("Display", "Standard" );
 json.put("ConfigurableModule", cfm_map);
 
 json.put("EndItem" , false);
 json.put("Context@odata.bind", "Containers('OR:wt.pdmlink.PDMLinkProduct:64091')");
 StringEntity params = new StringEntity(json.toString());
 
 
 
 
 /*
 * {
 "Name": "Part_P036",
 "AssemblyMode": {
 "Value": "separable",
 "Display": "Separable"
 },
 "EndItem" : false,
 "DefaultUnit": {
 "Value": "ea",
 "Display": "Each"
 },
 "DefaultTraceCode": { 
 "Value": "0",
 "Display": "Untraced"
 },
 "Source": { 
 "Value": "make",
 "Display": "Make"
 },
 "ConfigurableModule": {
 "Value" : "standard",
 "Display" : "Standard"
 },
 "GatheringPart": false,
 "PhantomManufacturingPart": false,
 "Context@odata.bind": "Containers('OR:wt.pdmlink.PDMLinkProduct:64091')"
 
}
 
 * 
 */
 
 
 
 
 
 
 
 post.addHeader( "Authorization", "Basic "+ encodedAuthorization);
 //post.addHeader("Accept", "application/json");
 post.addHeader("Content-Type", "application/json");
 post.addHeader("Accept","application/json");
 post.addHeader("CSRF_NONCE","ypTCuzcDl4rmuSC3jMyM71JH+8+sgGbbnN6j1lJp29rV90TG/ces9FtN38Kc4FTZiPr08k5g2rfciBWO+qT1ig43pbvSjhr5ruy41FV2/9uUzRTvha2t/XhVouSRhB0=");
 post.setEntity(params);
 
 
 HttpResponse response = client.execute(post);
 System.out.println("\nSending 'POST' request to URL : " + url);
 System.out.println("Post parameters : " + post.getEntity());
 System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
 
 BufferedReader rd = new BufferedReader( new InputStreamReader(response.getEntity().getContent()));
 
 StringBuffer result = new StringBuffer();
 String line = "";
 while ((line = rd.readLine()) != null) {
 result.append(line);
 }
 
 System.out.println(result.toString());
 
 }

 Hicham

1 reply

5-Regular Member
July 13, 2020

Hi

 

The CSRF-NONCE is provided by the REST API end point :

 

https://<Windchill server>/Windchill/servlet/odata/PTC/GetCSRFToken()

 

I'm not sure that the "MY-TOKEN" string had been provided by this end point  🙂

 

Hicham

 

VladiSlav17-PeridotAuthor
17-Peridot
July 13, 2020

Thanks for the answer!

Yes, I copied my real token there, but I just decided to replace it so. 😅
I apologize for being misleading.

Here is the real tokens format that I am adding:

F4a464/MVN5bbrRdYtbXq+TnODYTPq9qbbHS2OOWM+xlT80oT7XgpumOIboWGtAvILbsnp18ZOHnR3FiI7CBxZn0dOZuDo3fIMTRne2lBpIJIt8qe6/ptv+fIREML4k=

hlafkir5-Regular MemberAnswer
5-Regular Member
July 13, 2020

ok thank you for this light.

 

Can you try that please (working fine for me). Just replace the user-agent and the PDMLinkProduct oid with your one. You will then see what is going wrong with your code :

 

private void sendPost() throws Exception {
 
 String url = "http://pdm10.de/Windchill/servlet/odata/ProdMgmt/Parts";
 
 HttpClient client = HttpClientBuilder.create().build();
 HttpPost post = new HttpPost(url);
 
 // add header
 post.setHeader("User-Agent", USER_AGENT);
 BASE64Encoder enc = new sun.misc.BASE64Encoder();
 String username="wcadmin";
 String password="ts";
 String userpassword = username + ":" + password;
 String encodedAuthorization = enc.encode( userpassword.getBytes() );
 
 
 JSONObject json = new JSONObject();
 json.put("Name", "TestWTPartFromOdata");
 json.put("PhantomManufacturingPart" , false);
 //"GatheringPart": false,
 json.put("GatheringPart", false);
 
 HashMap<String, String> am_map = new HashMap<String, String>(); 
 am_map.put("Value", "separable");
 am_map.put("Display", "Separable" );
 json.put("AssemblyMode", am_map);
 
 
 HashMap<String, String> df_map = new HashMap<String, String>(); 
 df_map.put("Value", "ea");
 df_map.put("Display", "Each" );
 json.put("DefaultUnit", df_map);
 
 HashMap<String, String> dtc_map = new HashMap<String, String>(); 
 dtc_map.put("Value", "0");
 dtc_map.put("Display", "Untraced" );
 json.put("DefaultTraceCode", dtc_map);
 
 HashMap<String, String> src_map = new HashMap<String, String>(); 
 src_map.put("Value", "make");
 src_map.put("Display", "Make" );
 json.put("Source", src_map);
 
 
 HashMap<String, String> cfm_map = new HashMap<String, String>(); 
 cfm_map.put("Value", "standard");
 cfm_map.put("Display", "Standard" );
 json.put("ConfigurableModule", cfm_map);
 
 json.put("EndItem" , false);
 json.put("Context@odata.bind", "Containers('OR:wt.pdmlink.PDMLinkProduct:64091')");
 StringEntity params = new StringEntity(json.toString());
 
 
 
 
 /*
 * {
 "Name": "Part_P036",
 "AssemblyMode": {
 "Value": "separable",
 "Display": "Separable"
 },
 "EndItem" : false,
 "DefaultUnit": {
 "Value": "ea",
 "Display": "Each"
 },
 "DefaultTraceCode": { 
 "Value": "0",
 "Display": "Untraced"
 },
 "Source": { 
 "Value": "make",
 "Display": "Make"
 },
 "ConfigurableModule": {
 "Value" : "standard",
 "Display" : "Standard"
 },
 "GatheringPart": false,
 "PhantomManufacturingPart": false,
 "Context@odata.bind": "Containers('OR:wt.pdmlink.PDMLinkProduct:64091')"
 
}
 
 * 
 */
 
 
 
 
 
 
 
 post.addHeader( "Authorization", "Basic "+ encodedAuthorization);
 //post.addHeader("Accept", "application/json");
 post.addHeader("Content-Type", "application/json");
 post.addHeader("Accept","application/json");
 post.addHeader("CSRF_NONCE","ypTCuzcDl4rmuSC3jMyM71JH+8+sgGbbnN6j1lJp29rV90TG/ces9FtN38Kc4FTZiPr08k5g2rfciBWO+qT1ig43pbvSjhr5ruy41FV2/9uUzRTvha2t/XhVouSRhB0=");
 post.setEntity(params);
 
 
 HttpResponse response = client.execute(post);
 System.out.println("\nSending 'POST' request to URL : " + url);
 System.out.println("Post parameters : " + post.getEntity());
 System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
 
 BufferedReader rd = new BufferedReader( new InputStreamReader(response.getEntity().getContent()));
 
 StringBuffer result = new StringBuffer();
 String line = "";
 while ((line = rd.readLine()) != null) {
 result.append(line);
 }
 
 System.out.println(result.toString());
 
 }

 Hicham