Logrus Logrus - 1 month ago 15
Java Question

Reach a NetSuite RESTlet via OAuth

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.

Answer

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.