Error:invalid_client getting the Client Credentials

Hi, I’m trying to get the “Client Credentials” to access the Cloud Orchestrator API and I’m getting the following error {“error”:“invalid_client”}.

  1. I have created the External application as described
    https://docs.uipath.com/automation-cloud/docs/managing-external-applications

  2. The application is of type “Confidential application”

  3. I have the “OR.Machines.Read” to application scope

  4. To get the token I’m doing the steps described on “Client Credentials” on UiPath documentation

  5. When I’m executing the crul command I’m getting the http code 400 with {“error”:“invalid_client”}

My crul command is:
curl -X POST -H “Content-Type: application/x-www-form-urlencoded” -d ‘{ grant_type: “client_credentials” client_id: “api ID” client_secret: “App scret” scope: “OR.Machines.Read” }’ https://cloud.uipath.com/identity_/connect/token

Any suggestion how to solve this issue ?

2 Likes

Hello @sandro.nora!

It seems that you have trouble getting an answer to your question in the first 24 hours.
Let us give you a few hints and helpful links.

First, make sure you browsed through our Forum FAQ Beginner’s Guide. It will teach you what should be included in your topic.

You can check out some of our resources directly, see below:

  1. Always search first. It is the best way to quickly find your answer. Check out the image icon for that.
    Clicking the options button will let you set more specific topic search filters, i.e. only the ones with a solution.

  2. Topic that contains most common solutions with example project files can be found here.

  3. Read our official documentation where you can find a lot of information and instructions about each of our products:

  4. Watch the videos on our official YouTube channel for more visual tutorials.

  5. Meet us and our users on our Community Slack and ask your question there.

Hopefully this will let you easily find the solution/information you need. Once you have it, we would be happy if you could share your findings here and mark it as a solution. This will help other users find it in the future.

Thank you for helping us build our UiPath Community!

Cheers from your friendly
Forum_Staff

Having the same issue. I am amazed at the lack of documentation… especially when one sees this message:
image

3 Likes

Did you find a solution for this? I’m having the same issue

Having the same issue here. Any solutions found?

Make sure de clientID and secret id are not encoded,
i was exporting from postman as curl and client and secrtret had% as a url encoding, i recheck the value and now is working

Having the same issue when trying to make a REST call to UiPath with following request data:
{
“grant_type”:“client_credentials”,
“client_id”:“APP-ID-FROM-CLOUD”,
“client_secret”:“APP-SECRET-FROM-CLOUD”,
“scope”:“OR.Tasks OR.Folders OR.Folders.Write OR.Folders.Read OR.Robots OR.Robots.Read OR.Robots.Write OR.Machines OR.Machines.Read OR.Machines.Write OR.Jobs.Write OR.Jobs OR.Jobs.Read”
}
I tried using both application/json and application/x-www-form-urlencoded for Content-type in request header. Both ways seems to fail.
With application/json the call is failing with CORS erros.
With application/x-www-form-urlencoded call is failing with {“error”:“invalid_client”}.
I am trying to connect to orchestrator and create a job from a website in my local machine. The web site is running in on localhost.
I have checked the External application setting and have given all the detail including scopes and redirect url and using the APP ID, Secret received in this page.

Kindly help me resolve this issue

I Had been facing the same issue here, however I removed all quotation marks while using x-www-form-urlencoded and set auth type to bearer token and it works.

Thank you for the response. If you don’t mind could you also post a sample please?
I did not understand removal of quotations and auth type part. Following is the endpoint I am using for authentication:
https://cloud.uipath.com/identity_/connect/token/

Following is the Object i am passing in request body:
{
“grant_type”:“client_credentials”,
“client_id”:“APPID_FROM_ExternalApplicationsPage_IN_CloudPortal”,
“client_secret”:“APP_SECRET_FROM_ExternalApplicationsPage_IN_CloudPortal”,
“scope”:“OR.Robots OR.Robots.Read OR.Robots.Write OR.Machines OR.Machines.Read OR.Machines.Write OR.Execution OR.Execution.Read OR.Execution.Write OR.Assets OR.Jobs.Write OR.Jobs OR.Jobs.Read”
}

