cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

POST request_OData REST API

VladiSlav
16-Pearl

POST request_OData REST API

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!

1 ACCEPTED SOLUTION

Accepted Solutions
hlafkir
13-Aquamarine
(To:VladiSlav)

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

View solution in original post

7 REPLIES 7
hlafkir
13-Aquamarine
(To:VladiSlav)

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

 

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=

hlafkir
13-Aquamarine
(To:VladiSlav)

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

View solution in original post

I redid the code a bit.
Here's what happened:

private static void sendPost() throws Exception {
		 
        String url = "http://server/Windchill/servlet/odata/ProdMgmt/Parts";

        HttpClient client = HttpClientBuilder.create().build();
        HttpPost post = new HttpPost(url);

        // add header
        String username="wcadmin";
        String password="wc";
        String userpassword = username + ":" + password;
        String encodedAuthorization = new String(Base64.getEncoder().encode(userpassword.getBytes()));
        
        
        JSONObject json = new JSONObject();
        json.put("Name", "TestWTPartFromOdata");
        json.put("PhantomManufacturingPart" , 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);
        
        json.put("DefaultUnit", "kg");      
        json.put("DefaultTraceCode", "0");
        json.put("Source", "make");
        json.put("EndItem" , false);
        json.put("Context@odata.bind", "Containers('OR:wt.pdmlink.PDMLinkProduct:64091')");
        StringEntity params = new StringEntity(json.toString());
        
		       
        post.addHeader( "Authorization", "Basic " + encodedAuthorization);
        post.addHeader("Content-Type", "application/json");
        post.addHeader("Accept","application/json");
        post.addHeader("CSRF_NONCE","F4a464/MVN5bbrRdYtbXq+TnODYTPq9qbbHS2OOWM+xlT80oT7XgpumOIboWGtAvILbsnp18ZOHnR3FiI7CBxZn0dOZuDo3fIMTRne2lBpIJIt8qe6/ptv+fIREML4k=");
        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());
	}

Here are the errors I get:

1)

Post parameters : [Content-Type: text/plain; charset=ISO-8859-1,Content-Length: 290,Chunked: false]
Response Code : 400
{"error":{"code":null,"message":"Context is not valid."}}

2)

Post parameters : [Content-Type: text/plain; charset=ISO-8859-1,Content-Length: 291,Chunked: false]
Response Code : 403
{"error":{"code":null,"message":"Windchill type is not instantiable"}}

 I understand the problems in this line:

json.put("Context@odata.bind", "Containers('OR:wt.doc.WTDocument:1131319')");

 but I don’t quite know what to indicate here 😞

hlafkir
13-Aquamarine
(To:VladiSlav)

HI

 

When you set a document instead of a container OID as paramter for  Context@odata.bind, i guess that  you need some more knowledge about Windchill architecture and context/container url.

 

Please check these two articles to understand Windchill architecture, and how to read a container oid :

 

https://www.ptc.com/en/support/article/CS212423 for windchill Architecture

and

https://www.ptc.com/en/support/article/CS233649 for container OID

 

hicham

 

 

Thanks for the info!

I just tried all the options, but my understanding was not enough.

Now I switched to the product, as mentioned in one of the articles, and copied the following OID:

OR:wt.pdmlink.PDMLinkProduct:112148

but it still does not work and produces the same error:

 

 

Post parameters : [Content-Type: text/plain; charset=ISO-8859-1,Content-Length: 291,Chunked: false]
Response Code : 400
{"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 looked at the documentation, here is what this code means:

VladiSlav_1-1594666923753.png

I also tried to run this code on the server, the following error appeared:

 

 

Post parameters : [Content-Type: text/plain; charset=ISO-8859-1,Content-Length: 291,Chunked: false]
Response Code : 403
{"error":{"code":null,"message":"Windchill type is not instantiable"}}

 

 

Here is what the documentation says about this:

VladiSlav_0-1594707166667.png

But I used the admin user.
Help me please.
Thank you in advance!

I found a mistakes.
Type must be Instantiable.
Here's how to do it:

VladiSlav_0-1594710419406.png

Just as I understand it, the generated token can only be used by the user who received it.

 

Hicham,

Thank you very much for your help!

Announcements