0

I have an application that is using username and password for authentication to connect to net suite. the authentication method for net suite has changed to token base. After looking at 25 different possible solutions I have I get a 401 error. here's my code: Authorization type OAuth 1.0

Dim oauth_token = "xx"
        Dim oauth_token_secret = "xx"
        Dim oauth_consumer_key = "xx"
        Dim oauth_consumer_secret = "xx"
        Dim oauth_version = "1.0"
        Dim oauth_signature_method = "HMAC-SHA1"
        Dim oauth_nonce = Convert.ToBase64String(New ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()))
        Dim timeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
        Dim oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString()
        Dim resource_url = "https://646033-sb3.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=x&deploy=x"
          Dim baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" & "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}"
        Dim baseString = String.Format(baseFormat, oauth_consumer_key, oauth_nonce, oauth_signature_method, oauth_timestamp, oauth_token, oauth_version)

        baseString = String.Concat("PUT&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString))

        Dim compositeKey = String.Concat(Uri.EscapeDataString(oauth_consumer_secret), "&", Uri.EscapeDataString(oauth_token_secret))

        Dim oauth_signature As String
        Using hasher As New HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))
            oauth_signature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)))
        End Using

        'Dim headerFormat = "OAuth oauth_signature_method=""{0}"", " + "oauth_consumer_key=""{1}"", " + "oauth_token=""{2}"", oauth_signature=""{3}"", " + "oauth_version=""{4}"""

        Dim headerFormat = "OAuth oauth_nonce=""{0}"", oauth_signature_method=""{1}"", " & "oauth_timestamp=""{2}"", oauth_consumer_key=""{3}"", " & "oauth_token=""{4}"", oauth_signature=""{5}"", " & "oauth_version=""{6}"""

        'Dim authHeader = String.Format(headerFormat, Uri.EscapeDataString(oauth_signature_method), Uri.EscapeDataString(oauth_consumer_key), Uri.EscapeDataString(oauth_token),
        'Uri.EscapeDataString(oauth_signature), Uri.EscapeDataString(oauth_version))

        Dim authHeader = String.Format(headerFormat, Uri.EscapeDataString(oauth_nonce), Uri.EscapeDataString(oauth_signature_method), Uri.EscapeDataString(oauth_timestamp), Uri.EscapeDataString(oauth_consumer_key), Uri.EscapeDataString(oauth_token), Uri.EscapeDataString(oauth_signature), Uri.EscapeDataString(oauth_version))
        '****************************************************************************************************************************
        Dim Request As HttpWebRequest = WebRequest.Create("https://646033-sb3.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=1072&deploy=1")
        Request.Headers.Add("Authorization", authHeader)
        Request.ContentType = "application/json"
        Request.Method = "PUT"

        Using streamWriter = New StreamWriter(Request.GetRequestStream())
            Dim jsonFormatted As String = Regex.Unescape(JSon)
            streamWriter.Write(jsonFormatted)
            Console.WriteLine(authHeader)
        End Using

When I test the connection in postman the chrome app it works fine. I think the problem is in how I'm creating nonce value but not sure since this my first time dealing with token based authentication.

I appreciate everyone time and comments Thank you.

1 Answers1

0

You need to escape the signature after hashing it. The specification says that escaping per RFC3986 is required, but i have seen Netsuite examples that only escape the plus sign (+).

'Place within or after your Using block after the hash generation

oauth_signature = oauth_signature.Replace("+", "%2B")

Or - to do a full escaping via RFC3986 you can use this example Note: I found this function on another slashdot article: How to get Uri.EscapeDataString to comply with RFC 3986 'I just ported it from C# to VB.NET here:

oauth_signature = EscapeUriDataStringRfc3986(signatureString)

Friend Shared Function EscapeUriDataStringRfc3986(ByVal value As String) As String
    ' Start with RFC 2396 escaping by calling the .NET method to do the work.
    ' This MAY sometimes exhibit RFC 3986 behavior (according to the documentation).
    ' If it does, the escaping we do that follows it will be a no-op since the
    ' characters we search for to replace can't possibly exist in the string.
    Dim escaped As StringBuilder = New StringBuilder(Uri.EscapeDataString(value))

    ' Upgrade the escaping to RFC 3986, if necessary.
    Dim i As Integer = 0
    Do While (i < UriRfc3986CharsToEscape.Length)
        escaped.Replace(UriRfc3986CharsToEscape(i), Uri.HexEscape(UriRfc3986CharsToEscape(i)(0)))
        i = (i + 1)
    Loop

    '' Return the fully-RFC3986-escaped string.
    Return escaped.ToString
End Function
VBGuru
  • 1
  • Thank you VBGuru when I try this code: oauth_signature = auth_signature.Replace("+", "%2B") I get the 401 error My authorization header looks like this:authorization: OAuth_realm="646033_SB3",oauth_consumer_key="xx",oauth_token="xx",oauth_signature_method="HMAC-SHA1",oauth_timestamp="xx",oauth_nonce="xx",oauth_version="1.0",oauth_signature="gBCyHPJbRcb2WwmZdfkq7GTRprI%3D" – Chuckie Chiller Mar 28 '19 at 14:36
  • When I used Escapeuridatastring function same error header looks like authorization: OAuth_realm="646033_SB3",oauth_consumer_key="xx",oauth_token="xx",oauth_signature_method="HMAC-SHA1",oauth_timestamp="xx",oauth_nonce="xx",oauth_version="1.0",oauth_signature="IC7kD8DE0rOL2jmXoZ1p0n5ywQo%253D" Content-Type: application/json Host: 646033-sb3.restlets.api.netsuite.com – Chuckie Chiller Mar 28 '19 at 14:44
  • Yes, the 401 error means that you have a problem with your authorization header an not your signature. One thing i notice is that you have OAuth_realm listed in your header - this is incorrect. It should be OAuth real=. e.g. OAuth realm="646033_SB3",oauth_consumer_key="xx",oauth_token="xx",oauth_signature_method="HMAC-SHA1",oauth_timestamp="xx",oauth_nonce="xx",oauth_version="1.0",oauth_signature="gBCyHPJbRcb2WwmZdfkq7GTRprI%3D" – VBGuru Mar 31 '19 at 19:29
  • When I format the header as suggested I get a 500 error. This error is on the server side from what I was able to research. But there is nothing wrong on the server side I can connect to it using chrome extension "postman' and it works fine. I appreciate your time working on this. – Chuckie Chiller Apr 01 '19 at 13:38