Twitterizer: "Could not authenticate with OAuth" - c#

I'm using Twitterizer library for posting tweets within a web-site into my twitter account. It works just fine on site, running on my local server (authenticates with OAuth through twitter app and posts a tweet).
But when I'm trying to post a tweet on production server, Twitterizer says: "Result = Unauthorized. ErrorMessage = Could not authenticate with OAuth."
I double checked consumer keys, also tried to reset the keys and try again - same result.
Twitter application has read/write access to my twitter account and is not blocked.
This problem appeared suddenly after a period of successful working for about a month, when tweets were posted every hour or so.
What is the problem here?
UPDATE
It seems, that other guys also face this problem: https://dev.twitter.com/discussions/305
UPDATE 2
Finally, I have found out what caused the problem to appear in my case. Web app on production server tried to update a status with 140 characters (measured by String.Length property). And the first character was unicode Character 'LEFT-TO-RIGHT MARK' (U+200E). So, this text was passed to TwitterStatus.Update(..) without changes. I debugged a bit Twitterizer sources and noticed that oauth_signature(=hash) was calculated incorrectly. oauth_signature was generated from another url that was actually requested. I haven't cleared the reason why and when this error occurs and maybe will write more information in next few days.
UPDATE 3
I tried to post the same message with new version of Twitterizer (2.3.3) and no error occured. Problem disappeared.
It's the code, that I'm using to post a tweet:
OAuthTokens tokens = new OAuthTokens();
tokens.AccessToken = ConfigurationManager.AppSettings["twitterAccessToken"];
tokens.AccessTokenSecret = ConfigurationManager.AppSettings["twitterAccessTokenSecret"];
tokens.ConsumerKey = ConfigurationManager.AppSettings["twitterAutoPosterConsumerKey"];
tokens.ConsumerSecret = ConfigurationManager.AppSettings["twitterAutoPosterConsumerSecret"];
string text = "Some text";
TwitterResponse<TwitterStatus> tweetResponse = TwitterStatus.Update(tokens, text);
if (tweetResponse.Result == RequestResult.Success)
{
// Tweet posted successfully!
_log.InfoFormat("Posted a tweet #{0}.", tweetResponse.ResponseObject.Id);
}
else
{
_log.ErrorFormat("Error occured while posting a tweet. Result = {0}. ErrorMessage = {1}",
tweetResponse.Result, tweetResponse.ErrorMessage);
}

