Oauth failing: "Failed to validate oauth signature and token"

crasherco
@crasherco Crasher

I'm attempting to authenticate users via Twitter in order to give them an access token cookie so they can make search API requests from my web front end. Or, stated in reverse: I need my users to be able to search tweets (which I'm doing right now sans authentication pre-1.1) so now I need to log them in and give them access tokens for these requests.

But try as I might to follow this: https://dev.twitter.com/docs/auth/implementing-sign-twitter, I'm getting stuck at Step 1: Getting request token. Here is my HttpPost and the Twitter 1.1 api response, in plain text (via wireshark):

POST /oauth/request_token HTTP/1.1
Authorization: OAuth oauth_callback="https%3A%2F%2Fwww.mysite.co%2Ftwitter_auth_callback",oauth_consumer_key="CONSUMERKEY",oauth_nonce="f8bef3a17dac4b4eaa09fad7f7794a18",oauth_signature="1234e59bb9abcda53d9c288e168abcdef1234cbf33",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1357508339",oauth_version="1.0"
Content-Length: 0
Host: api.twitter.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

HTTP/1.1 401 Unauthorized
Date: Sun, 06 Jan 2013 21:38:59 GMT
Status: 401 Unauthorized
X-MID: 68894c41b43b29da51219321de4b1d832245811b
Pragma: no-cache
X-Frame-Options: SAMEORIGIN
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Content-Type: text/html; charset=utf-8
Last-Modified: Sun, 06 Jan 2013 21:38:59 GMT
Content-Length: 44
X-Runtime: 0.01900
Expires: Tue, 31 Mar 1981 05:00:00 GMT
X-Transaction: 283282525072ab56
Set-Cookie: k=10.35.51.113.1357508339018529; path=/; expires=Sun, 13-Jan-13 21:38:59 GMT; domain=.twitter.com
Set-Cookie: guest_id=v1%3A135750833902835385; domain=.twitter.com; path=/; expires=Wed, 07-Jan-2015 09:38:59 GMT
Set-Cookie: _twitter_sess=BAh7CDoPY3JlYXRlZF9hdGwrCFZlzRE8AToHaWQiJTc0YzY4MTEyZGZmNGM3%250AODJlNTYwNzA0MjNiYjE3ZmFhIgpmbGFzaElDOidBY3Rpb25Db250cm9sbGVy%250AOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--46808a2fb500feb4cf99ae5157448438bedda649; domain=.twitter.com; path=/; HttpOnly
Vary: Accept-Encoding
Server: tfe

Failed to validate oauth signature and token

Which looks very similar to the post/response example on the other page. Does anything look wrong to you? Definitely could use some help after wrestling with this for a few hours.

The one thing that does jump out at me is my oauth signature. Mine lookes 16-bit encoded and the example's does not. Why are we hashing the secret in the first place? Because non https requests are allowed? And how would I go about hashing that in java? I'm assuming it's a Sha1 hash, 64-bit encoded, then URL encoded. Is that right? (Trying to avoid suing Twitter4J. Don't want to be dependent on additional libraries if I can help it.)

BTW, timestamps are identical. It's not that.

Cyrus

1 year 14 weeks ago

Replies

episod
@episod Taylor Singletary

Take a look at at least some OAuth library for Java -- Scribe and SignPost are both worthwhile, and Scribe is especially light-weight. Twitter4j may be more than you need, as you imagine.

But OAuth is hard to get right and it's best to stand on the shoulders of those who've already gone to the mat on writing a client library for it.

In this case, it looks like your Authorization header is omitting the oauth_signature attribute.

1 year 14 weeks ago
crasherco
@crasherco Crasher

Please take a look at my new information and let me know if you see anything wrong.

I've toyed around with twitter4j but I really, really, really don't want to be dependent on a library written by a single developer. I have no idea how efficient, secure or maintained it is (or will be), and that goes for the others you mentioned as well. If we were talking about an Apache commons library or something, that would be different.

In any case, this Oauth flow should be simple to do without a 3rd-party library. Please let me know if you see anything wrong with the POST code I posted earlier.

BTW, what is the process (in high-level terms) for generating an oauth_signature. It's a 64-bit encoded SHA1 hash of....?

1 year 13 weeks ago
crasherco
@crasherco Crasher

<Suppressing gripes about how complicated this process is when it's been so easy with Facebook and Google Oauth...>

Here's my request. Yes, I'm including oauth_signature and I'm pretty sure it's calculated correctly. Do you notice anything wrong?

POST /oauth/request_token HTTP/1.1
Authorization:
OAuth oauth_callback="https%3A%2F%2Fwww.mysite.co%2Ftwitter_auth_callback",
oauth_consumer_key="FLp------------------------Q",
oauth_nonce="00772af9dbb3430882956fe8878a53fd",
oauth_signature="EjTlm7kCWblahblahblahbvxZhhCcDM",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1357582126",
oauth_version="1.0"
Content-Length: 0
Host: api.twitter.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

HTTP/1.1 401 Unauthorized
Date: Mon, 07 Jan 2013 18:08:46 GMT
Status: 401 Unauthorized
X-Frame-Options: SAMEORIGIN
X-MID: 7f0e40ae6ae65f7d1a36ef8e74fe10f568d6c33b
Pragma: no-cache
Last-Modified: Mon, 07 Jan 2013 18:08:46 GMT
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
X-Transaction: d7ea4542a3e0ae3a
Content-Length: 44
Expires: Tue, 31 Mar 1981 05:00:00 GMT
X-Runtime: 0.02328
Content-Type: text/html; charset=utf-8
Set-Cookie: k=10.35.1.123.1357582126114238; path=/; expires=Mon, 14-Jan-13 18:08:46 GMT; domain=.twitter.com
Set-Cookie: guest_id=v1%3A135758212612662057; domain=.twitter.com; path=/; expires=Thu, 08-Jan-2015 06:08:46 GMT
Set-Cookie: _twitter_sess=BAh7CCIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7ADoPY3JlYXRlZF9hdGwrCC9MMxY8AToHaWQiJTEw%250AYzgzY2Y2YmVlMGQ4NWFjNWRmYWUzZTQ2NmE2ZTEx--aec5d01d3d4f7699db5253363745a471eee7cbbc; domain=.twitter.com; path=/; HttpOnly
Vary: Accept-Encoding
Server: tfe

Failed to validate oauth signature and token

My request looks pretty darn identical to the example here, so I'm really depending on someone at Twitter to explain how two things that look identical aren't.

https://dev.twitter.com/docs/auth/implementing-sign-twitter

Do I need an Accept: / header?
Does the lack of post body matter?
Does my oauth_signature need to end with %3D (equals sign) for some reason? Many of the examples do?
Why doesn't the example provided have a "content-length" header?
This should work over both http and https, right?

1 year 14 weeks ago
crasherco
@crasherco Crasher

Solved this here: https://dev.twitter.com/discussions/13935

1 year 13 weeks ago
zukasmichael
@zukasmichael Michael Zukas

in most cases it's wrong date time issue.

try first: ntpdate time.apple.com as root on server

10 weeks 4 days ago