All the scopes are assigned at both User and Application level.
This endpoint is working fine in POSTMAN with “Content-type” header as x-www-form-urlencoded.
But it’s not working when trying in Javascript code i.e., React Web Application.
I tried all values for Content-type: x-www-form-urlencoded, application/json, application/xml etc. But none worked.
**Also tried: **
stringifying the request object, Sending Raw JSON object and adding them to endpoint URL directly as query parameters.
None of the ways worked for me. Kindly post a sample.
Thank you for the help

My pleasure!
Here, I’m using php to debug a supose troubleshoot, one important thing that I’ve tryed was to do not use json_encode php function in this case, although I did use a http_build_query in php function. you must try to find something near by this function for you js script.

<?php
class myClass extends TPage
{
    public function __construct()

    {
        parent::__construct();
        $api = [];
        $sh = curl_init();
 /*---[Here, the output must be something like: grant_type=client_credentials&client_id=<yourCliendId>&client_secret=<YourSecretkey>&scope=OR.Queues]*/

      $encode= http_build_query([
                  'grant_type' => 'client_credentials',
                  'client_id' => '<yourCliendId>',
                  'client_secret' => '<YourSecretkey>',
                  'scope' => 'OR.Queues'
        ]);
//--------------------------------------------------------------------------       
        curl_setopt_array($sh,[
            CURLOPT_URL => 'https://cloud.uipath.com/identity_/connect/token',
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $encode,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER => [
                   'Authorization:Bearer Token',
                   'Content-Type: application/x-www-form-urlencoded'
                   ],
             ]);
        var_dump($api = curl_exec($sh));
        curl_close($sh);

    }
}

Lemme know if it helps!
Regards

1 Like

Thank you very much @FoxHere for the response.
I have tried similar way with some JS code and it worked. Posting the JS version that worked , in case anyone else is looking for.

var xhttp = new XMLHttpRequest();

var data = "grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&scope=OR.Robots+OR.Robots.Read+OR.Robots.Write+OR.Machines+OR.Machines.Read+OR.Machines.Write+OR.Execution+OR.Execution.Read+OR.Execution.Write+OR.Assets+OR.Jobs.Write+OR.Jobs+OR.Jobs.Read";

var res = {};
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
      console.log(JSON.parse(this.responseText));
    res = JSON.parse(this.responseText);
  }

};
xhttp.open("POST","https://cloud.uipath.com/identity_/connect/token", false);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

xhttp.send(data);

However the problems are not stopping there. The next calls to Get Releases, Start Job using Authorization header with Bearer token coming from above call’s response, are also failing.
I am not sure why, but the I am continuously getting a 405 error reponse. Following is the JS code I tried for Get Releases
var xhttp1 = new XMLHttpRequest();

xhttp1.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    console.log(JSON.parse(this.responseText));
  }
};
xhttp1.open("GET","https://cloud.uipath.com/invenivcsltd/DefaultTenant/odata/Releases?$filter=Name eq 'RELEASE_NAME'", false);
//xhttp.setRequestHeader("Content-type", "application/json; odata.metadata=minimal; odata.streaming=true");
//xhttp1.setRequestHeader("Access-Control-Allow-Origin", "*");
xhttp1.setRequestHeader("Authorization", "Bearer "+res.access_token);
xhttp1.setRequestHeader("X-UIPATH-OrganizationUnitId", "1340217");
//xhttp1.setRequestHeader("X-UIPATH-TenantName", "DefaultTenant");
xhttp1.send();

I tried checking all the details and everything seems fine. But following is the response I am receiving.


Documentation says to use GET Method. But it is giving 405 Method not allowed error on pre-flight and COR on original call.
Kindly point my mistake.

Hello again @Madan_Ongole! Is there any update? Have you troubleshoot it?

