Search code examples
c#.netasp.net-mvctwitter

mvc.net get profile info from Twitter


I'm trying to retrieve profile information from Twitter after authenticating using standard mvc.net external authentication.

I can do this for Facebook using the below code (needs Facebook SDK installed) located in the ExternalLoginCallback function.

 if (string.Equals(loginInfo.Login.LoginProvider, "facebook", StringComparison.CurrentCultureIgnoreCase))
        {
            var identity = AuthenticationManager.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie);
            var access_token = identity.FindFirstValue("FacebookAccessToken");
            var fb = new FacebookClient(access_token);

            // you need to specify all the fields that you want to get back
            dynamic myInfo = fb.Get("/me?fields=email,first_name,last_name");
            email = myInfo.email;
            firstName = myInfo.first_name;
            lastName = myInfo.last_name;
        }

I am looking for a Twitter equivalent.


Solution

  • So here's what I did based largely on this

    Obtain twitter access token asp.net identity

    First, i installed the TwitterinviAPI nuget package as per @Mate suggestion above.

    Second, i updated the twitter section of ConfigureAuth in StartUp.Auth.cs to include a "Provider"

    app.UseTwitterAuthentication(new TwitterAuthenticationOptions()
            {
                ConsumerKey = ConfigurationManager.AppSettings["TwitterConsumerKey"],
                ConsumerSecret = ConfigurationManager.AppSettings["TwitterConsumerSecret"],
                Provider = new LinqToTwitterAuthenticationProvider(),
                BackchannelCertificateValidator = new Microsoft.Owin.Security.CertificateSubjectKeyIdentifierValidator(new[]
                    {
                       "A5EF0B11CEC04103A34A659048B21CE0572D7D47", // VeriSign Class 3 Secure Server CA - G2
                       "0D445C165344C1827E1D20AB25F40163D8BE79A5", // VeriSign Class 3 Secure Server CA - G3
                       "7FD365A7C2DDECBBF03009F34339FA02AF333133", // VeriSign Class 3 Public Primary Certification Authority - G5
                       "39A55D933676616E73A761DFA16A7E59CDE66FAD", // Symantec Class 3 Secure Server CA - G4
                       "‎add53f6680fe66e383cbac3e60922e3b4c412bed", // Symantec Class 3 EV SSL CA - G3
                       "4eb6d578499b1ccf5f581ead56be3d9b6744a5e5", // VeriSign Class 3 Primary CA - G5
                       "5168FF90AF0207753CCCD9656462A212B859723B", // DigiCert SHA2 High Assurance Server C‎A 
                       "B13EC36903F8BF4701D498261A0802EF63642BC3" // DigiCert High Assurance EV Root CA
                     }),
            });
    

    Third, I added the LinqToTwitterAuthenticationProvider Class to Model/IdentityModels (though you can put this code anywhere you like)

    public class LinqToTwitterAuthenticationProvider : TwitterAuthenticationProvider
    {
        public const string AccessToken = "TwitterAccessToken";
        public const string AccessTokenSecret = "TwitterAccessTokenSecret";
    
        public override Task Authenticated(TwitterAuthenticatedContext context)
        {
            context.Identity.AddClaims(
                new List<Claim>
                {
                new Claim(AccessToken, context.AccessToken),
                new Claim(AccessTokenSecret, context.AccessTokenSecret)
                });
    
            return base.Authenticated(context);
        }
    

    Lastly, I updated ExternalLoginCallback in the Accounts controller with the following code to get the user details from twitter

      else if (string.Equals(loginInfo.Login.LoginProvider, "twitter", StringComparison.CurrentCultureIgnoreCase))
            {
                // Generate credentials that we want to use
                var identity = AuthenticationManager.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie);
                var access_token = identity.FindFirstValue(LinqToTwitterAuthenticationProvider.AccessToken);
                var access_token_secret = identity.FindFirstValue(LinqToTwitterAuthenticationProvider.AccessTokenSecret);
                var creds = new TwitterCredentials(ConfigurationManager.AppSettings["TwitterConsumerKey"], ConfigurationManager.AppSettings["TwitterConsumerSecret"],access_token, access_token_secret);
                var authenticatedUser = Tweetinvi.User.GetAuthenticatedUser(creds);
                email = authenticatedUser.Email;
                firstName = authenticatedUser.Name.Substring(0, authenticatedUser.Name.IndexOf(' '));
                lastName = authenticatedUser.Name.Substring(authenticatedUser.Name.IndexOf(' ') + 1);
    
            }
    

    There was one little GOTCHYA. Email was coming through as null even after all this. The problem was in my twitter app set up I had not supplied a privacy or ToS URL and hence could not check the option under the permissions tab to request users email. Just a freindly FYI.

    Hope this helps!!