Oauth 1.0 module help

Working on setting up connection with Netsuite REST API. Uses oauth 1.0.
When setting up credentials in Netsuite you are provided consumer secret/key & token ID/secret.

I see on the oauth module where to add the consumer secret/key but no where to use the token ID/secret, just the url to request token.

I’m sure its something simple but im not 100% familiar with 1.0.

Thanks

An integration partner has already integrated NetSuite, but not using OAuth. You may want to review their implementation in dev.apiant.com, assembly uuid = e9621513ced541438d0661c1acf128b0

The OAuth modules only work for “standard” integrations. Some API providers do not follow standards. Don’t know if that is why the integration in dev does not use OAuth or not, I was not involved with it.

There are 3 different webservices for netsuite. The one on dev is a suitescript integration (restlets) on netsuite. there is also a soap webservice and rest (which i am working with).

I have the connection set up and working on postman and just looking to duplicate on apiant.

So, as it is I am just seeing how i would pass all 4 IDs over.

Sorry, I’m not familiar with how they implement their OAuth. OAuth v1.0a only needs a consumer key and secret for the initial workflow.

Ok, well maybe you can help point me in the right direction

Like I mentioned before, using the provided collection from Netsuite, I imported to postman and am able to use any of the CRUD calls and they all function properly.

so…the provided collection sets up everything. The authorization is oauth 1.0 and all authorization data is added to the request header. I have all 4 variables held in postman.

I can run a GET call to retrieve metadata on a record. The default call only provides the accept header, everything else is inherited from parent


Do you have any idea which way i should head to get this ported over to apiant? I started with the oauth1.0a module but not sure how to provide the token values or how to add the header if need be.
I also tried just passing it as a http call but get a 401 error so netsuite clearly isnt accepting that.

Any ideas?

Hmm. My first suggestion is to just try to make an API call like Postman is doing by using the raw HTTP Transaction module.

Take these values from Postman:

You will need to examine how Postman is actually sending the headers to determine the key/value pairs. Then put those values here:

If that works, then the next hurdle is to figure out how to connect accounts via the OAuth v1.0a handshake. The system’s OAuth Workflow modules are for that, but only support “standard” handshaking. Only a consumer key and secret are needed to handshake, if they follow the standard.

I don’t use Postman, so I don’t know if you can examine all the back-and-forth it does for the handshake to obtain the access token. If you can, send logs of what it is doing and I can take a look at it for you.

Good luck!

I tried to replicate in apiant and no go there. 401

Here is the raw log from the postman console.

Below is a base call for retrieving customer metadata.

GET https://tstdrv2164811.suitetalk.api.netsuite.com/rest/platform/v1/metadata-catalog/record?select=customer

GET /rest/platform/v1/metadata-catalog/record?select=customer HTTP/1.1
Accept: application/swagger+json
Authorization: OAuth realm=“TSTDRV2164811”,oauth_consumer_key=“2bb1d46bb5f3a69fdea1ede39bf46e186bd860a15d8deaf51f7488b1e09bd2a2”,oauth_token=“02545230f53d0cf8fc5075f8cee01847f28131127fad358501479952bb8ce046”,oauth_signature_method=“HMAC-SHA256”,oauth_timestamp=“1579789885”,oauth_nonce=“fUfNfeDNp1P”,oauth_version=“1.0”,oauth_signature=“3FOL6yO0JpFzeZf81ft4OrHmpZpll%2FXuj4%2FrdplQEB8%3D”
User-Agent: PostmanRuntime/7.22.0
Cache-Control: no-cache
Postman-Token: 79c9e566-cf72-4751-8f0f-708b5a4a05e2
Host: tstdrv2164811.suitetalk.api.netsuite.com
Accept-Encoding: gzip, deflate, br
Cookie: NS_ROUTING_VERSION=LAGGING
Connection: keep-alive

HTTP/1.1 200 OK
Date: Thu, 23 Jan 2020 14:31:25 GMT
X-N-OperationId: bf125bad-24bd-43f1-8a0f-8fdf337ef3c7
NS_RTIMER_COMPOSITE: 960769647:706172746E6572733032372E70726F642E7376616C652E6E65746C65646765722E636F6D:80
Strict-Transport-Security: max-age=31536000
Pragma: No-Cache
Cache-Control: No-Cache
Expires: 0
edge-control: no-store
X-NetSuite-JobId: d4fce688-06cd-4b35-b8ac-273b76ab2fe2
Content-Type: application/swagger+json; charset=UTF-8
Content-Length: 37633
P3P: CP=“CAO PSAa OUR BUS PUR”
Vary: User-Agent
Keep-Alive: timeout=10, max=996
Connection: Keep-Alive