Please check in the message, if message have apostrophes (') , please replace it with &#39;
Note that &#39; will count as 5characters.
I think that apostrophes will effect the request package that send to twitter, that make twitter cannot get Token Correctly, so we will got error "Could not authenticate with OAuth".

I had the same trouble. PHP 5.3.1 ran on my local server, while PHP 4.3.2 ran on my production server. I use OAuth library of Google Code obtained from the below,
http://code.google.com/p/oauth/source/browse/#svn%2Fcode%2Fjavascript.
I explored the OAuth header which PHP proxy program received from javascript code on a browser. On my local server, it was
OAuth realm="",oauth_consumer_key="XXX",oauth_token="XXX",oauth_version="1.0",oauth_timestamp="1314956434",oauth_nonce="mF7Tof",oauth_signature_method="HMAC-SHA1",oauth_signature="DbuaiDeMhMYNZ5BaQmOoFr%2FRsEQ%3D"
while on my production server, all the double quotations above were escaped, namely, '\"'.
So I replaced the escaped double quotation to the unescaped one using str_replace function. Then it got work well just the same on my production server. The cause is the difference of the way how double quotation is treated between PHP 5.3.1 and PHP 4.3.2. Escaped double quotation caused an error "Could not authenticate with OAuth."

Related

Invalid token when password resetting on Microsoft.AspNetCore.Identity but ONLY on server side, not localhost

I'm currently a beginner developer and I'm coding a password reset on my WebApp.
So as you can see everything is good in localhost but in live I got an invalid token and I don't know why:
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist or is not confirmed
return RedirectToAction(nameof(ForgotPasswordConfirmation));
}
var code = await _userManager.GeneratePasswordResetTokenAsync(user);
var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme);
// Go to the change password page
Response.Redirect(callbackUrl);
}
// If we got this far, something failed, redisplay form
return View(model);
}
I have checked the files in my FTP and everything is the same in AccountController.cs.
My token is supposed to be built with some special characters as "+" and I know my url will be like http://localhost:5000/Account/ResetPassword?userId=00c2a3ad-64c8-49d3-95e5-49a120831b85&code=CfDJ8MVJi%2BoeOmp....
I have figured my callbackUrl has a different behavior onlineat the %25
Do I have decoded the URL and I found %25 means "%" in UTF-8 and I think it's an encoding/decoding problem so I trued to encode like this code = HttpUtility.UrlEecode(code) and decoding it but it's even worse because my token is getting invalid so maybe I got completely my theory is wrong.
Have you any clues? any soution to my problem? Glad to disscuss with.
Thanks for paying attention to my issue,
BR X-MAS Greetings,
Lap1
EDIT:
Okay first of all thanks for so I checked my versions on the both environnemnets by using dotnet -- info and here are my versions. and . So I know I installed a newer version of .NET Framework on my PC. But there is remaining the 2.0.0 version and it's used for every debugging. I don't know if the problem is here so If you have any clues I'm here to exploit this.
EDIT 2: so I uninstalled the newer versions (not a good idea buut I did just in case) to keep the same versions in 2.2.202 and my code still running
EDIT3: ok so I will keep updating my thoughts about my issue. I think it's because the code is encoded once before I see the URL. e.g. + becomes %2F and it becomes %252F in the URL. I never encoded the code string but there is somewhere in the server some options...

Unable to return user favorites via Tableau REST API

