Is there a way to Force Authorization?

Feb 21, 2013 at 12:36 AM
Edited Feb 21, 2013 at 12:36 AM
Hi Joe,

We deal with multiple Twitter accounts per user. Our code seems to work the first time we authorize a twitter account but then it keeps that user in session so the next time we try to authorize a different twitter account it thinks it's already IsAuthorized.

Is there a way to force it to go to Twitter every time?

Here's our code:
var twitterCtx = new TwitterContext();

        IOAuthCredentials credentials = new SessionStateCredentials();
        if (credentials.ConsumerKey == null || credentials.ConsumerSecret == null)
        {
            credentials.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
            credentials.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
        }
        
        WebAuthorizer auth = new WebAuthorizer
        {
            Credentials = credentials,
            PerformRedirect = authUrl => Response.Redirect(authUrl)
        };

        if (!Page.IsPostBack)
        {
            auth.CompleteAuthorization(Request.Url);
        }
                
        if (auth.IsAuthorized)
        {
            if (Request.QueryString["oauth_token"] != null && !String.IsNullOrEmpty(Request.QueryString["oauth_token"].ToString()))
            {
                // Redirect to insert data 
            }
        }
        else
        {
            auth.BeginAuthorization(Request.Url);
        }
Coordinator
Feb 21, 2013 at 12:47 AM
Edited Feb 21, 2013 at 2:39 AM
Hi,

Generally, this wouldn't happen unless two users were using the same computer and the same browser session. Since the credentials are in session, you can create a new instance of SessionStateCredentials and set the OAuthToken and AccessToken to null. You could do this before every query, but that would require the user to authenticate every time you performed a query, which might be uncomfortable for the user. One thought is to do this on either Log In or Log off.

The Credentials property is type ICredentials, meaning that you can also manage credential storage yourself with a custom ICredentials type. You can look at the downloadable source code to see all of the different ICredentials types that are supported for an idea of implementation.

@JoeMayo
Feb 21, 2013 at 2:18 AM
That is exactly what I needed to do in this situation. Should have thought of that myself.

thx Joe!
Craig
Mar 4, 2013 at 10:46 PM
Hi Joe,

I have a question for you. You say when you have the auth tokens and the consumer key/secret you can just pass that to say, post a tweet. I can't find any documentation on how that works in linq-to-twitter. How do you it all in one shot since I have all the tokens/secrets I need? I'm using asp.net c#.

I would think I could do this but I'm always IsAuthorized = false.

var twitterCtx = new TwitterContext(auth);
var destroy = twitterCtx.DestroyStatus(id);


Thanks,
Craig


On Wed, Feb 20, 2013 at 8:47 PM, JoeMayo <notifications@codeplex.com> wrote:

From: JoeMayo

Hi,

Generally, this wouldn't happen unless two users were using the same computer and the same browser session. Since the credentials are in session, you can create a new instance of SessionStateCredentials and set the OAuthToken and AccessToken to null. You could do this before ever query, but that would require the user to authenticate every time you performed a query, which might be uncomfortable for the user. One thought is to do this on either Log In or Log off.

The Credentials property is type ICredentials, meaning that you can also manage credential storage yourself with a custom ICredentials type. You can look at the downloadable source code to see all of the different ICredentials types that are supported for an idea of implementation.

@JoeMayo

Read the full discussion online.

To add a post to this discussion, reply to this email (LinqToTwitter@discussions.codeplex.com)

To start a new discussion for this project, email LinqToTwitter@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Coordinator
Mar 4, 2013 at 10:55 PM
Hi,

You would fill in all four credentials, something like this:
            var auth = new SingleUserAuthorizer
            {
                Credentials = new InMemoryCredentials
                {
                    ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"],
                    ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"],
                    OAuthToken = ConfigurationManager.AppSettings["twitterOAuthToken"],
                    AccessToken = ConfigurationManager.AppSettings["twitterAccessToken"]
                }
            };
That uses SingleUserAuthorizer, but you can use whatever authorizer you want. Also, the example uses InMemoryCredentials, but you can use the ICredentials type that you want. Another item that might be different is the fact that the example pulls the credentials out of the config file. If you were using another authorizer and needed to load the person's credentials, then you would get that persons credentials from wherever you saved them and load the OAuthToken and AccessToken.

Here's the documentation that shows an example of how some of the authorizers work:

http://linqtotwitter.codeplex.com/wikipage?title=Learning%20to%20use%20OAuth&referringTitle=Securing%20Your%20Applications

