OAuth With Client Credentials

Hi, I am using the Tutorial OAuth With Client Credentials with the powershell format.
We are in the US region.

The script I am using is a direct copy from the Tutorial:
$secret = "SECRET";
$id = "CLIENT";
auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("{id}:${secret}"))
response = Invoke-WebRequest -Uri https://login.mypurecloud.com/oauth/token -Method POST -Body @{grant_type='client_credentials'} -Headers @{"Authorization"="Basic {auth}"}
$responseData = $response.content | ConvertFrom-Json
$roleResponse = Invoke-WebRequest -Uri https://api.mypurecloud.com/api/v2/authorization/roles -Method GET -Headers @{"Authorization"= $responseData.token_type + " " + $responseData.access_token}
write-host $roleResponse.content

The response I am getting is:
Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At C:\Users\steph\cr-x\getoauth.ps1:5 char:13

  • $response = Invoke-WebRequest -Uri https://login.mypurecloud.com/oaut ...
  •         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\Users\steph\cr-x\getoauth.ps1:6 char:38

  • $responseData = $response.content | ConvertFrom-Json
  •                                  ~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidData: (:slight_smile: [ConvertFrom-Json], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

Invoke-WebRequest : The request was aborted: Could not create SSL/TLS secure channel.
At C:\Users\steph\cr-x\getoauth.ps1:7 char:17

  • ... eResponse = Invoke-WebRequest -Uri https://api.mypurecloud.com/api/v2 ...
  •             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    • FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

I have also tried a similar attempt using a curl script:
export TOKEN=cat oauth.txt
export CLIENT_ID=cat oauth.txt | awk -F":" '{print $1 }'
export CLIENT_SECRET=cat oauth.txt | awk -F":" '{print $2 }'
export TOKEN64=cat oauth.txt | 'base64'

echo token = $TOKEN
echo token = $TOKEN64
echo client_Id = $CLIENT_ID
echo client_secret = CLIENT_SECRET curl -L -X POST "https://login.mypurecloud.com/oauth/token" \ -H "Authorization: Basic {TOKEN64}"
-H "Content-Type: application/x-www-form-urlencoded"
-d "grant_type=client_credentials"

curl -k -v -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic ${TOKEN64}" -d "grant_type=client_credentials" https://login.mypurecloud.com/oauth/token >result

With the result:
400 Bad Request

What am I doing wrong, please?

It's hard to say exactly what's going on in your code since there are partial stack traces from multiple errors and they don't match the code you shared and there's no details about what the actual response was (http status code and body). But the error about being unable to establish a TLS connection is most suspicious. Be sure your script is using TLS 1.1 or above when establishing a connection. TLS 1.0 is unsupported.

Hi Tim,

Thanks for the response. However the information I have provided for the Powershell attempt is from a single attempt but of course some of the errors refer to the latter code which is attempting to use information that was not retrieved from the initial login.

So changing tack then - with the curl script:
export TOKEN=cat oauth.txt
export CLIENT_ID=cat oauth.txt | awk -F":" '{print $1 }'
export CLIENT_SECRET=cat oauth.txt | awk -F":" '{print $2 }'
export TOKEN64=cat oauth.txt | 'base64'

echo token = $TOKEN
echo token = $TOKEN64
echo client_Id = $CLIENT_ID
echo client_secret = CLIENT_SECRET curl -k -v "https://login.mypurecloud.com/oauth/token" \ -H "accept: application/json" \ -H "User-Agent: CustomerView" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "Authorization: Basic {TOKEN64}"
-d "grant_type=client_credentials" >result1

The result1 file has:
400 Bad request

With verbose mode on, the output is:
bash-3.2$ ./trial1.curl
sQUPOYg
token = YWI1YzY5ZGUtNDkzNi00MjE0LTkxYzctNmM1MmMzMjViNzE0Onp1L......LWFBNnNRVVBPWWcNCg0K
client_Id = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
client_secret = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 54.152.195.5...

  • TCP_NODELAY set
  • Connected to login.mypurecloud.com (54.152.195.5) port 443 (#0)
  • ALPN, offering http/1.1
  • Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
  • successfully set certificate verify locations:
  • CAfile: /etc/pki/tls/certs/ca-bundle.crt
    CApath: none
  • TLSv1.2 (OUT), TLS header, Certificate Status (22):
    } [5 bytes data]
  • TLSv1.2 (OUT), TLS handshake, Client hello (1):
    } [512 bytes data]
  • TLSv1.2 (IN), TLS handshake, Server hello (2):
    { [89 bytes data]
    0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* TLSv1.2 (IN), TLS handshake, Certificate (11):
    { [4898 bytes data]
  • TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    { [333 bytes data]
  • TLSv1.2 (IN), TLS handshake, Server finished (14):
    { [4 bytes data]
  • TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    } [70 bytes data]
  • TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    } [1 bytes data]
  • TLSv1.2 (OUT), TLS handshake, Finished (20):
    } [16 bytes data]
  • TLSv1.2 (IN), TLS change cipher, Client hello (1):
    { [1 bytes data]
  • TLSv1.2 (IN), TLS handshake, Finished (20):
    { [16 bytes data]
  • SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
  • ALPN, server did not agree to a protocol
  • Server certificate:
  • subject: CN=mypurecloud.com
  • start date: Jul 5 00:00:00 2018 GMT
  • expire date: Aug 5 12:00:00 2019 GMT
  • issuer: C=US; O=Amazon; OU=Server CA 1B; CN=Amazon
  • SSL certificate verify ok.
    } [5 bytes data]

POST /oauth/token HTTP/1.1
Host: login.mypurecloud.com
accept: application/json
User-Agent: CustomerView
Content-Type: application/x-www-form-urlencoded
Authorization: Basic YWI1YzY5ZGUtND...............G9HaVhrU2x0ZHo0
S28wYTFMdU............VVBPWWcNCg0K
Content-Length: 29

} [29 bytes data]

  • upload completely sent off: 29 out of 29 bytes
    { [5 bytes data]
    < HTTP/1.1 400 Bad Request
    < Content-Type: text/plain; charset=utf-8
    < transfer-encoding: chunked
    < Connection: keep-alive
    <
    { [20 bytes data]
    100 44 0 15 100 29 15 29 0:00:01 --:--:-- 0:00:01 46
  • Connection #0 to host login.mypurecloud.com left intact

Working with the curl script only - what have I done wrong - anyone?
btw - it appears we are running TLS1.2

Please regenerate your client secret immediately. Your client secret, the base64 encoded id/secret, and the resulting auth token must always be handled like passwords. Do not post them publicly intact.

The "400 bad request" response means something is incorrect with your request body or headers. A spot check of the values looks like it's correct, so it's likely a syntax error somewhere in your script or incorrect cURL configuration that's causing the request to be malformed.

Hey Tim

Have done and corrected the post as well. Thanks.

Will see if I can sort syntax.

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.