Reply
Regular Contributor
wakurth
Posts: 12
0
Accepted Solution

404 Bad Request: when trying to get a token response with grant_type=password

[ Edited ]

I'm trying to get a token response using grant_type=password OAuth and I keep getting a 404 bad request. I use methods like these to access all sorts of other REST api's soooo, I'm not sure what I'm doing wrong. Maybe it's the ContentType? 

 

I've tried just appending the PostData like query strings to the end of the url.... and posting it in the request stream... maybe it needs to be in a header? 

 

Note: I've also tried this endpoint: "https://login.salesforce.com/services/oauth2/authorize" for AUTH_TOKEN_URL

 

Here's the last thing I've tried (e.g. adding auth data into the header)... still no luck:

 

Private Const AUTH_TOKEN_URL As String = "https://login.salesforce.com/services/oauth2/token"

 

Public Shared Function GetSalesForceAccessToken() As TokenResponse

 

Dim request As HttpWebRequest = GenerateWebRequest(AUTH_TOKEN_URL, "POST")

Dim json As String = ProcessWebRequest(request)

Dim js As JavaScriptSerializer = New JavaScriptSerializer

Dim tr As TokenResponse = js.Deserialize(Of TokenResponse)(json)

Return tr

 

End Function

 

 

Private Shared Function GenerateWebRequest(ByVal url As String, ByVal method As String) As HttpWebRequest

 

Dim request As HttpWebRequest = DirectCast(System.Net.WebRequest.Create(url), HttpWebRequest)
request.Method = method
request.Credentials = CredentialCache.DefaultCredentials
request.AllowWriteStreamBuffering = True
request.ServicePoint.Expect100Continue = False

Dim postData As String = GetPostData()

request.Headers.Add("Authorization", postData)

request.ContentType = "application/json"

 

Return request

 

End Function

 

 

 Private Shared Function GetPostData() As String

 

