oAuth 401 Unauthorized


#1

I keep getting 401 unauthorized. I think that I was successfully posting to the 1.1 auth at one point but something changed in the last 4 weeks or so (not in my code, did oauth get stricter?).

Does anyone see anything that could be potentially causing the problem? Is there anything I can add to the code to get more info on why it’s failing?

    Private Function NewTweet(status As String) As WebResponse

        Try

            Dim oauth_token = "token"              'access token
            Dim oauth_token_secret = "secret"                'acces token secret
            Dim oauth_consumer_key = "key"                                   'consumer key
            Dim oauth_consumer_secret = "secret"            'consumer secret

            Dim oauth_version As String = "1.0"
            Dim oauth_signature_method As String = "HMAC-SHA1"
            Dim oauth_nonce = Convert.ToBase64String(New ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture)))

            Dim timeSpan As TimeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)
            Dim oauth_timestamp As String = Convert.ToInt64(timeSpan.TotalSeconds).ToString(CultureInfo.InvariantCulture)

            Dim resource_url As String = "https://api.twitter.com/1.1/statuses/update.json"

            Dim baseFormat As String = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&status={6}"

            Dim baseString As String = String.Format(baseFormat, oauth_consumer_key, oauth_nonce, oauth_signature_method, oauth_timestamp, oauth_token, oauth_version, Uri.EscapeDataString(status))

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

            Dim compositeKey As String = 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_consumer_key=""{0}"", " & _
                                "oauth_nonce=""{1}"", " & _
                                "oauth_signature=""{2}"", " & _
                                "oauth_signature_method=""{3}"", " & _
                                "oauth_timestamp=""{4}"", " & _
                                "oauth_token=""{5}"", " & _
                                "oauth_version=""{6}"""

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

            '-------------------------------------------------------

            Dim postBody As String = "status=" & Uri.EscapeDataString(status)

            ServicePointManager.Expect100Continue = False

            Dim request As HttpWebRequest = DirectCast(WebRequest.Create(resource_url), HttpWebRequest)
            request.Headers.Add("Authorization", authHeader)
            request.Method = "POST"
            request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8"

            Using stream As Stream = request.GetRequestStream()
                Dim content As Byte() = ASCIIEncoding.ASCII.GetBytes(postBody)
                stream.Write(content, 0, content.Length)
            End Using

            Dim response As WebResponse = request.GetResponse()

            Return response

        Catch ex As Exception

            Return Nothing

        End Try

    End Function

#2

At first glance this looks correct. The most recent “more strict” we got on 1.1 was more explicitly requiring that Content-Header, but it looks like you’re already sending it. Are you sending a Content-Length header as well?