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!
Solved! Go to Solution.
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
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=
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
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 😞
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:
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:
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:
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!