Shambles. I’m getting the same error. Anyone managed to get this one resolved?

1 Like

Hey Yusuf,
make sure you do not include authorization header in your request.

Hey Yusuf,

I’m Also getting the same problem when building the HTTP Request using the UiPath activities.

Doing it in postman is fine because you can change the content type to application/x-www-form-urlencoded, but I’m not having much luck doing that within UiPath.

Reverting to the old way for now, but did you or anyone here ever figure out what was wrong?

EDIT:
Found this obscure forum post that solved it:

Hi, for NodeJS, I was able to attain the access token and release key using the following:

const axios = require("axios").default;
require('dotenv').config()

const base_url = `https://cloud.uipath.com/${process.env.org_name}/${process.env.tenant_name}/orchestrator_`
let access_token='',
release_key='',
access_token_req_data = `grant_type=client_credentials&client_id=${process.env.client_id}&client_secret=${process.env.client_secret}&scope=OR.Execution+OR.Folders+OR.Jobs+OR.Machines+OR.Queues+OR.Robots`;

async function get_access_release() {
    try {
        // get access token
        let response = await axios.post('https://cloud.uipath.com/identity_/connect/token', access_token_req_data, {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        })

        access_token = response.data.access_token

        console.log('access_token: ', access_token)
        
        //get release key
        response = await axios.get(`${base_url}/odata/Releases?$filter=ProcessKey eq 'cat.facts'`, {
            headers: {
                'Authorization': `Bearer ${access_token}`,
                'X-UIPATH-OrganizationUnitId': process.env.org_unit_id
            }
        })

        release_key = response.data.value[0]['Key']

        console.log('release_key: ', release_key)
    } catch (err) {
        console.log(err)
    }
}

get_access_release()

Hello,

For anyone who is looking for answer: when authorizing for client credential POST call has to be made to https://<orchestor_url>/identity_/connect/token. The request has to include data specified in UiPath documentation i. e.
{
grant_type: “client_credentials”
client_id: “{app_id}”
client_secret: “{app_secret}”
scope: “{scopes}”
}

What documentation doesn’t specify is the headers which should be as follows:
{
“Authorization”: “Basic {client_id:client_secret}”,
“Content-Type”: “application/x-www-form-urlencoded”
}
the {client_id:client_secret} has to be encoded using Base64. Below is an example in python. Note that it will work only for Confidential Application authorization flow.

def get_bearer_token ():

client_id = <client_id>                  #this has to be taken from Admin>External Applications
client_secret = <client_secret>   #this has to be taken from Admin>External Applications (only 
                                                       visible when adding new application registrations

# Encode the client ID and client secret
authorization = base64.b64encode(bytes(client_id + ":" + client_secret, "ISO-8859-1")).decode("ascii")



headers = {
    "Authorization": f"Basic {authorization}",
    "Content-Type": "application/x-www-form-urlencoded"
}
body = {
    "grant_type": "client_credentials",
    "client_id": <client_secret>,
    "client_secret": <client_id>,
    "scope": "OR.Queues"

}

response = requests.post("https://asuite.aidrpacloud.com/identity_/connect/token", data=body, headers=headers, verify=False)

return response.json()["access_token"]
2 Likes

Dears,
you should learn first How to use form-data and form-urlencoded content type in Logic Apps HTTP action.

Here is good article: Link

Conclusion:
if postman/fiddler is used or any app, in the Body part your key/value pairs should be as following:
grant_type=client_credentials&client_id={your client id}&client_secret={client_secret}&scope=OR.Jobs OR.Queues OR.Tasks OR.Folders OR.Machines OR.Robots OR.Execution

i.e.:
Body (Separated by &):
Key=Value&Key=Value

Don`t Miss Header Part:
Content-Type → should set to → application/x-www-form-urlencoded

I tried it and it works now. i hope it works for you too.

2 Likes

thank you a lot this is the solution,

I think UiPath should enhance their documentation, they messed a lot of details like the headder and this body format