Accessing Twitter Privacy Using DotNetOpenAuth in MVC4

I am creating an application with MVC4 that will allow users to use Twitter and allows them to tweet from the application. I can get the authenticated user without problems using BuiltInOAuthClient.Twitter which is in MVC4. http://www.asp.net/web-pages/tutorials/security/enabling-login-from-external-sites-in-an-aspnet-web-pages-site

I have an access token and oauth_verifier, but I need to also get acess_secret from Twitter. https://dev.twitter.com/docs/auth/implementing-sign-twitter

What I am missing is how to pass the oauth_verifier back to Twitter to get the access secret using OAuthWebSecurity.

Again, I can use Twitter to log in, but I need to be able to use Twitter as a user. I already did this with the TweetSharp library, but I'm trying to use DotNetOpenAuth in this project.

UPDATE: I am using the OAuthWebSecurity class as described in the first link for authentication management. OAuthWebSecurity.RegisterClient in AuthConfig expects DotNetOpenAuth.AspNet.IAuthenticationClient. You cannot exchange this using the TwitterConsumer class as suggested.

I can use the "built-in" part of DotNetOpenAuth authentication as described in the first link, or I can use my own code for full authorization, but I'm trying to find a way to do both.

I can do this individually, but then the user is presented with a Twitter dialog twice (once for logging in and once for authorization). I hope that it is possible to use an already connected authentication page that uses OAuthWebSecurity, but also part of the authorization.

+3
source share
4 answers

I've been banging my head on the wall for several days, but I finally have something that works. It would be interesting to know if this is a valid solution!

First create a new OAuthClient:

public class TwitterClient : OAuthClient { /// <summary> /// The description of Twitter OAuth protocol URIs for use with their "Sign in with Twitter" feature. /// </summary> public static readonly ServiceProviderDescription TwitterServiceDescription = new ServiceProviderDescription { RequestTokenEndpoint = new MessageReceivingEndpoint( "https://api.twitter.com/oauth/request_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), UserAuthorizationEndpoint = new MessageReceivingEndpoint( "https://api.twitter.com/oauth/authenticate", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), AccessTokenEndpoint = new MessageReceivingEndpoint( "https://api.twitter.com/oauth/access_token", HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest), TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() }, }; public TwitterClient(string consumerKey, string consumerSecret) : base("twitter", TwitterServiceDescription, consumerKey, consumerSecret) { } /// Check if authentication succeeded after user is redirected back from the service provider. /// The response token returned from service provider authentication result. protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { string accessToken = response.AccessToken; string accessSecret = (response as ITokenSecretContainingMessage).TokenSecret; string userId = response.ExtraData["user_id"]; string userName = response.ExtraData["screen_name"]; var extraData = new Dictionary<string, string>() { {"accesstoken", accessToken}, {"accesssecret", accessSecret} }; return new AuthenticationResult( isSuccessful: true, provider: ProviderName, providerUserId: userId, userName: userName, extraData: extraData); } } 

The important part is the response to the ITokenSecretContainingMessage message. It seems like TokenSecret has the answer all the time, but it is only on the internal property. By choosing it, you get access to public property. I cannot say that I am a fan of this, but then I also do not understand why the DotNetOpenAuth Asp.Net team hid the property in the first place. There must be a good reason.

Then you register this client in AuthConfig:

 OAuthWebSecurity.RegisterClient( new TwitterClient( consumerKey: "", consumerSecret: ""), "Twitter", null); 

Now, in the ExternalLoginCallback method on the AccountController, accessSecret is available in the ExtraData dictionary.

+10
source

The DotNetOpenAuth.AspNet.Clients.TwitterClient class allows authentication, not authorization. Thus, you will not be able to send tweets as this user if you use this class.

Instead, you can use DotNetOpenAuth.ApplicationBlock.TwitterConsumer , which does not share this restriction, and you can even copy the source code of this type into your application and expand it as needed.

You need to refine the TwitterConsumer class (once you have copied it into your own project) to implement the required interface for the OAuthWebSecurity class OAuthWebSecurity accept it. Otherwise, you can simply use TwitterConsumer directly to authenticate and authorize your web application, so that the user only looks at Twitter, but you get all the control you need. In the end, people using ASP.NET used TwitterConsumer to authorize and authorize subsequent Twitter calls until OAuthWebSecurity even existed.

+2
source

For a WebForms project template that references Microsoft.AspNet.Membership.OpenAuth in AuthConfig.cs instead of Microsoft.Web.WebPages.OAuth (MVC4 Internet application), I was able to modify Paul Manzotti's answer to make it work:

  • Create your own custom Twitter client class that derives from DotNetOpenAuth.AspNet.Clients.TwitterClient

    public class CustomTwitterClient: TwitterClient {public CustomTwitterClient (consumerKey string, consumerSecret string): base (consumerKey, consumerSecret) {}

     protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response) { //return base.VerifyAuthenticationCore(response); string accessToken = response.AccessToken; string accessSecret = (response as ITokenSecretContainingMessage).TokenSecret; string userId = response.ExtraData["user_id"]; string userName = response.ExtraData["screen_name"]; var extraData = new Dictionary<string, string>() { {"accesstoken", accessToken}, {"accesssecret", accessSecret} }; return new AuthenticationResult( isSuccessful: true, provider: ProviderName, providerUserId: userId, userName: userName, extraData: extraData); } 

    }

  • Add user client to AuthConfig.cs

     public static void RegisterOpenAuth() { OpenAuth.AuthenticationClients.Add("Twitter", () => new CustomTwitterClient( consumerKey: ConfigurationManager.AppSettings["twitterConsumerKey"], consumerSecret: ConfigurationManager.AppSettings["twitterConsumerSecret"])); } 

Ta-doe! Now you can hide the access secret.

+1
source

You can extract oauth_token_secret from OAuthWebSecurity by developing your own TokenManager. You can register the token manager when registering your Twitter client with OAuthWebSecurity.RegisterClient.

I used this method to extract the required values ​​to bypass the Linq-to-Twitter library authorization step.

I will post my decision soon on my blog.

0
source

All Articles