-->

Reach a NetSuite RESTlet via OAuth

2020-06-03 06:44发布

问题:

The goal is to be able to call RESTlets using OAuth-header instead of NLAuth-header from my Java-application. In order to achieve it I took the following steps:

  1. I created NetSuite Developer Community Account and got a testing environment with admin access (domain system.na1.netsuite.com).

  2. I opened Setup --> Company --> Enable Features. Then opened the "SuiteCloud"-tab and checked the "Client SuiteScript", "Server SuiteScript" and "Token-Based Authentication" here.

  3. I opened the edit-page of one of the roles (it is called "08: Inspection" here). On the "Permissions"-tab I opened the "Setup"-tab and added the following permissions to this role: "Access Token Management", "Log in using Access Tokens" and "User Access Tokens".

  4. I edited my account to have that role: opened "Access"-tab while editing the user and on the"Roles"-tab I added that role ("08: Inspection").

  5. I opened Setup --> Integration --> Manage Integrations --> New and created new application here ("TestIntegr"). The final page held two strings: Consumer Key and Consumer Secret. I saved them in my separate file.

  6. I opened Setup --> Users/Roles --> Access Tokens --> New and created new token for my application+user+role. The final page held two strings: Token ID and Token Secret. I saved them in my separate file.

  7. I used my test program to generate authorization header string and then used this string in rest-client (I used "Insomnia") to reach my dummy-restlet. Got "INVALID_LOGIN_ATTEMPT"-error.

  8. In NetSuite audit-logs I can see failures on behalf of my user but without a role.

More technical info on the 7th step with examples below.

The URL I used to reach my dummy-restlet was https://rest.na1.netsuite.com/app/site/hosting/restlet.nl?script=546&deploy=1

So I generated the "signature string" ("consumer_key" from step 5 and "token" from step 6):

GET&https%3A%2F%2Frest.na1.netsuite.com%2Fapp%2Fsite%2Fhosting%2Frestlet.nl&deploy%3D1%26oauth_consumer_key%3D17840f699409f5031c22a6e4af15961e9627c168cd0ae71f9c14f71b4097a0b6%26oauth_nonce%3D1444927941574%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1444927941%26oauth_token%3Df3c29a8b2c7988e00947d8c5836ef0ff1883556d96b8beac5bbbdda001ba0292%26realm%3DTSTDRV1403065%26script%3D546

Then I generated "signature" using this string and "consumer_secret&token_secret". The header then had the following look:

OAuth oauth_signature="7doRJOJyV36Av4e4BBUgoOPn7Vk%3D", oauth_nonce="1444927941574", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="17840f699409f5031c22a6e4af15961e9627c168cd0ae71f9c14f71b4097a0b6", oauth_token="f3c29a8b2c7988e00947d8c5836ef0ff1883556d96b8beac5bbbdda001ba0292", oauth_timestamp="1444927941", realm="TSTDRV1403065"

Then I used this header with my rest-client and got the "INVALID_LOGIN_ATTEMPT"-error (while NLAuth header works perfectly with this rest-client, this user and this dummy-restlet).

I checked my signature-algorithm with this online-tool: http://nouncer.com/oauth/authentication.html It shows the same results with the same tokens/timestamp/nonce/etc. I suppose I missed something during setting up NetSuite environment (user/role/something else). On the other side the NetSuite HelpCenter says: "An INVALID_LOGIN_ATTEMPT error is returned when the nonce, consumer key, token, or signature in the OAuth header is invalid".

Please tell me what is wrong.

回答1:

The steps seems to be correct as you are able to get consumer and user keys.

The probable error could be in your java code. I was able to get a successful response from a RESTLet using Java code. I used Scribe-Java as OAuth 1a client library.

Below is my main method

OAuthConfig authConfig = new OAuthConfig("CONSUMER_KEY", "CONSUMER_SECRET", null, SignatureType.Header, null, null);
    Token token = new Token("TOKEN_ID", "TOKEN_SECRET");
    OAuth10aServiceImpl auth10aServiceImpl = new OAuth10aServiceImpl(new NetSuiteApi(), authConfig);
    OAuthRequest request = new OAuthRequest(Verb.GET, "RESTLET_URL");
    request.setRealm("NS_ACCOUNT_ID");
    auth10aServiceImpl.signRequest(token, request);
    Response response = request.send();

you will also need to write NetSuiteApi class, as it is required by Scribe. Just, a framework overhead

import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.Token;

public class NetSuiteApi extends DefaultApi10a {

@Override
public String getAccessTokenEndpoint() {
    // TODO Auto-generated method stub
    return null;
}

@Override
public String getAuthorizationUrl(Token arg0) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public String getRequestTokenEndpoint() {
    // TODO Auto-generated method stub
    return null;
}

}

Also, make sure that the user or user's has access to execute the RESTlet in its deployment.