How to Create a Twitter @Anywhere ActionFilter in ASP.NET MVC
My newest project, Captain Obvious, got a fair amount of attention this week when it landed on the front page of Hacker News – one of the key features that makes the first version of Captain Obvious tick is Twitter @Anywhere integration.
Twitter @Anywhere is brand new and there isn’t much developer documentation for it – the way to think about Twitter @Anywhere is as a Javascript platform that allows you to outsource user authentication and registration to Twitter’s servers, and in exchange you get less hassle but also less intimate access to your user’s accounts.
One of the key features to integrating Twitter @Anywhere users with your ASP.NET MVC site is reading the cookie that Twitter sets after users have authenticated – this cookie contains two parts:
- The Twitter user’s unique ID, an integer representing their unique account (because remember – Twitter users can change their handles!)
- A SHA1 hash of the Twitter user’s unique ID + your application’s consumer secret – you use this to verify that the cookie was set by Twitter, since they’re the only ones who know your consumer secret other than you.
Naturally, if you are going to use this cookie as your authentication mechanism, then you are going to need to write your own Authorize attribute that allows you to validate the content’s of the Twitter @Anywhere cookie. Here’s the source code I use for doing that:
ValidTwitterAnywhereAttribute
/// <summary> /// Controller Action Filter Attribute which requires that /// </summary> public class ValidTwitterAnywhereAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { var twitterCookieValue = httpContext.Request.Cookies["twitter_anywhere_identity"]; var consumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"]; return TwitterAuthHelper.ValidateTwitterCookie(twitterCookieValue, consumerSecret); } }
Here’s the relevant source code from the TwitterAuthHelper that I use to actually validate the hash in the cookie:
TwitterAuthHelper
public static bool VerifyTwitterUser(string twitterCookieValue, string ConsumerSecret) { var results = twitterCookieValue.Split(':'); var sha1 = new SHA1CryptoServiceProvider(); var hash = BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(results[0] + ConsumerSecret))) .ToLower().Replace("-", ""); if (hash.Equals(results[1])) return true; return false; }
I’m using this code in production and it works great – all you have to do to use it is decorate your controller methods with the [ValidTwitterAnywhere] attribute and it will behave just like Forms authentication if you have that enabled in your ASP.NET MVC app.