UPDATE: Sept 2019.
This API call now works as intended.
Issues on the Tableau end appear to have been resolved and the call now returns the correct data.
===============================================================
I'm using the Tableau REST API via C# to try and get a list of users favorites.
I know the user has some, because its me.
I have tried using API Version 2.8,3.0, 3.1 and 3.2 with little to no joy.
2.8 and 3.0 respond with:
<?xml version='1.0' encoding='UTF-8'?>
<tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.8.xsd"> //3.0.xsd when using API Version 3.0
<favorites/> //There should be a plethora of favorites of all varieties in here.
</tsResponse>
3.1 and 3.2 give me a (404) Not found.
The code i have in c# is:
public static string QueryFavourites(string APIVersion, string AuthToken, string SiteID, string UserID)
{
string result = "";
try
{
string url = $#"{Server}/api/{APIVersion}/sites/{SiteID}/favorites/{UserID}";
// Create the web request
WebRequest request = WebRequest.Create(url) as WebRequest;
request.PreAuthenticate = true;
request.Headers.Add($"x-tableau-auth: {AuthToken}");
// Get response
using (WebResponse response = request.GetResponse())
{
// Get the response stream
StreamReader reader = new StreamReader(response.GetResponseStream());
// Read the whole contents and return as a string
result = reader.ReadToEnd();
}
return result;
}
catch(Exception E)
{
logger.Error("Error! System Says: " + E.Message);
return result;
}
}
I know the method works, as it is used for multiple other API calls using a different URL for each (depending on the call).
Does anyone know if its an issue on the tableau end or on my end?
Apparently it should work with Tableau server 2.8 or above, which we have. (i think we're running 2018.1)
Is anyone able to get a list of favorites for a user using tableau REST API?
Where am i going wrong?
(I have also posted the question on Tableau Forum.)
UPDATE:
I have included the CURL and Headers of the request, as well as the results, in the screenshots below. (I use 'Restlet Client' more than 'Postman' so screenshots are from the former.) ID's and authentication tokens have been removed as they are sensitive information, and i don't think my company would be happy with me putting them on the public facing internet.
All ID's and auth keys are in the correct case and presented correctly. They are used in several other API calls with success and are pulled direct from Tableau via the API.
The exceptions, i have found out are the inability to find the version of the API that i am calling. so v2.6 - v2.8 and v3.0 all "work". Other versions return a 404001 VERSION_NOT_FOUND error.
The approach i would take is:
Query a user on the site. (the user that has the favorites)
Check if the user is actually: the same user you are authenticated as; and the same user you are gonna query for favorites
If they are the same, try adding a favorite with the REST API (DataSource, View or Workbook)
Get the favorites for the user, the datasource/view/workbook you added as a favorite should be in there.
If you want to Update the user, Add user to site or Add user to Group, I've added links to the documentation
You can do these things with Postman/tool of your choice.
What you can also try is ensuring the user that is querying another user (or the same) is a server admin (just to be safe), and making sure that you are a member of the same site of another (or the same) user.
Hope this helps!
EDIT: Maybe you can try adding a new user with group regular to a site, ensuring that you are a member of the site too. Afterwards adding a favorite and getting the favorites for the user of group regular. If that doesnt work u can verify whether its impossible to get favorites for users of group regular as well, besides admins.
Finally found out what was happening.
It doesn't work as intended.
It will only return user favorites for the user that is authenticated in the authentication token, regardless of what user id you put in the request.
Had a call with Tableau support and accidentally figured it out, when we switched authenticated user.
I will leave this here in case anyone else comes across the same issue.

how to post on facebook wall for specific list of users using asp.net c#?

I am trying to post on specific group of users on facebook such as (close friends, or family, or college friend...) and I used the code bellow.
code that I used:
1
FacebookClient fpost1 = new FacebookClient(access_token);
fpost1.Post("/1234567890/feed", new { message = "test post"});
note: access_token is working correctly when I am doing some job before this exception.
I put my friendlist id instead of 1234567890, that you can get it from graph .../me?fields=friendlists
it did not work and gave me this error "(OAuthException - #2) An unexpected error has occurred. Please retry your request later."
2
FacebookClient fpost1 = new FacebookClient(access_token);
fpost1.Post("/me/feed", new { message = "it is very cold.", to="1234567890"});
this one work, but it post to "only me" as target.
thank you
It looks to me that what you are doing here...
FacebookClient fpost1 = new FacebookClient(access_token);
fpost1.Post("/1234567890/feed", new { message = "test post"});
is wrong. Because I believe that 1234567890 is a user-id, right? Not a friendslist-id. According to the documentation this edge/endpoint signature goes like....
/{user-id}/feed
where user-id is obviously a user id. The documentation states that...
Most nodes in the Graph API have edges that can be published to (such as Photos or Posts). All Graph API publishing is done simply with an HTTP POST request to the relevant endpoint with any necesssary parameters included. For example, if you wanted to publish a post on behalf of someone, you would make an HTTP POST request as below:
POST graph.facebook.com
/{user-id}/feed?
message={message}&
access_token={access-token}
Notice that it says "On Behalf of Someone". My understanding is that you are publishing on behalf of someone and to do that, this someone must have requested an access_token through your application. In other words, if this user hasn't logged in to your app and generated a valid access token you cannot publish on his/her wall
POST graph.facebook.com
me/feed?message="hello"&privacy={"value": "CUSTOM", "allow": "1234567890"}
where the 1234567890 is one of friendlists id

Problem getting access_token after migrating to OAuth 2.0

I have tried migrating my app to the OAuth 2.0 routine. I am having trouble getting the access_token from the cookie set by the JavaScript API. I decode the information in the cookie, but instead of an access_token and the user information I get a code. This seems like a rather weird change.
Is there any workaround for this, because it seems that you can't get your code exchanged to an access_token when you haven't specified a redirect_uri when you acquired the code.
I have considered just taking the access_token from the response in the JavaScript API and storing it in a cookie, but that kinda defeats the whole purpose of the extended security and I wanted to ask if there was a proper way to do it.
Could be that I am doing something wrong though, and if that is the case please tell me :)
EDIT
I am aware that the cookie holds a signed request, but according to the docs that signed request should hold the information I require like access_token and uid, but in my instance it only holds the code. That is basically the part I don't understand.
Turns out that (even though it is not documented) we need to exchange the code for an access_token ourselves. I think this is a total waste since that was the nice thing about the old cookie. It was fast and easy to get the access_token.
Anyway. To get the access_token from the new cookie you need to do the following:
public string ReturnAccessToken()
{
HttpCookie cookie = htc.Request.Cookies[string.Format("fbsr_{0}", facebookAppID)];
string jsoncode = System.Text.ASCIIEncoding.ASCII.GetString(FromBase64ForUrlString(cookie.Value.Split(new char[] { '.' })[1]));
JsonData data = JsonMapper.ToObject(jsoncode);
getAccessToken(data["code"].ToJson()
}
private string getAccessToken(string code)
{
//Notice the empty redirect_uri! And the replace on the code we get from the cookie.
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}", "YOUR_APP_ID", "", "YOUR_APP_SECRET", code.Replace("\"", ""));
System.Net.HttpWebRequest request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;
System.Net.HttpWebResponse response = null;
using (response = request.GetResponse() as System.Net.HttpWebResponse)
{
System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());
string retVal = reader.ReadToEnd();
return retVal;
}
}
public byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
result.Append(String.Empty.PadRight(padChars, '='));
result.Replace('-', '+');
result.Replace('_', '/');
return Convert.FromBase64String(result.ToString());
}
This may seem a bit redundant, but I suppose you can store the access_token in a session variable. If you do this and iFrame the your app on Facebook you need to know that it will not work in IE 6, 7 and 8 if the user have set his browser privacy settings to medium. There is a workaround for this, but as it is not a part of this question I will not write it. If people really want it, write a comment and I will show it :)
-----------------------------------EDIT------------------------------------------
When using any of the old IE browsers you can't use cookies or session variables in pages that are Iframed in, like your pages on Facebook. This is a problem that can't really be solved sufficiently in coding. By sufficiently I mean that the solution is not nice. You need to set the p3p-header in your response. You can of course do this in coding for all the pages that you service, but the easiest solution (if you are using a .NET server to host your pages) is to set up a p3p policy for the IIS. A guide for this can be seen in http://support.microsoft.com/kb/324013. It shouldn't matter what you write in the p3p policy (if you check Facebooks own you can see that they use "We don't have a p3p policy), the important part is that there stands something. I have had troubles just using random text though, but if you use the text in the example there shouldn't be a problem :)
This took me forever to find out, so I hope someone can use it :D
Unfortunately I don't have the answer directly, but I do have a documentation bug that I filed against facebook in order to try to get the documentation there: http://bugs.developers.facebook.net/show_bug.cgi?id=20363
I have a similar problem that when I try to decode the signedRequest from the authResponse of FB.login, they payload contains something like:
{"algorithm":"HMAC-SHA256","code":"THE_CODE_HERE","issued_at":1315433244,"user_id":"THE_USER_ID"}
As you stated, the docs do talk about how to turn that code into an access_token. That appears to be in the "Server Side" documentation here: http://developers.facebook.com/docs/authentication/
If you grab the accessToken from FB.login you can get it from the js and cache it, but as you said, that isn't actually signed, and could relatively easily be faked.
And you're right, this doesn't appear to have any of the useful information that's described here: developers.facebook.com/docs/authentication/signed_request/ (http removed since I don't have enough reputation points yet to post more than 2 links - sorry)
Perhaps you can vote up my bug? I'll post this link on that bug too.
fbsr_APP_ID cookie is actually a signed_request, check out facebook official docs how do you decode signed request verify signature and get the user information. You can look also at official php SDK source how they get access token from there.
You have to use the code to get the actual access_token.