@JoeMayo
Mar 4, 2013 at 11:17 PM
Awesome, thx Joe, I'll try this!

Sent from my iPad

On Mar 4, 2013, at 6:55 PM, "JoeMayo" <notifications@codeplex.com> wrote:

From: JoeMayo

Hi,

You would fill in all four credentials, something like this:
            var auth = new SingleUserAuthorizer
            {
                Credentials = new InMemoryCredentials
                {
                    ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"],
                    ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"],
                    OAuthToken = ConfigurationManager.AppSettings["twitterOAuthToken"],
                    AccessToken = ConfigurationManager.AppSettings["twitterAccessToken"]
                }
            };
That uses SingleUserAuthorizer, but you can use whatever authorizer you want. Also, the example uses InMemoryCredentials, but you can use the ICredentials type that you want. Another item that might be different is the fact that the example pulls the credentials out of the config file. If you were using another authorizer and needed to load the person's credentials, then you would get that persons credentials from wherever you saved them and load the OAuthToken and AccessToken.

Here's the documentation that shows an example of how some of the authorizers work:

http://linqtotwitter.codeplex.com/wikipage?title=Learning%20to%20use%20OAuth&referringTitle=Securing%20Your%20Applications

@JoeMayo
Mar 4, 2013 at 11:58 PM
We have always pulled Token and the TokenSecret.. how do they fit in here?

OAuthToken = ConfigurationManager.AppSettings["twitterOAuthToken"],
AccessToken = ConfigurationManager.AppSettings["twitterAccessToken"]
Maybe I'm storing the wrong information since twitter has changed to 1.1?
thanks,
Craig



On Mon, Mar 4, 2013 at 7:16 PM, Craig Kelley <mokumax@gmail.com> wrote:
Awesome, thx Joe, I'll try this!

Sent from my iPad

On Mar 4, 2013, at 6:55 PM, "JoeMayo" <notifications@codeplex.com> wrote:

From: JoeMayo

Hi,

You would fill in all four credentials, something like this:
            var auth = new SingleUserAuthorizer
            {
                Credentials = new InMemoryCredentials
                {
                    ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"],
                    ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"],
                    OAuthToken = ConfigurationManager.AppSettings["twitterOAuthToken"],
                    AccessToken = ConfigurationManager.AppSettings["twitterAccessToken"]
                }
            };
That uses SingleUserAuthorizer, but you can use whatever authorizer you want. Also, the example uses InMemoryCredentials, but you can use the ICredentials type that you want. Another item that might be different is the fact that the example pulls the credentials out of the config file. If you were using another authorizer and needed to load the person's credentials, then you would get that persons credentials from wherever you saved them and load the OAuthToken and AccessToken.

Here's the documentation that shows an example of how some of the authorizers work:

http://linqtotwitter.codeplex.com/wikipage?title=Learning%20to%20use%20OAuth&referringTitle=Securing%20Your%20Applications

@JoeMayo

Read the full discussion online.

To add a post to this discussion, reply to this email (LinqToTwitter@discussions.codeplex.com)

To start a new discussion for this project, email LinqToTwitter@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Coordinator
Mar 5, 2013 at 12:09 AM
ConsumerKey and ConsumerSecret come from your Twitter application and you will always set those. There are two ways to get the other two, OAuthToken and AccessToken.
  1. One way is to perform OAuth authentication at least one time and then read those two from the Credentials. This is what you would do if you were building an app for multiple people, where you save each person's credentials. Essentially, they will always have to authenticate at least one time. Then you grab their credentials and save them. On subsequent queries, you can get their credentials from wherever you stored them and reload so that user doesn't need to re-authenticate.
  2. Another way to get those credentials is in the scenario where you are the only person using the application, or the application is running on a server. In that case, you can visit your Twitter app and generate the AccessToken and AccessSecret and assign those to OAuthToken and AccessToken, respectively. I know the names are confusing because the standards have changed and Twitter has changed their API and somewhere along the way, things got a little out of whack on naming.
Is that what you were asking for?

@JoeMayo
Mar 5, 2013 at 1:11 AM
Perfect, thx again!

Sent from my iPad

On Mar 4, 2013, at 8:10 PM, "JoeMayo" <notifications@codeplex.com> wrote:

From: JoeMayo

