401: Invalid / expired Token with Silverlight

Sep 26, 2011 at 2:26 PM
Edited Sep 26, 2011 at 2:29 PM

Hi,

I've just implemented PIN-based authentication in my Silverlight application, but I keep getting the error 'Invalid / expired Token'.

I am using the latest build (92759) and Silverlight 5 RC.

I've followed the examples and, using the async approach, can successfully authenticate a user via the PIN method. I then serialise the AccessToken and OAuthToken strings to Isolated Storage. This all works and I have checked on Twitter that the authentication has actually been successful.

When I then ask Twitter for a users' Followers I get the error. I am creating my TwitterContext in the following way...

{ {
TwitterContext Create()
{
  var auth = new SingleUserAuthorizer               
  {         
     Credentials = new InMemoryCredentials 
      {           
         AccessToken = app.appVM.Tokens.AccessToken,     
         OAuthToken = app.appVM.Tokens.OAuthToken,   
         ConsumerKey = ConsumerKeys.KEY, 
         ConsumerSecret = ConsumerKeys.SECRET   
      },     
      ScreenName = app.appVM.Tokens.ScreenName, 
      UserId = app.appVM.Tokens.UserId   
  };

  return new TwitterContext(auth, BASE_URL, SEARCH_URL);
}

} }

Can anyone suggest a fix please?

Coordinator
Sep 26, 2011 at 3:46 PM

Hi,

It looks like you're using Single-User authorization, which is different from PIN authorization.  It might be possible that you're using the wrong keys, so let me summarize:ConsumerKey and

  1. Visit dev.twitter.com to verify tokens for your InMemoryCredentials.
  2. ConsumerSecret are specified under OAuth Settings.
  3. Values for AccessToken and OAuthToken are specified under Your Access Token.
  4. Under Your Access Token, AccessToken maps to OAuthToken and AccessTokenSecret maps to AccessToken.

BTW, after having to explain #4, I realize that this is not as clear as can be and opened a new issue: http://linqtotwitter.codeplex.com/workitem/31509.

@JoeMayo

 

 

Sep 26, 2011 at 4:09 PM

Hi Joe,

Thanks for the quick response.

I've just created a new Twitter application and hard-coded the following 4 strings into the previous code:

  • AccessToken = [Access token],
  • OAuthToken = [Access token secret],
  • ConsumerKey = [Consumer Key],
  • ConsumerSecret = [Consumer Secret]

Unfortunately, I still get exactly the same result: 401: Invalid / expired token.

BTW: if I map the values for my access token as in #4 I get a 404: Not found exception.

Secondly, I tried using a PinAuthorizer to submit request based on my persisted credential (rather than SingleUserAuthorizer), but got the same results also.

Thanks,

Chris 

Coordinator
Sep 26, 2011 at 4:30 PM

Chris,

401's are tough to debug because there are so many variables.  Here are more suggestions:

  1. It looks like your AccessToken and OAuthToken are backwards.
  2. Check your application settings on dev.twitter.com to make sure your application has the appropriate Access Level (read/write) permissions.
  3. Check your application settings on dev.twitter.com to make sure it is set to a Web application as opposed to a client application.  I think the new way to do this is by ensuring that you have a Callback URL specified.
  4. Open Fiddler (or other HTTP utility) to see if the message Twitter returns provides insight.
  5. I commented the source code that you downloaded as "Not yet stable..." because of various issues.  This shouldn't affect the OAuth, but the comments explain which is the best source version to use.  Alternatively, you can use NuGet or click the download tab to obtain a copy of the most recent official release.
  6. Just to mention, I haven't tested this on Silverlight 5 beta/RC.

Joe

Coordinator
Sep 26, 2011 at 4:36 PM

One more tip: Make sure your server time matches the Twitter server time.  You can get this from viewing the TwitterContext.RequestHeaders property or via the HTTP headers (which you can see with Fiddler).  There's a timestamp in the OAuth signature, which needs to be within a time threshold of the Twitter server's OAuth process that's doing security verification of the request.

Joe

Sep 27, 2011 at 10:52 AM
Edited Sep 27, 2011 at 10:53 AM

Hi Joe,

Some progress :).

Firstly, yes I was using the application's access tokens the wrong way around. Secondly, the oauth_timestamp in the headers does not take account of daylight savings time. If I turn off this option in the system clock the timestamps are OK.

So, I can now get this working using the clock change and the application's own auth tokens. Still receiving the same problems when deserialising perstisted tokens from isolated storage though.

Chris

Sep 27, 2011 at 12:44 PM

Hi Joe,

Progress update:

  • Searches work with both no authentication and OAuth
  • Friends works with no authentication but fails with OAuth
  • Followers works with no authentication but fails with OAuth
  • UpdateStatus works with OAuth (although a NotSupported exception is thrown somewhere along the stack).

I appreciate that this is all a bit convoluted from your point of view so I'm putting together a simple example project. What's the best email address to send it to please?

Chris

Nov 9, 2011 at 10:35 PM

Hi Joe,

I've now got a really simple example written that demonstrates the problem. Could you let me know the best email address for you please (either here or ping me at chris@percollate.com).

Cheers,

Chris