Simple C# Evernote API OAuth example or guide?

Anybody know where I can find a simple example C# code example? Apparently really tough to find.
I'm just starting out, got my Developer key.
Initial (really noob question/presumption) - -Can (should/must) my solution be a web service client? No new libraries I need to install in .Net right?
Basically, as a test, I want to be able to securely present a single note from a private notebook in html similar to what the Everfort export in html looks like on a outside WebSite.
Many Thanks in Advance!
You should start by downloading our API ZIP from http://www.evernote.com/about/developer/api/. You'll find C# client sample code in /sample/csharp. This sample code demonstrates using the Evernote API from a desktop application that authenticates using username and password.
I am not sure if you ever got this working, but I was playing around with Evernote, OpenAuth and C# this morning and managed to get it all working. I have put together a blog post / library explaining the experience and outlining how to do it with MVC here - http://www.shaunmccarthy.com/evernote-oauth-csharp/ - it uses the AsyncOAuth library: https://github.com/neuecc/AsyncOAuth
I wrote a wrapper around AsyncOAuth that you might find useful here: https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple
One prickly thing to be aware of - the Evernote Endpoints (/oauth and /OAuth.action) are case sensitive
// Download the library from https://github.com/shaunmccarthy/AsyncOAuth.Evernote.Simple
// Configure the Authorizer with the URL of the Evernote service,
// your key, and your secret.
var EvernoteAuthorizer = new EvernoteAuthorizer(
"https://sandbox.evernote.com",
"slyrp-1234", // Not my real id / secret :)
"7acafe123456badb123");
// First of all, get a request token from Evernote - this causes a
// webrequest from your server to Evernote.
// The callBackUrl is the URL you want the user to return to once
// they validate the app
var requestToken = EvernoteAuthorizer.GetRequestToken(callBackUrl);
// Persist this token, as we are going to redirect the user to
// Evernote to Authorize this app
Session["RequestToken"] = requestToken;
// Generate the Evernote URL that we will redirect the user to in
// order to
var callForwardUrl = EvernoteAuthorizer.BuildAuthorizeUrl(requestToken);
// Redirect the user (e.g. MVC)
return Redirect(callForwardUrl);
// ... Once the user authroizes the app, they get redirected to callBackUrl
// where we parse the request parameter oauth_validator and finally get
// our credentials
// null = they didn't authorize us
var credentials = EvernoteAuthorizer.ParseAccessToken(
Request.QueryString["oauth_verifier"],
Session["RequestToken"] as RequestToken);
// Example of how to use the credential with Evernote SDK
var noteStoreUrl = EvernoteCredentials.NotebookUrl;
var noteStoreTransport = new THttpClient(new Uri(noteStoreUrl));
var noteStoreProtocol = new TBinaryProtocol(noteStoreTransport);
var noteStore = new NoteStore.Client(noteStoreProtocol);
List<Notebook> notebooks = client.listNotebooks(EvernoteCredentials.AuthToken);
http://weblogs.asp.net/psteele/archive/2010/08/06/edamlibrary-evernote-library-for-c.aspx might help. As the author states it just bundles some and fixes some. Haven't tried it myself but thought I'd mention for a possibly easier way to get started. Possibly.
This might help too...found it using the Way Back Machine since the original blog site was offline.
https://www.evernote.com/pub/bluecockatoo/Evernote_API#b=bb2451c9-b5ff-49bb-9686-2144d984c6ba&n=c30bc4eb-cca4-4a36-ad44-1e255eeb26dd
The original blog post: http://web.archive.org/web/20090203134615/http://macrolinz.com/macrolinz/index.php/2008/12/
Scroll down and find the post from December 26 - "Get it while it's hot..."

Categories