ConsumerKey and ConsumerSecret come from your Twitter application and you will always set those. There are two ways to get the other two, OAuthToken and AccessToken.
  1. One way is to perform OAuth authentication at least one time and then read those two from the Credentials. This is what you would do if you were building an app for multiple people, where you save each person's credentials. Essentially, they will always have to authenticate at least one time. Then you grab their credentials and save them. On subsequent queries, you can get their credentials from wherever you stored them and reload so that user doesn't need to re-authenticate.
  2. Another way to get those credentials is in the scenario where you are the only person using the application, or the application is running on a server. In that case, you can visit your Twitter app and generate the AccessToken and AccessSecret and assign those to OAuthToken and AccessToken, respectively. I know the names are confusing because the standards have changed and Twitter has changed their API and somewhere along the way, things got a little out of whack on naming.
Is that what you were asking for?

@JoeMayo
Mar 5, 2013 at 2:10 AM
I think our app may be a bit of a hybrid of what you just explained. We allow users to manage multiple twitter accounts. Each twitter account grants us read/write access and we store their AccessToken/Secret in the DB. The user is allowed to switch between different users while logged in. They log in with their email address and password however. We do not have a "twitter" login. How we've done it in the past is we sent the ConsumerKey/Secret and along with the user's specific Twitter account AccessToken/Secret when posting a tweet, etc.

By sending it the same way as you suggested above (or at least trying to). We get the IsAuthorized = true but can't do anything with it. When we try to delete a tweet it always says 'You may not delete another user's status'. I've reAuthorized this specific Twitter account I'm testing and verified that the consumer/tokens are all right.

Our old app (using Twitterizer) still works fine. So.. have any ideas that may help us out? Oh, we are doing this in a webservice in this instance.

Here is our code:

var accessToken = .... (gets the user's data)

var auth = new SingleUserAuthorizer
{
Credentials = new InMemoryCredentials
{
ConsumerKey = ConfigurationManager.AppSettings["ConsumerKey"],
ConsumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"],
OAuthToken = accessToken.Token,
AccessToken = accessToken.TokenSecret
}
};

var twitterCtx = new TwitterContext(auth);
var destroy = twitterCtx.DestroyStatus(Id.ToString());

Thanks,
Craig


On Mon, Mar 4, 2013 at 9:10 PM, Craig Kelley <mokumax@gmail.com> wrote:
Perfect, thx again!

Sent from my iPad

On Mar 4, 2013, at 8:10 PM, "JoeMayo" <notifications@codeplex.com> wrote:

From: JoeMayo

ConsumerKey and ConsumerSecret come from your Twitter application and you will always set those. There are two ways to get the other two, OAuthToken and AccessToken.
  1. One way is to perform OAuth authentication at least one time and then read those two from the Credentials. This is what you would do if you were building an app for multiple people, where you save each person's credentials. Essentially, they will always have to authenticate at least one time. Then you grab their credentials and save them. On subsequent queries, you can get their credentials from wherever you stored them and reload so that user doesn't need to re-authenticate.
  2. Another way to get those credentials is in the scenario where you are the only person using the application, or the application is running on a server. In that case, you can visit your Twitter app and generate the AccessToken and AccessSecret and assign those to OAuthToken and AccessToken, respectively. I know the names are confusing because the standards have changed and Twitter has changed their API and somewhere along the way, things got a little out of whack on naming.
Is that what you were asking for?

@JoeMayo

Read the full discussion online.

To add a post to this discussion, reply to this email (LinqToTwitter@discussions.codeplex.com)

To start a new discussion for this project, email LinqToTwitter@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com


Coordinator
Mar 5, 2013 at 4:56 AM
I tried to repro, but it still worked. Here's an example that I modified from the downloadable Console Demos project:
        void DestroyStatus(TwitterContext twitterCtx)
        {
            Console.WriteLine("This demo will post a test status and show its ID. Then, the status will be destroyed.\n");

            Console.Write("Enter your test status update: ");
            string status = Console.ReadLine();

            Console.WriteLine("\nStatus being sent: \n\n\"{0}\"", status);

            Console.WriteLine("\nPress any key to post tweet...\n");
            Console.ReadKey();

            var tweet = twitterCtx.UpdateStatus(status);

            Console.WriteLine(
                "Status returned: " +
                "(" + tweet.StatusID + ")" +
                tweet.User.Name + ", " +
                tweet.Text + "\n");

            Console.WriteLine("Status ID: " + tweet.StatusID);
            Console.WriteLine("\nThis ID will be used to delete the status.");

            Console.WriteLine("\nStatus being destroyed: \n\n\"{0}\"", status);
            Console.Write("\nDo you want to destroy this status? (y or n): ");
            string confirm = Console.ReadLine();

            if (confirm.ToUpper() == "N")
            {
                Console.WriteLine("\nThis status is *not* being destroyed.");
            }
            else if (confirm.ToUpper() == "Y")
            {
                var auth = twitterCtx.AuthorizedClient as PinAuthorizer;
                var ctx = new TwitterContext(
                    new SingleUserAuthorizer
                    {
                        Credentials = new InMemoryCredentials
                        {
                            ConsumerKey = auth.Credentials.ConsumerKey,
                            ConsumerSecret = auth.Credentials.ConsumerSecret,
                            OAuthToken = auth.Credentials.OAuthToken,
                            AccessToken = auth.Credentials.AccessToken
                        }
                    });

                Console.WriteLine("\nPress any key to destroy...\n");
                Console.ReadKey();

                var destroy = ctx.DestroyStatus(tweet.StatusID);

                Console.WriteLine(
                    "(" + destroy.StatusID + ")" +
                    destroy.User.Name + ", " +
                    destroy.Text + " was destroyed.");
            }
            else
            {
                Console.WriteLine("Not a valid entry.");
            }
        }
Notice that I'm constructing a new SingleUserAuthorizer instance before deleting. I'm using the same tokens as from the authorizer that performed to original tweet.

Here are a few things that I would check:
  • Run this demo or download the Console Demos to verify that you're working from a known good point.
  • Use credentials of a user that you know are valid, perhaps your own.
  • Make sure the tweet hasn't already been deleted.
  • Has the user revoked your app's permission.
  • Hook up Fiddler to make sure you're seeing the whole message from Twitter - I wrap it in the TwitterQueryException, but still do this on occasion because the API continuously evolves. When doing this, look at the HTTP status code too because the message and code don't always seem to match (though it's gotten better over time) and this might provide some insight.
A couple of these ideas are wild-shots, but that's how brain-storming goes.

Joe
Mar 5, 2013 at 3:15 PM
Hi Joe,

Yeah, that works like that but... we do not use Twitter OAuth authentication for our users to log into our app. They log in using email/password.

After they are logged in they can add multiple Twitter accounts to their Mokumax account. So, if I select TwitterAccount1 (that I have added via Oauth at some point in history - most likely months ago) I can post tweets, etc. Since we already have the Token/TokenSecret we don't redirect them to Twitter to OAuth during their session. We just use their credentials.

Even the Console app makes you go to Twitter and grab a code each time. That is what we need to avoid.

Maybe it's not possible with Linq-to-Twitter?

Thanks,
Craig
Coordinator
Mar 5, 2013 at 3:50 PM
Craig,

Definitely possible. People use this functionality all the time. Here's an application for deleting archived tweets:

http://www.martani.net/2013/02/wipe-your-oldest-tweets-using-twitter.html

I showed you the console demo and suggested it as a troubleshooting mechanism, not suggesting that's what you do. Use the console program to verify that a set of keys you're using are correct and work. The console program works. If you don't have the right keys in the console program or the keys are being assigned to the wrong properties, then that might tell you what the problem is. Note that the console program is using the exact same keys in the delete operation that were used to create the tweet.

After you know you have good keys that work, you can do the same thing with your code. Use those same keys (that you got to work in your Console program) in your code, hit a breakpoint in the debugger, and step through the code to verify that the right keys are being placed into the right credentials properties. Also, make sure that the tweet you're trying to delete was tweeted using the same keys.

@JoeMayo
Mar 5, 2013 at 5:24 PM
Ok, I have to say a BIG Thank YOU and SORRRRY.. I guess long days and nights caught up with me. I was passing the wrong Id for the tweet.

AHHHH, sorry for taking up so much of your time Joe!

You really rock and I appreciate it pal!
Coordinator
Mar 5, 2013 at 5:53 PM
Not a problem - good luck.
Feb 18, 2015 at 9:44 PM
Hi Joe,

Can you give sample example for linq2twitter using Asp.Net 4.5, c#. Need to ask user credentials for every time..
Feb 18, 2015 at 9:51 PM
I mean for latest one LinqtoTwitter 3.1.2 verson. in samples i am finding for mvc5 but not for ASP.Net..

Thanks in advance.
Coordinator
Feb 24, 2015 at 2:40 AM
Hi,

You should read #8, #9 and #10 in the LINQ to Twitter FAQ.

@JoeMayo