Return "OAuth grant_type=""password"", client_id=""" & AuthHelper.ConsumerKey & """ , client_secret=""" & AuthHelper.ConsumerSecret & """, username=""" & AuthHelper.UserName & """, password=""" & AuthHelper.Password & """"

End Function

 

Private Shared Function ProcessWebRequest(ByVal webRequest As HttpWebRequest) As String

 

Dim responseReader As StreamReader = Nothing
Dim responseData As String = ""

Try
responseReader = New StreamReader(webRequest.GetResponse().GetResponseStream())
responseData = responseReader.ReadToEnd()
Catch we As WebException
Throw we 'right here is where I get the 404
Finally
webRequest.GetResponse().GetResponseStream().Close()
responseReader.Close()
responseReader = Nothing
End Try

Return responseData

 

 

End Function

 

 

Moderator
SimonF
Posts: 7,984
0

Re: 404 Bad Request: when trying to get a token response with grant_type=password

You seen to be sending the form payload in the Authorization header, which is not correct, it needs to be in the POST body. you alos set the request contentType to be json, but you're not sending json. you need to sent the paramters as a standard html forms POST type request.

Cheers
Simon
docs | blog | twitter
Regular Contributor
wakurth
Posts: 12
0

Re: 404 Bad Request: when trying to get a token response with grant_type=password

I made these changes (which make this a basic POST request)... still no luck... does there need to be a content dispostion, and content type declared in the body maybe?

 

Private Const AUTH_TOKEN_URL As String = "https://login.salesforce.com/services/oauth2/authorize"

 

Public Shared Function GetSalesForceAccessToken() As TokenResponse

 

Dim request As HttpWebRequest = DirectCast(System.Net.WebRequest.Create(AUTH_TOKEN_URL), HttpWebRequest)
request.Method = "POST"

Dim dataToSend As Byte() = Encoding.UTF8.GetBytes(GetPostData())
request.ContentLength = dataToSend.Length

Dim reqStream As Stream = request.GetRequestStream()

reqStream.Write(dataToSend, 0, dataToSend.Length)
reqStream.Close()
reqStream.Dispose()

Dim json As String = ProcessWebRequest(request)

Dim js As JavaScriptSerializer = New JavaScriptSerializer

Dim tr As TokenResponse = js.Deserialize(Of TokenResponse)(json)

Return tr

 

End Function

 

Private Shared Function GetPostData() As String

 

Dim body As New StringBuilder()

body.Append("&grant_type=password&")

body.Append("client_id=" + AuthHelper.ConsumerKey + "&")

body.Append("client_secret=" + AuthHelper.ConsumerSecret + "&")

body.Append("username=" + AuthHelper.UserName + "&")

body.Append("password=" + AuthHelper.Password)

Return body.ToString()

 

End Function

 

Private Shared Function ProcessWebRequest(ByVal webRequest As HttpWebRequest) As String

 

Dim responseReader As StreamReader = Nothing
Dim responseData As String = ""

Try
responseReader = New StreamReader(webRequest.GetResponse().GetResponseStream())
responseData = responseReader.ReadToEnd()
Catch we As WebException
Throw we
Finally
webRequest.GetResponse().GetResponseStream().Close()
responseReader.Close()
responseReader = Nothing
End Try

Return responseData

 

End Function

Regular Contributor
wakurth
Posts: 12
0

Re: 404 Bad Request: when trying to get a token response with grant_type=password

I also tried creating the Post body data like so... no luck: There has to be some fundamental detail about how this request needs to be made that is being left out....

 

Private Shared Function GetPostData() As String


Dim boundary As String = DateTime.Now.Ticks.ToString("x")

Dim separator As String = String.Format("--{0}", boundary)

Dim footer As String = String.Format("\r\n{0}--\r\n", separator)


Dim body As New StringBuilder()

body.AppendLine(separator)

body.AppendLine("Content-Disposition: form-data;")

body.AppendLine()

body.AppendLine("&grant_type=password&client_id=" + AuthHelper.ConsumerKey + "&")

body.Append("client_secret=" + AuthHelper.ConsumerSecret + "&")

body.Append("username=" + AuthHelper.UserName + "&")

body.Append("password=" + AuthHelper.Password)

body.AppendLine()
body.AppendLine(footer)

Return body.ToString()

 

End Function

Moderator
SimonF
Posts: 7,984
0

Re: 404 Bad Request: when trying to get a token response with grant_type=password

Yes, you'll need to set the cotent type to application/x-www-form-urlencoded , and the username/password grant requests should goto the token endpoint /services/oauth2/token, and your body string should not start with a &

Cheers
Simon
docs | blog | twitter
Regular Contributor
wakurth
Posts: 12
0

Re: 404 Bad Request: when trying to get a token response with grant_type=password

Sooo, I think this is what you have described, but still no luck... hrmmmm :/

 

Public Class SalesForceOAuth

 

Private Const AUTH_TOKEN_URL As String = "https://login.salesforce.com/services/oauth2/token"

 

Public Shared Function GetSalesForceTokenResponse() As TokenResponse

 

Dim data As String = "grant_type=basic-credentials&client_id={0}&client_secret={1}&username={2}&password={3}"

data = String.Format(data, AuthHelper.ConsumerKey, AuthHelper.ConsumerSecret, AuthHelper.UserName, AuthHelper.Password)

Dim json As String = PostData(AUTH_TOKEN_URL, data)

Dim jss As New JavaScriptSerializer

Dim t As TokenResponse = jss.Deserialize(Of TokenResponse)(json)

Return t

 

End Function

 

 

Private Shared Function PostData(ByVal url As String, ByVal data As String) As String

 

Dim request As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
request.Method = "POST"
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = data.Length

Dim encoding As Encoding = New UTF8Encoding(False)

Dim writer As New StreamWriter(request.GetRequestStream(), encoding)
writer.Write(data)
writer.Close()
writer.Dispose()
Dim response As String = WebResponseGet(request)
Return response

 

End Function

 

 

Private Shared Function WebResponseGet(ByVal webRequest As HttpWebRequest) As String


Dim responseReader As StreamReader = Nothing
Dim responseData As String = ""
Try
responseReader = New StreamReader(webRequest.GetResponse().GetResponseStream())
responseData = responseReader.ReadToEnd()
Catch
Throw
Finally
webRequest.GetResponse().GetResponseStream().Close()
responseReader.Close()
responseReader = Nothing
End Try
Return responseData


End Function

 

 

End Class

Regular Contributor
wakurth
Posts: 12
0

Re: 404 Bad Request: when trying to get a token response with grant_type=password

This did it... Thank you.

 

Imports System.Net
Imports System.Collections.Specialized
Imports System.Web.Script.Serialization
Imports System.IO

Public Class SalesForceOAuth

Private Const AUTH_TOKEN_URL As String = "https://login.salesforce.com/services/oauth2/token"

Public Shared Function GetSalesForceTokenResponse() As TokenResponse

Dim data As String = "grant_type=password&client_id={0}&client_secret={1}&username={2}&password={3}"

data = String.Format(data, AuthHelper.ConsumerKey, AuthHelper.ConsumerSecret, AuthHelper.UserName, AuthHelper.Password(True))

Dim json As String = PostData(AUTH_TOKEN_URL, data)

Dim jss As New JavaScriptSerializer

Dim t As TokenResponse = jss.Deserialize(Of TokenResponse)(json)

Return t

End Function

Private Shared Function PostData(ByVal url As String, ByVal data As String) As String

Dim request As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
request.Method = "POST"
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = data.Length

'Dim encoding As Encoding = New UTF8Encoding(False)

Dim writer As New StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII)
writer.Write(data)
writer.Close()
writer.Dispose()

Dim response As String = WebResponseGet(request)
Return response

End Function

Private Shared Function WebResponseGet(ByVal webRequest As HttpWebRequest) As String
Dim responseReader As StreamReader = Nothing
Dim responseData As String = ""
Try
responseReader = New StreamReader(webRequest.GetResponse().GetResponseStream())
responseData = responseReader.ReadToEnd()
Catch
Throw
Finally
webRequest.GetResponse().GetResponseStream().Close()
responseReader.Close()
responseReader = Nothing
End Try
Return responseData
End Function

End Class


Public Class TokenResponse

Public Property id As String

Public Property issued_at As String

Public Property refresh_token As String

Public Property instance_url As String

Public Property signature As String

Public Property access_token As String

End Class

 

Regular Contributor
wakurth
Posts: 12
0

Re: 404 Bad Request: when trying to get a token response with grant_type=password

is the issued_at value epoc time?