Netsuite's documentation is not forthcoming. Does anyone have code they've written that will help me generate a valid signature.
Asked
Active
Viewed 9,756 times
3 Answers
13
There is some sample code in the NetSuite Suite answers site, but you'll have to log in to access it.
https://netsuite.custhelp.com/app/answers/detail/a_id/42165/kw/42165
Here is the code from the answer that I was able to make work. The only difference is that their code broke by trying to encode the timestamp as an int. I typecasted it to a str and the encoding worked fine. The keys/tokens/realm are from their demo code. Insert your own and you should be good to go.
import oauth2 as oauth
import requests
import time
url = "https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5", secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38", secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "GET"
realm="ACCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
req = oauth.Request(method=http_method, url=url, parameters=params)
signature_method = oauth.SignatureMethod_HMAC_SHA1()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
headery = header['Authorization'].encode('ascii', 'ignore')
headerx = {"Authorization": headery, "Content-Type":"application/json"}
print(headerx)
conn = requests.get("https://rest.netsuite.com/app/site/hosting/restlet.nl?script=992&deploy=1",headers=headerx)
print(conn.text)

Tyrel Denison
- 466
- 5
- 14
-
1This method of using OAuth no longer works. Netsuite requires SHA256 signature. SHA1 is deprecated. – Peter Andreoli Jun 22 '21 at 15:28
-
Hi @PeterAndreoli, considering that the library oauth does not allow for OAuth2.0, what would be the better alternative to implement OAuth2.0 for NetSuite connection? – Limyandi Vico Trico Jul 16 '21 at 00:17
-
Unfortunately I do not have the answer for this right now. I am going to be updating our integrations soon so hopefully I'll be back here with a solution. – Peter Andreoli Jul 16 '21 at 15:28
-
-
2@LimyandiVicoTrico its funny that you bring this up now. My fix was just pushed to prod! You can find my solution here https://github.com/pietro-andreoli/python-oauth2-additions . Essentially I extended the base class of the `SignatureMethod_HMAC_SHA1` class in order to make my own implementation for SHA256. Not guaranteed to be a perfect solution, but has been working on my end for a little now. Will update if anything changes. – Peter Andreoli Aug 04 '21 at 15:41
-
I should clarify that this is not an implementation of OAuth 2.0. It is a conversion from SHA1 signature to SHA256, which is needed if your integration uses TBA – Peter Andreoli Aug 04 '21 at 15:51
-
Hi @PeterAndreoli, thanks for the solution, I have used your implementation for the migration from SHA1 signature to SHA256 signature and it worked great. Do you know if there is any movement from NetSuite to deprecate TBA authentication, and force user to use OAuth2 in the near future? – Limyandi Vico Trico Aug 09 '21 at 03:30
4
Just for reference, I recently did this in Python3 using requests_oauthlib
and it worked with standard use of the library:
from requests_oauthlib import OAuth1Session
import json
url = 'https://xxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=xxx&deploy=xxx'
oauth = OAuth1Session(
client_key='xxx',
client_secret='xxx',
resource_owner_key='xxx',
resource_owner_secret='xxx',
realm='xxx')
payload = dict(...)
resp = oauth.post(
url,
headers={'Content-Type': 'application/json'},
data=json.dumps(payload),
)
print(resp)

Ilmari Aalto
- 221
- 2
- 5
-
1I think most people on a new integration will need to add `signature_method='HMAC-SHA256',` to the OAuth1Session options. Other than that you are totally correct! Thanks so much, I almost gave up on libraries, it just took me a little bit to figure out the 256 thing. – Taylor j. Eke Feb 08 '22 at 20:45
2
Building off NetSuite's original sample code I was able to get the below working with SHA256, I think you could do a similar thing for SHA512.
import binascii
import hmac
import time
from hashlib import sha256
import oauth2 as oauth
import requests
url = "https://<account>.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=<scriptId>&deploy=1"
token = oauth.Token(key="080eefeb395df81902e18305540a97b5b3524b251772adf769f06e6f0d9dfde5",
secret="451f28d17127a3dd427898c6b75546d30b5bd8c8d7e73e23028c497221196ae2")
consumer = oauth.Consumer(key="504ee7703e1871f22180441563ad9f01f3f18d67ecda580b0fae764ed7c4fd38",
secret="b36d202caf62f889fbd8c306e633a5a1105c3767ba8fc15f2c8246c5f11e500c")
http_method = "POST"
realm = "CCT123456"
params = {
'oauth_version': "1.0",
'oauth_nonce': oauth.generate_nonce(),
'oauth_timestamp': str(int(time.time())),
'oauth_token': token.key,
'oauth_consumer_key': consumer.key
}
class SignatureMethod_HMAC_SHA256(oauth.SignatureMethod):
name = 'HMAC-SHA256'
def signing_base(self, request, consumer, token):
if (not hasattr(request, 'normalized_url') or request.normalized_url is None):
raise ValueError("Base URL for request is not set.")
sig = (
oauth.escape(request.method),
oauth.escape(request.normalized_url),
oauth.escape(request.get_normalized_parameters()),
)
key = '%s&' % oauth.escape(consumer.secret)
if token:
key += oauth.escape(token.secret)
raw = '&'.join(sig)
return key.encode('ascii'), raw.encode('ascii')
def sign(self, request, consumer, token):
"""Builds the base signature string."""
key, raw = self.signing_base(request, consumer, token)
hashed = hmac.new(key, raw, sha256)
# Calculate the digest base 64.
return binascii.b2a_base64(hashed.digest())[:-1]
req = oauth.Request(method=http_method, url=url, parameters=params)
oauth.SignatureMethod_HMAC_SHA256 = SignatureMethod_HMAC_SHA256
signature_method = oauth.SignatureMethod_HMAC_SHA256()
req.sign_request(signature_method, consumer, token)
header = req.to_header(realm)
header_y = header['Authorization'].encode('ascii', 'ignore')
header_x = {"Authorization": header_y, "Content-Type": "application/json"}
print(header_x)
response = requests.request("POST", url, data={}, headers=header_x)
# conn = requests.post(url, headers=headerx)
print(response.text)

Jay42
- 417
- 1
- 11
- 24
-
If this is a GET request then we have to include the request parameters in the URL. – user1456599 Aug 31 '22 at 20:24