5

I am using the Netsuite web services (SuiteTalk) api but keep getting a Invalid login attempt error when using a tokenPassport. As the token authentication seems quite complex I will include all the steps i have taken.

I have retreived the account id from Setup > Integration > Web Service Preferences

I have set up a new role with all Authentication boxes unchecked. In the permissions > Setup I have added the following permissions

  • Access Token Management = Full

  • User Access Tokens = Full

  • Web Services = Full

I have added the new role to my User Access Permissions

I have created a new application in Setup > Integration > Manager Integrations Under the Authentication tab I have selected TOKEN-BASED Authentication

I have created a new access token in the Setup > Users/Roles > Access Tokens with the following settings

  • Application Name = the new applicaiton

  • User = me

  • Role = the new role

  • Token Name = renamed to something that makes sense

My request xml looks like

<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:msg="urn:messages_2016_2.platform.webservices.netsuite.com" 
xmlns:core="urn:core_2016_2.platform.webservices.netsuite.com">
  <env:Header>
    <msg:tokenPassport>
      <core:account>123XXXX_SB1</core:account>
      <core:consumerKey>MY_CONSUMER_KEY</cre:consumerKey>
      <core:token>MY_TOKEN_ID</core:token>
      <core:nonce>ZcVszy7ySJ3Ji8PIgwlW</core:nonce>
      <core:timestamp>1530692570</core:timestamp>
      <core:signature algorithm="HMAC-SHA256">nN7V4PH9qWNT9BocMQzKcFetqZ3QxpxutDJ8iZjSmH8=</core:signature>
    </msg:tokenPassport>
  </env:Header>
  <env:Body>
    <msg:get>
      <msg:baseRef xsi:type="core:RecordRef" internalId="1234567" type="customer"/>
    </msg:get>
  </env:Body>
</env:Envelope>  

I am using the following ruby class to generate the nonce and signature

class NetSuiteToken
    attr_reader :account, :consumer_key, :consumer_secret, :token_id, :token_secret

    def initialize(account, consumer_key, consumer_secret, token_id, token_secret)
      @account = account.to_s
      @consumer_key = consumer_key
      @consumer_secret = consumer_secret
      @token_id = token_id
      @token_secret = token_secret
    end

    def passport
      {
        'msg:tokenPassport' => {
          'core:account' => account,
          'core:consumerKey' => consumer_key,
          'core:token' => token_id,
          'core:nonce' => nonce,
          'core:timestamp' => timestamp,
          'core:signature' => signature,
          :attributes! => { 'core:signature' => { 'algorithm' => 'HMAC-SHA256' } }
        }
      }
    end

    private

    def signature
      Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), signature_key, signature_data))
    end

    def signature_key
      "#{consumer_secret}&#{token_secret}"
    end

    def signature_data
      "#{account}&#{consumer_key}&#{token_id}&#{nonce}&#{timestamp}"
    end

    def nonce
      @nonce ||= Array.new(20) { alphanumerics.sample }.join
    end

    def alphanumerics
      [*'0'..'9',*'A'..'Z',*'a'..'z']
    end

    def timestamp
      @timestamp ||= Time.now.to_i
    end
end

If anybody could offer any assistance it would be highly appreciated.

user346443
  • 4,672
  • 15
  • 57
  • 80
  • Are you getting any response from the API when you submit your SOAP message? – Charl Jul 04 '18 at 10:14
  • Yes. soapenv:Server.userException Invalid login attempt. USER_ERROR Invalid login attempt. sb-partners-java054.svale.netledger.com – user346443 Jul 05 '18 at 04:17
  • 1
    The only difference I see between your code and my own is that you use SHA256 and I use SHA1. Both are supported tough, so I'm not sure what the issue is. – Charl Jul 05 '18 at 05:32
  • Thanks Carl. I appreciate the confirmation. – user346443 Jul 05 '18 at 11:03

3 Answers3

4

You need to add the role permission called "Log in using Access Tokens"

dcrs
  • 294
  • 1
  • 4
3

Just ran into a new flavor of this that was a giant time waster.

Scenario was as follows - After a SANDBOX refresh, new Token was generated for User, Role & Integration. Note that User, Role & Integration were refreshed from PROD.

No matter what was done, attempt to use Token with SuiteTalk generated a "permission_denied" error in Login Audit Trail.

Per NS Support - I added a New Role, a New Integration & Generated New Tokens with those and still received "permission_denied" for the User.

Solution was to Add & then Remove a Global Permission from each Impacted User.

Once I added & removed any Global Permission from each impacted user, this issue resolved. I stress “any” Permission (Any global permission, even a global permission completely unrelated to the functions being used)

2

I've met the same issue recently.

Try to log in your Netsuite and check Login audit trait (make sure that you are using the advanced search, and have added details column).

So, in the detail column you can find out what the true problem is with your login.

As for me, it was InvalidTimestamp first, and the reason is that I reused the same timestamp for my soap requests.

The second error is permission_denied, this one is kinda tricky, and wasted my a few hours, and finally it turns out that my college have set the wrong token.

Hope this could help.

Mengnan
  • 62
  • 3
  • Hey, can you let me know if you used a package in Ruby or manually created the XML data? New to this and am trying to figure out how to accomplish a login using soap and tba. – tkansara Jan 01 '19 at 17:34