Also, here is a call for updating a customer. both are working by the way in postman.

PATCH https://tstdrv2164811.suitetalk.api.netsuite.com/rest/platform/v1/record/customer/1185

PATCH /rest/platform/v1/record/customer/1185 HTTP/1.1

Content-Type: application/json

Authorization: OAuth realm=“TSTDRV2164811”,oauth_consumer_key=“2bb1d46bb5f3a69fdea1ede39bf46e186bd860a15d8deaf51f7488b1e09bd2a2”,oauth_token=“02545230f53d0cf8fc5075f8cee01847f28131127fad358501479952bb8ce046”,oauth_signature_method=“HMAC-SHA256”,oauth_timestamp=“1579790356”,oauth_nonce=“cKPIZ6nRyXT”,oauth_version=“1.0”,oauth_signature=“GoOEr1nFoidhcNpK2vTPAD8Ty3NWFgjryu2L%2Ffja8TY%3D”

User-Agent: PostmanRuntime/7.22.0

Accept: /

Cache-Control: no-cache

Postman-Token: af29c92f-8050-48c4-a677-aba4df01f439

Host: tstdrv2164811.suitetalk.api.netsuite.com

Accept-Encoding: gzip, deflate, br

Content-Length: 63

Cookie: NS_ROUTING_VERSION=LAGGING

Connection: keep-alive

{

“companyname”: “AVT TEST2”,

“email”: “email123@yahoo.com

}

HTTP/1.1 204 No Content

Date: Thu, 23 Jan 2020 14:39:15 GMT

X-N-OperationId: a7199284-0809-4b78-89a1-ff518c1d4240

NS_RTIMER_COMPOSITE: 1823609207:706172746E6572733031312E70726F642E7376616C652E6E65746C65646765722E636F6D:80

Strict-Transport-Security: max-age=31536000

Pragma: No-Cache

Cache-Control: No-Cache

Expires: 0

edge-control: no-store

X-NetSuite-JobId: aeace6cb-3140-4142-be02-172136d141c8

Location: https://tstdrv2164811.suitetalk.api.netsuite.com/rest/platform/v1/record/customer/1185

Content-Type: application/json;charset=utf-8

P3P: CP=“CAO PSAa OUR BUS PUR”

Vary: User-Agent

Keep-Alive: timeout=10, max=965

Connection: Keep-Alive

This is a demo account so no worries about exposing any values.

Thanks

Sorry, since the headers contain dynamically computed values like the nonce and timestamp you won’t be able to use the HTTP Transaction module. Has been years since I’ve worked with OAuth v1.0a, I had forgotten about that. OAuth v2 just uses a simple access token in the header.

So you will either have to figure out how to connect to their API via the OAuth v1.0a Workflow module, or find some other solution if they aren’t doing standard v1.0a handshaking.

Im guessing there is no built module for calculating time/nonce and storing values so they dont get reused

Nope, all of the OAuth v1.0a logic is done via a 3rd-party library the system uses.

ok. Is there any way I can get to the inner working of the oauth module? I would like to see whats going on behind the scenes and maybe be able to modify my own version to handle this

Sorry, but no. The OAuth implementation is a 3rd-party library that is not accessible via the assembly editor. The module is basically just a shell around that library.

The dev system has 6 apps integrated that use OAuth v1.0a. So it does work.

What errors occur when you try to connect an account via the v1.0a Workflow module?

That is part of the problem. I cannot find any specific URL listed to point the oauth module to to retrieve any token/authorization/etc.

So it appears as I will need to calculate the timestamp, nonce, and signature on the fly.

Timestamp should be easy.
Nonce, not sure exactly the requirements yet but I think that should be fairly straight forward using a random function

Signature, that i am not sure on how to calculate. i know the string and key order for generation but i have yet to find a straight forward example on how to calculate that. Netsuite accept SHA1 or SHA256.

This is the Java library the system uses for OAuth: https://github.com/scribejava/scribejava

You should be able to find all the needed routines in that library and put within an inline JSP.

I also found this sample code that uses the Scribe library to connect to Netsuite:

https://blog.prolecto.com/2017/11/11/download-a-java-application-to-connect-to-netsuite-oauth-tba-restlet-endpoints/

