Updating a SOAP Web Services Integration to Send Token-Based Authentication Details

This procedure and Java code snippets demonstrate how to update an application with token-based authentication (TBA) details.

Use the TokenPassport and TokenPassportSignature complex types to send TBA details. These types are defined in the Core XSD. See also TokenPassport Complex Type.

This example uses request-level credentials. With TBA, structure your SOAP request this way. The login operation isn't supported. For additional requirements, see Requirements for Using Token-Based Authentication.

Note:

With token-based authentication, don't include an application ID in your request. Including an application ID with TBA will cause the request to fail.

To update a SOAP web services integration to send token-based authentication details:

  1. Add logic for creating an RFC 2104-compliant signature. For example, you could add a method that has three arguments: a base string, a key, and an algorithm. Later, you could call this method by passing values specific to your request. (For details on the data needed to create the correct base string and key values, see TokenPassportSignature.)

    This example doesn't require the use of a third-party library. However, the javax.crypto package is used.

                    protected String computeShaHash(String baseString, String key, String algorithm) throws Exception {
    
       byte[] bytes = key.getBytes();
       SecretKeySpec mySigningKey = new SecretKeySpec(bytes, algorithm);
    
       Mac messageAuthenticationCode = Mac.getInstance(algorithm);
    
       messageAuthenticationCode.init(mySigningKey);
    
       byte[] hash = messageAuthenticationCode.doFinal(baseString.getBytes());
    
       String result = new String(java.util.Base64.getEncoder().encode(hash));
    
       return result;
    } 
    
                  
  2. Using variables that reflect data specific to your request, add logic for calling the computeShaHash method you created in step 1 to calculate a signature.

                    public String computeSignature(
          String account,
          String consumerKey,
          String consumerSecret,
          String token,
          String tokenSecret,
          String nonce,
          Long timeStamp
    ) throws Exception {
       String baseString = account + "&" + consumerKey + "&" + token + "&" + nonce + "&" + timeStamp;
    
       String key = consumerSecret + '&' + tokenSecret;
    
       String signature = computeShaHash(baseString, key, "HmacSHA256");
    
       return signature;
    } 
    
                  
  3. Add logic for creating a TokenPassport SOAP header.

                    @Override
       public void setTokenPassport(
             String account,
             String consumerKey,
             String token,
             String nonce,
             Date timestamp,
             String signatureAlgorithm,
             String signature
       ) throws Exception
       {
          initPort();
          if(m_tokenPassport == null)
          {
             m_tokenPassport = new TokenPassport();
             ((Stub) m_port).setHeader( m_sMessagesUrn, "tokenPassport", m_tokenPassport);
          }
          m_tokenPassport.setAccount(account);
          m_tokenPassport.setConsumerKey(consumerKey);
          m_tokenPassport.setToken(token);
          m_tokenPassport.setNonce(nonce);
          m_tokenPassport.setTimestamp(timestamp.getTime());
          TokenPassportSignature signatureElement = new TokenPassportSignature();
          signatureElement.setAlgorithm(signatureAlgorithm);
          signatureElement.set_value(signature);
          m_tokenPassport.setSignature(signatureElement);
       } 
    
                  
  4. To add your token-based authentication credentials to a request, add logic similar to the following. Notice that in this example, the exact variables are defined. This example calls the computeSignature method from step 3 to create the signature. It also sets the values in the fields of the TokenPassport object created in step 4. These values are later visible in the SOAP request. By contrast, the consumer secret and token secret aren't explicitly part of the SOAP request. They are represented only in the signature.

                    public void testGetServerTimeWithTBA() throws Exception
    {
    // Constants
       String sCompId = "1234567";
       String consumerKey = "71cc02b731f05895561ef0862d71553a3ac99498a947c3b7beaf4a1e4a29f7c4";
       String consumerSecret = "7278da58caf07f5c336301a601203d10a58e948efa280f0618e25fcee1ef2abd";
       String tokenId = "89e08d9767c5ac85b374415725567d05b54ecf0960ad2470894a52f741020d82";
       String tokenSecret = "060cd9ab3ffbbe1e3d3918e90165ffd37ab12acc76b4691046e2d29c7d7674c2";
       String algorithm = SignatureAlgorithm._HMAC_SHA256;
    
    // Nonce and timeStamp must be unique for each request. Also, make sure that the nonce value you 
    // generate does not contain special characters.
    
       String nonce = RandomStringUtils.randomAlphanumeric(20);
       Long timeStamp = System.currentTimeMillis() / 1000L;
    
       String signature = c.computeSignature(sCompId, consumerKey, consumerSecret, tokenId, tokenSecret, nonce, timeStamp);
    
    // create and set TokenPassport SOAP Header
    // notice - no secrets are included in this call
          c.setTokenPassport(
                sCompId,
                consumerKey,
                tokenId,
                nonce,
                new Date(timeStamp),
                algorithm,
                signature);
    
          c.getPort().getServerTime();
       } 
    
                  

    The following example shows how the resulting SOAP request should appear.

                    <ns:tokenPassport soap:actor="http://schemas.xmlsoap.org/soap/actor/next" soap:mustUnderstand="0" xmlns:ns="urn:messages_2017_1.platform.webservices.netsuite.com">
       <ns:account>1234567</ns:account>
       <ns:consumerKey>71cc02b731f05895561ef0862d71553a3ac99498a947c3b7beaf4a1e4a29f7c4</ns:consumerKey>
       <ns:token>89e08d9767c5ac85b374415725567d05b54ecf0960ad2470894a52f741020d82</ns:token>
       <ns:nonce>6obMKq0tmY8ylVOdEkA1</ns:nonce>
       <ns:timestamp>1439829974</ns:timestamp>
       <ns:signature algorithm="HMAC_SHA256">fzGxUBu6SZvGqv5hk8P4ou2DPthSxXtJ4zJIeCBQK5A=</ns:signature>
    </ns:tokenPassport> 
    
                  
    Note:

    For the signature algorithm value, you can use either a hyphen or an underscore. (For example, HMAC-SHA256 or HMAC_SHA256). However, the underscore is only acceptable in a SOAP web services request. SOAP web services integrations use the NetSuite TokenPassport complex type. The underscore is used by the SignatureAlgorithm enumeration, which is defined in the core types XSD.

    Important:

    Only a hyphen is acceptable in the algorithm value for RESTlets and REST web services. RESTlets and REST web services integrations use the OAuth protocol, which requires the use of a hyphen, for example, HMAC-SHA256. For more information, see RESTlet Authentication and Setting Up Authentication.

Related Topics

General Notices