1

In a VB .net environment, I am making the following call, trying to implement the authorize step of an OAuth process to connect to an Accelo API (a time-entry and billing type of app). I'm trying to get an access token:

Dim jsonstring = "{'Content-Type':'Application/x-www-Form-urlencoded', 
'authorization':'Basic MDBhM...GbG5oLlZB'}"
Dim data = Encoding.UTF8.GetBytes(jsonstring)
Dim result_post = SendRequest(New Uri("https://ourinfo.api.accelo.com/oauth2/v0/token"), data, "application/json", "POST")

with the function defined as this:

Private Function SendRequest(uri As Uri, jsonDataBytes As Byte(), contentType As String, method As String) As String
    Dim req As WebRequest = WebRequest.Create(uri)
    req.ContentType = contentType
    req.Method = method
    req.ContentLength = jsonDataBytes.Length


    Dim stream = req.GetRequestStream()
    stream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
    'stream.Close()

    Dim response = req.GetResponse().GetResponseStream()

    Dim reader As New StreamReader(response)
    Dim res = reader.ReadToEnd()
    reader.Close()
    response.Close()

    Return res
End Function

and I keep receiving an error on this line:

Dim response = req.GetResponse().GetResponseStream()

Saying

 "System.Net.WebException: 'The remote server returned an error: (400) Bad Request.'"

It seems to me like a syntax error or something in the way my calling method is formed or the format of the parameters passed. I got the HTTP request code suggestion/format from here:

How to POST a JSON to a specific url using VB.NET?

and I'm using the Accelo API to set the content-type and authorization "basic" part where the string is encoded in Base 64. This is a service application so i'm supposed to be able to get the token in 1-step (no user confirmation is required). I already have a "token" from when I registered, but the API still indicates I should do this code. i'm following this:

https://api.accelo.com/docs/?_ga=2.218971609.1390377756.1568376911-2053161277.1565440093#service-applications

Can anyone tell me what exactly I'm doing wrong here? I'm confused and this is the first time I'm trying to implement OAuth.

There is some example code in the API documentation that looks like this:

POST /oauth2/v0/token HTTP/1.1
Host: planet-express.api.accelo.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic {client_credentials}

grant_type=client_credentials
scope=read(staff)

And I'm not sure the difference between the = and : syntax purposes. I was not able to search and find any answers to whether I'm calling everything correctly. Should I be passing the scope and grant_type in the JSON string, or setting it as a property on "req" object in the "SendRequest" function? I know that the grant_type is supposedly required but how do I set it?

What's the token I received initially when I registered, if I'm supposed to get a token this way?

PBJ
  • 354
  • 2
  • 15
  • Content Type and Authorization should likely be in the http header, not the body (though there is a enumerated property for Content Type). – MarkL Sep 13 '19 at 17:17
  • Yes sir, thank you. I realize my entire script was badly formatted because I misunderstood the call method entirely. I was misunderstanding the headers vs data. – PBJ Sep 13 '19 at 18:18

1 Answers1

1

I got it working with the help of a colleague. Apparently I was confusing header data and the json "data,"and I was not formatting the data correctly either. I should have been looking at the WebResponse too, not only the WebRequest. I changed my code to the following, which works now:

Sub SendRequestGetAccess()
    Dim req As WebRequest = WebRequest.Create(uri)
    req.Method = "POST"
    req.Headers.Add("Authorization", "Basic " & "MDB....")
    req.ContentType = "Application/x-www-Form-urlencoded"
    req.ContentLength = jsonDataBytes.Length
    Dim stream = req.GetRequestStream()
    stream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
    stream.Close()

    Dim response As WebResponse = req.GetResponse()
    Console.WriteLine((CType(response, HttpWebResponse)).StatusDescription)
    Dim dataStream = response.GetResponseStream()
    Dim reader As StreamReader = New StreamReader(dataStream)
    Dim responseFromServer As String = reader.ReadToEnd()
    Console.WriteLine(responseFromServer)
    reader.Close()
    dataStream.Close()
    response.Close()
    'Dim firstItem = jsonResult.Item("data").Item(0).Value(Of String)("token")
    Dim j As Object = New JavaScriptSerializer().Deserialize(Of Object)(responseFromServer)
    Dim _itemvalue = j("itemkey")

End Sub

And I had to use dashes instead of colons in my json data:

 Dim jsonstring = "grant=creds" & "&scope=read"
 Dim data = Encoding.UTF8.GetBytes(jsonstring)
 SendRequestGetAccess(New Uri("https...site.com/oauth2/v0/token"), data)
PBJ
  • 354
  • 2
  • 15