Maybe the problem is that they don’t do a handshake to provide the access token and secret. If you have those values in-hand, then that would explain why the system’s integration won’t work for you. It expects a user to do the browser-based workflow to authorize access to obtain those values.

Thanks

After a ton more digging I am pretty sure I have what i need to do figured out, now its just a matter of getting it right.

So, I have a section of code calculating a nonce, pulling UNIX timestamp, and calculating the signature.
Unfortunately, still no go. I tried using known values for everything to see if my signature matches and im not matching up quite right.

Using this data…

GET /rest/platform/v1/metadata-catalog/record?select=customer HTTP/1.1
Accept: application/swagger+json
Authorization: OAuth realm=“TSTDRV2164811”,
oauth_consumer_key=“2bb1d46bb5f3a69fdea1ede39bf46e186bd860a15d8deaf51f7488b1e09bd2a2”,
oauth_token=“02545230f53d0cf8fc5075f8cee01847f28131127fad358501479952bb8ce046”,
oauth_signature_method=“HMAC-SHA1”,
oauth_timestamp=“1579805526”,
oauth_nonce=“V5GBSPyMRPB”,
oauth_version=“1.0”,
oauth_signature=“rp6xmqnCofmVPl9D0nk48G9DVww%3D”
User-Agent: PostmanRuntime/7.22.0
Cache-Control: no-cache
Postman-Token: cbc0f225-374c-4ecc-8b5b-daf60469137e
Host: tstdrv2164811.suitetalk.api.netsuite.com
Accept-Encoding: gzip, deflate, br
Cookie: NS_ROUTING_VERSION=LAGGING
Connection: keep-alive

…I pulled the key, token, nonce, etc and tried passing all those values through to my signature hash and no go.

This is what I have attempting to do that…

<?php
$account = 'ARG1';
$consumer = 'ARG2';
$token = 'ARG3';
$key = ($consumer & $token);
$created = 'ARG4';
$nonce  = 'ARG5';
$sign = ($account & $consumer & $token & $nonce & $created);
$signature = urlencode(base64_encode(hash_hmac('sha1', $sign, $key, true)));

$output .= sprintf(
    '<root><signature>%s</signature><Nonce>%s</Nonce><Created>%s</Created></root>',
    $signature,
    $nonce,
    $created
);



echo $output;


?>

While it is calculaing, it isn’t matching what i expect from above. Not sure if you have any insight here or if I just need to keep working with it.

Thanks

Hard to help at a code level without debugging it myself.

Did you see this?

So I think I made some progress but still stuck on the signature creation itself.

Working with netsuite, their support is limited to getting it working within postman. Since that works, they consider it done.

I was able to find this (https://netsuite.custhelp.com/app/answers/detail/a_id/69223/kw/69223) and using the web services base string/key I was able to generate a signature that matches their example. Downside is, it still doesnt work. BUT I am now able to see attempts on the netsuite log showing invalid signature. If I mess with the nonce or timestamp, i will get validation errors there so I know that all of those are being created properly, its just now the signature.

So I turned my attention to postman itself to try to see how exactly they are creating the signature. took a hot minute but eventually they led me to their repository and this (https://github.com/postmanlabs/postman-runtime/blob/develop/lib/authorizer/oauth1.js)

Now my js isnt fantastic but it looks like signature is (in order) url, method, consumer key, token, sign method, time, nonce, version.

I tried that but no go. I was hoping you could take a look here and maybe your wealth of knowledge would help direct me. thanks

for reference, I created fd83db239b45437c898e7a4238882919

Only people with accounts can view the first link you posted.

It doesn’t seem you are sending the headers correctly. Each key-value pair is a header. Send them like this:

OAuth v2 uses an “Authorization” header that contains “Bearer xxx” where xxx is the access token. I don’t think OAuth v1.0a uses a header named “Authorization” at all, but I could be wrong. I would try removing it and just send all the key-value pairs as headers.

I can confirm that the authorization header is a single string with comma separate values like i have it. when i move everything to individual headers it fails completely. keeping it as a single string i can manipulate the individual values and see changes in the log in terms of it recognizing/accepting the nonce, timestamp, etc. So that part i believe is all correct. The log even recognizes the token being passed that way which is tied to the application/role combo in netsuite (which shows accurately on the log).

Im just stuck on the actual signature creation which i believe is the basestring itself. banging my head against the wall trying to match postman

Sorry, it doesn’t seem I will be of any further help on this.