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

Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X

Why is CreateThing java REST call in R6 is failing with HTTP Error 403 Forbidden?

ptc-89213
6-Contributor

Why is CreateThing java REST call in R6 is failing with HTTP Error 403 Forbidden?

The method=post is not allowed in URL parameter in TWX server R6 version due to security issues. So modified the code to use post like below. However the request still fails. I have ensured that URL as well as appKey is correct. Any Ideas ?

URL thingworx_rest_url = new URL(

  ACConfig.REST_BASEURI + "Resources/EntityServices/Services/CreateThing");

  HttpURLConnection http_connection = (HttpURLConnection) thingworx_rest_url

  .openConnection();

  http_connection.setDoOutput(true);

  http_connection.setRequestMethod("POST");

  http_connection.setRequestProperty("appKey", ACConfig.AUTH_APPKEY);

  http_connection.setUseCaches(false);

  String input = "name="

  + ACConfig.ACThingName + "&description="

  + ACConfig.ACThingName

  + "&thingTemplateName=RemoteThing";

  byte[] postData       = input.getBytes( StandardCharsets.UTF_8 );

  int postDataLength = postData.length;

  http_connection.setInstanceFollowRedirects( false );

  http_connection.setRequestMethod( "POST" );

  http_connection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded");

  http_connection.setRequestProperty( "charset", "utf-8");

  http_connection.setRequestProperty( "Content-Length", Integer.toString( postDataLength ));

  try( DataOutputStream wr = new DataOutputStream( http_connection.getOutputStream())) {

    wr.write( postData );

  }

  if (http_connection.getResponseCode() != HttpURLConnection.HTTP_CREATED) {

  throw new RuntimeException("Failed : HTTP error code : "

  + http_connection.getResponseCode());

  }

1 ACCEPTED SOLUTION

Accepted Solutions
ptc-89213
6-Contributor
(To:ptc-89213)

Resolved by using json content in post instead of plain text.

If you need to use plain text, then filter content option should be turned off.

View solution in original post

12 REPLIES 12
paic
1-Newbie
(To:ptc-89213)

If the call is properly formed (sorry I can't ensure that from just looking at your script) try executing it twice in a row.

If that works, I believe there is a knowledge base article about this type of behavior.

ptc-89213
6-Contributor
(To:paic)

Hi,

As this is a programatic call, it cannot be executed twice..

I resolved it however by enabling REST on 6.0 as follows..

To unlock/ allow all REST calls, here are the steps:

  1. Click on Subsystems under SYSTEM within the left pane of Composer
  2. Click on PlatformSubsystem
  3. Click on Configuration
  4. Check the box next to Allow Request Method Switch to allow all REST API calls through a browser URL
  5. Uncheck Filter Content-Type

Let me know if there is any other preferable way..without compromising on security.

Thanks

Shashikant

paic
1-Newbie
(To:ptc-89213)

Unfortunately if that is what you had to do, then the call you are making is incorrect. That seems to indicate that it is still taking the POST as a URL based call vs. an actual POST

We do not recommend using this switch as it carries security risks with it (Please see release notes on this)

ptc-89213
6-Contributor
(To:paic)

The request is proper post call without passing parameters on URL as done in 5.4.

The same request is working as soon as switch those config options.

Do you have pointers to any sample code for such post request without changing those config options?

Thanks in advance..

I'm having the exact same issue but trying to issue the PUT with a lua script.

paic
1-Newbie
(To:ptc-89213)

Please log these as cases at support.ptc.com, regular API calls should work fine using the POST and PUT methods.

davidcor
1-Newbie
(To:paic)

Pai - I opened a cse, but could this be due to the fact that Tomcat dos not allow PUT by default? Would we need to make some modification to the web.xml in order to make this work?

I finally figured out my problem. In my case, I needed to set the Content-Type in the header to application/json.

ptc-89213
6-Contributor
(To:ptc-89213)

It seems the problem is Thingworx server is filtering the form data.

When I deselect Filter Content-Type in PlatformSubsystem configuration, it is allowing the post request

Now the question is how to pass the form data using post with default options of Filter Content-Type ?

ptc-89213
6-Contributor
(To:ptc-89213)

Resolved by using json content in post instead of plain text.

If you need to use plain text, then filter content option should be turned off.

Hello Shashikant,

good to know you have found a solution!

could you share example of your code that is working ?

thanks  a lot

Richard

ptc-89213
6-Contributor
(To:richardmu)

Hi Richard,

This should help you...

URL thingworx_rest_url = new URL(

  ACConfig.REST_BASEURI + "Resources/EntityServices/Services/CreateThing");

Create JSONObject and put all parameters and pass it to following API.

private static void executePostRequest(URL thingworx_rest_url,

  JSONObject inputObj) throws IOException, ProtocolException,

  JSONException {

  inputObj.put("appKey", ACConfig.AUTH_APPKEY);

  inputObj.put("x-thingworx-session", "true");

  System.out.println("URL:" + thingworx_rest_url.toExternalForm());

  String input = inputObj.toString();

  System.out.println("POSTData:" + input);

  HttpURLConnection http_connection = (HttpURLConnection) thingworx_rest_url

  .openConnection();

  http_connection.setRequestMethod("POST");

  http_connection.setDoOutput(true);

  http_connection.setRequestProperty("appKey", ACConfig.AUTH_APPKEY);

  http_connection.setRequestProperty("x-thingworx-session", "true");

  http_connection.setUseCaches(false);

  http_connection.setInstanceFollowRedirects(false);

  http_connection.setRequestProperty("Content-Type", "application/json");

  http_connection.setRequestProperty("charset", "UTF-8");

  try (DataOutputStream wr = new DataOutputStream(

  http_connection.getOutputStream())) {

  wr.write(input.getBytes());

  wr.flush();

  }

  System.out.println("RESPONSE:" + http_connection.getResponseCode());

  }

Top Tags