title: Twitter API returns 401
body: <p>This is a test for an application which will be using the twitter API to block certain users. While submitting the following HTTP POST, it always returns 401 Unauthorized. Note the keys ("###") have been removed but they are found in the Twitter Developers tool for the app. </p>
  
  <p>Seems like this should be easily available, so Im hoping we can provide a easy solution for the community. If you help me figure this one out I will refactor into a nicer code base and make it available for all.</p>
  
  <p>FYI - I followed instructions from Twitter at <a href="https://dev.twitter.com/docs/auth/creating-signature#note-lexigraphically" rel="nofollow">https://dev.twitter.com/docs/auth/creating-signature#note-lexigraphically</a></p>
  
  <pre><code>Protected Sub btnBlock_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnBlock.Click
      Try
          Dim oauth_signature_method = "HMAC-SHA1" 'goes in header
          Dim oauth_consumer_key As String = "###" 'goes in header
          Dim oauth_token As String = "###" 'goes in header
          Dim oauth_version As String = "1.0" 'goes in header
          Dim oauth_timestamp As String = GenerateTimeStamp() 'goes in header 
          Dim oRandom As New Random()
          Dim oauth_nonce As String = GenerateNonce(oRandom) 'goes in header
          Dim screen_name As String = txtUserName.Text.Trim
          Dim sURL As String = "https://api.twitter.com/1.1/blocks/create.json"
          Dim sHTTPMethod As String = "POST"
  
          Dim dSignatureParameters As New SortedDictionary(Of String, String)
          dSignatureParameters.Add("oauth_signature_method", oauth_signature_method)
          dSignatureParameters.Add("oauth_consumer_key", oauth_consumer_key)
          dSignatureParameters.Add("oauth_token", oauth_token)
          dSignatureParameters.Add("oauth_version", oauth_version)
          dSignatureParameters.Add("oauth_timestamp", oauth_timestamp)
          dSignatureParameters.Add("oauth_nonce", oauth_nonce)
          dSignatureParameters.Add("screen_name", screen_name)
  
          'https://dev.twitter.com/docs/auth/creating-signature#note-lexigraphically
          Dim sParameterString As String = GenerateSignature(dSignatureParameters)
  
          Dim sSignatureBaseString = sHTTPMethod.ToUpper &amp; "&amp;" &amp; HttpUtility.UrlEncode(sURL) &amp; "&amp;" &amp; HttpUtility.UrlEncode(sParameterString)
          Dim oauth_consumer_secret As String = "###"
          Dim oauth_token_secret As String = "###"
          Dim sSigningKey As String = HttpUtility.UrlEncode(oauth_consumer_secret) &amp; "&amp;" &amp; HttpUtility.UrlEncode(oauth_token_secret)
          Dim oauth_signature As String = ""
          Using oHasher As HMACSHA1 = New HMACSHA1(ASCIIEncoding.ASCII.GetBytes(sSigningKey)) 
              'goes in header
              oauth_signature = Convert.ToBase64String(oHasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sSignatureBaseString)))
          End Using
          Dim dHeaderParameters As New SortedDictionary(Of String, String)
          dHeaderParameters.Add("oauth_signature_method", oauth_signature_method)
          dHeaderParameters.Add("oauth_consumer_key", oauth_consumer_key)
          dHeaderParameters.Add("oauth_token", oauth_token)
          dHeaderParameters.Add("oauth_version", oauth_version)
          dHeaderParameters.Add("oauth_timestamp", oauth_timestamp)
          dHeaderParameters.Add("oauth_nonce", oauth_nonce)
          dHeaderParameters.Add("oauth_signature", oauth_signature)
          Dim sAuthHeader As String = GenerateHeader(dHeaderParameters)
  
          Dim oRequest As HttpWebRequest = (HttpWebRequest).Create(sURL)
          oRequest.Method = sHTTPMethod
          oRequest.ContentType = "application/x-www-form-urlencoded;charset=UTF-8" 'or 16?
          Dim oProxy As New WebProxy("proxy.wellsfargo.com", 8080)
          oProxy.Credentials = CredentialCache.DefaultCredentials
          oRequest.Proxy = oProxy
  
          oRequest.Headers.Add("Authorization", sAuthHeader)
  
          Dim sRequestBody As String = "screen_name=" &amp; screen_name
          Dim bytes() As Byte = System.Text.Encoding.ASCII.GetBytes(sRequestBody)
          oRequest.ContentLength = bytes.Length
          Dim oRS As System.IO.Stream = oRequest.GetRequestStream()
          oRS.Write(bytes, 0, bytes.Length)
          oRS.Close()
  
          Dim oResponse As WebResponse = oRequest.GetResponse()
          Dim oStream As Stream = oResponse.GetResponseStream()
          Dim oReadStream As New StreamReader(oStream, True)
          litResponse.Text = oReadStream.ReadToEnd()
          oResponse.Close()
          oReadStream.Close()
      Catch ex As Exception
          litError.Text = ex.Message
      End Try
  
  End Sub
  
  Private Function GenerateHeader(ByVal dParameters As SortedDictionary(Of String, String)) As String
      Dim sHeader As String = "OAuth "
      For Each sKey As String In dParameters.Keys
          sHeader &amp;= HttpUtility.UrlEncode(sKey) &amp; "=""" &amp; HttpUtility.UrlEncode(dParameters(sKey)) &amp; """"
          If sKey &lt;&gt; dParameters.Keys.Last Then
              sHeader &amp;= ", "
          End If
      Next
      Return sHeader
  End Function
  
  Private Function GenerateSignature(ByVal dParameters As SortedDictionary(Of String, String)) As String
      Dim sSignature As String = ""
      For Each sKey As String In dParameters.Keys
          sSignature &amp;= HttpUtility.UrlEncode(sKey) &amp; "=" &amp; HttpUtility.UrlEncode(dParameters(sKey))
          If sKey &lt;&gt; dParameters.Keys.Last Then
              sSignature &amp;= "&amp;"
          End If
      Next
      Return sSignature
  End Function
  
  Private Function GenerateTimeStamp() As String
      Dim ts As TimeSpan = DateTime.UtcNow - New DateTime(1970, 1, 1, 0, 0, 0, 0)
      Return Convert.ToInt64(ts.TotalSeconds).ToString()
  End Function
  
  Private Function GenerateNonce(ByVal oRandom As Random) As String
      Dim sb As New StringBuilder
      For i As Integer = 0 To 31
          Dim g As Integer = oRandom.[Next](3)
          Select Case g
              Case 0
                  ' lowercase alpha
                  sb.Append(ChrW(oRandom.[Next](26) + 97), 1)
                  Exit Select
              Case Else
                  ' numeric digits
                  sb.Append(ChrW(oRandom.[Next](10) + 48), 1)
                  Exit Select
          End Select
      Next
      Dim sRandom As String = sb.ToString()
      Dim bytes() As Byte = Text.Encoding.ASCII.GetBytes(sRandom)
      Dim sResult As String = Convert.ToBase64String(bytes)
      Dim sPattern As String = "[^A-Za-z0-9]"
      sResult = Regex.Replace(sResult, sPattern, "")
      Return sResult
  End Function
  </code></pre>