RestSharp, Twitter. update_with_media cannot authorize - c#

trying to send Tweet with the image attached, using RestSharp:
_client = new RestClient("https://api.twitter.com")
{
Authenticator = OAuth1Authenticator.ForProtectedResource(Key, Secret, Token, TokenSecret)
};
RestRequest request = new RestRequest("/1.1/statuses/update_with_media.json", Method.POST);
request.AddFile("media", att.File, att.FileName, "base64");
request.AddParameter("status", postStatus.Text);
var result = await _client.ExecuteTaskAsync(request);
The result is "Could not authenticate you" error no - 32
Thanks
UPDATE: All authentication parameters start from oauth_ and go in alphabetical order, the token, token secret, app key and app key secret are correct, the update status without media works perfectly.
UPDATE 2:
Solution
var request = new RestRequest("/1.1/statuses/update_with_media.json", Method.POST);
request.AlwaysMultipartFormData = true;
request.AddParameter("status", message, ParameterType.UrlSegment);
request.AddFile("media[]", file, filename, "application/octet-stream");
var result = _client.Execute(request);

This is actually a problem with restsharp 104.4 (version in Nuget as of time of writing)
We hit the same problem, but your solution above did not work for us. The UrlSegment parameter fails on a status update, and while it does not fail on a call to update_with_media, it also does not post the status, just the picture.
The problem is with OAuth1Authenticator, it does not ignore non-oauth POST or GET parameters, hence the authentication errors above, and why the URL segment parameter "works".
To fix this, get the latest version of RestSharp from GitHub and use that instead.
For those interested, the checkin involved was only made a month or so after the release and can be found here.

Related

ADFS v4.0 and /userinfo endpoint giving 405

Integrating older ASP.NET server-side application into ADFS for authentication, which means I pretty much had to write everything from scratch. have everything working (/authorize, /token) up until the /userinfo call.
My code, in a nutshell -
HttpClient client = new HttpClient();
var req = new HttpRequestMessage {
RequestUri = new Url("https://<server_ip>/adfs/oauth2/userinfo"),
Method = HttpMethod.Get,
};
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
req.Headers.UserAgent.Clear();
req.Headers.UserAgent.Add(new ProductInfoHeaderValue("OldApp", "11.3.0"));
var result = await client.SendAsync(req);
The result is a HTTP error 405 - Method Not Allowed. Doing searches online, I see this as a common issue when the trailing "/" is left off the url, but I get the same result with a trailing slash.
After poking around, there are a lot of examples that use newer libraries and such that I can't use, sadly. None mention usage of the /userinfo, and I'm thinking that the issue isn't necessarily in how I'm calling the URL, but configuration of the 'Application Group' in ADFS.
Okay - I found the issue, and will document it here in case others come across the same thing..
While I am not sure why /userinfo is giving a 405 - the URL I was using is wrong, despite it being listed in the Endpoints folder. There shouldn't be any "oauth2" in the URL. The correct code (and URL) is:
var req = new HttpRequestMessage {
RequestUri = new Url("https://<server_ip>/adfs/userinfo"),
Method = HttpMethod.Get,
};
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
req.Headers.UserAgent.Clear();
req.Headers.UserAgent.Add(new ProductInfoHeaderValue("OldApp", "11.3.0"));
var result = await client.SendAsync(req);
Also something to keep in mind - this has been stated elsewhere, but not as clearly as here, I hope:
The /userinfo will ONLY give you the NameIdentifier ("sub") claim. (As far as I can see.) No matter what scope you pass it. You will get all your information (that should normally be in the /userinfo call) in the "id_token" parameter from you /token call, encoded as JWT.
Personally I was led to do the same thing as you, the only solution was to download the ADAL library (You will find the link below) and debug the code in order to re-produce the same HTTP stream from ADAL.
You can create a new project so that you can integrate ADAL, for debugging or else intercepting the HTTP stream
Link ADAL

Is there a way to delete a header of a request using RestSharp

I am creating a two test case one of them validates the OK message in response with valid Authentication token and the other validates Unauthorized message with the invalid/missing token.
In first test case the valid Authentication token is provided (as header) which passes the test case. But when I created second test case with missing token it still got passed even though I did not provide any token there. How it is getting passed without the token.
I have already tried request.AddorUpdateParameter, it did not work.
Test Case I
RestClient client = new RestClient(clientName);
RestRequest request = new RestRequest("Products", Method.GET);
request.AddParameter(Common.AuthenticationKey, Common.AuthenticationValue);
IRestResponse response = client.Execute(request);
Test Case II
RestClient client = new RestClient(clientName);
RestRequest request = new RestRequest("Products", Method.GET);
IRestResponse response = client.Execute(request);
It still gives me OK status. It is taking reference of the first test case request?
The second test case should fail since authentication token is not provided.
Adding your own header should overwrite any existing headers, so adding "Accept","*" or something similar should do the trick

HTTP Request works in postman but doesn't work in code

I'm trying to access a website that requires login via a form.
I used the Postman HTTP client.
I tried to do the normally http post request but didn't seem to work, I get a successful status code (200 OK) but it doesn't log in, eventually did work with a GET request with BODY parameters (I hadn't seen GET request with body parameters).
Well, I tried to simulate this request in C# code with no luck, I even tried the generated code that Postman offers with no luck again.
Down below is the Postman request and the C# code snippet based on auto-generated Postman code. Does anyone know if is there to make this request with any library or if there is something that I miss?
Thank you in advance.
var client = new RestClient("https://thessalia-3.teilar.gr/login.asp");
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Referer", "https://thessalia-3.teilar.gr/login.asp");
var parameters = new Dictionary<string, string>();
parameters["userName"] = JsonConvert.SerializeObject("myusername");
parameters["pwd"] = JsonConvert.SerializeObject("mypass");
parameters["loginTrue"] = JsonConvert.SerializeObject("extravalue");
var content = new FormUrlEncodedContent(parameters);
request.AddParameter("application/x-www-form-urlencoded", content);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Console.WriteLine(response.StatusCode);
Postman Request Photo
Edit:
Postman Request Body Parameters
I've also tried to run this but also not logged in.
Auto-generated code form Postman
If the request was successful (200) and you got the HTML page for "Invalid Credentials", then your code that's making the request should be fine and the issue is with the credentials. Like I said in my first comment, don't serialize the parameters to JSON, URL-encode them instead:
parameters["userName"] = HttpUtility.UrlEncode("myusername");
parameters["pwd"] = HttpUtility.UrlEncode("mypass");
parameters["loginTrue"] = HttpUtility.UrlEncode("extravalue");
This is the standard way and it works with writing the parameters directly to the request stream, or with a utility class like StringContent. However, since you're using the utility class FormUrlEncodedContent, it URL-encode them for you, so you don't have to. In that case, simply assign them directly as string:
parameters["userName"] = "myusername";
parameters["pwd"] = "mypass";
parameters["loginTrue"] = "extravalue";

Trello API OAuth can't find my app

I'm using Trello's Developer API's implementation of OAuth to post stuff to a list.
I've successfully made a request and got my oauth_token and oauth_token_secret back from https://trello.com/1/OAuthGetRequestToken
But when I call https://trello.com/1/OAuthAuthorizeToken, passing the oauth_token that I've just received, I get a response of 'App not found'.
Can anyone help?
EDIT: Here's what I'm getting back from https://trello.com/1/OAuthGetRequestToken
oauth_token=8d0e43fd0cc67726567d49ae5e818852&oauth_token_secret=[secret]
And here's the Authorization header I'm sending (escaped in C#)
"OAuth oauth_version=\"1.0\", oauth_signature_method=\"HMAC-SHA1\", oauth_nonce=\"8335006\", oauth_timestamp=\"1414663625\", oauth_consumer_key=\"9612eaca23c7bdd3eca60dc8c2a8159c\", oauth_signature=\"M6sLyyfHGYXOtQnLJexDx96kbFo=\", oauth_token=\"8d0e43fd0cc67726567d49ae5e818852\""
Am I doing something wrong or is this an error on Trello's end?
EDIT: I'm using RestSharp to call the Trello API, as below:
var client = new RestSharp.RestClient("https://trello.com/");
var request = new RestSharp.RestRequest("1/OAuthAuthorizeToken", Method.GET);
EDIT: Here's the complete RestSharp code:
var client = new RestSharp.RestClient("https://trello.com/");
var request = new RestSharp.RestRequest("1/OAuthAuthorizeToken", Method.GET);
Uri uri = new Uri(string.Format("{0}/{1}", client.BaseUrl, request.Resource));
string authHeader = GenerateAuthorizationHeader(uri);
//This is the output of GenerateAuthorizationHeader()
//string authHeader = "OAuth oauth_version=\"1.0\", oauth_signature_method=\"HMAC-SHA1\", oauth_nonce=\"8335006\", oauth_timestamp=\"1414663625\", oauth_consumer_key=\"9612eaca23c7bdd3eca60dc8c2a8159c\", oauth_signature=\"M6sLyyfHGYXOtQnLJexDx96kbFo=\", oauth_token=\"8d0e43fd0cc67726567d49ae5e818852\"";
request.AddHeader("Authorization", authHeader);
The GenerateAuthorizationHeader method uses OAuth.OAuthBase to generate the TimeStamp and Signature for the OAuth request.
Looks like it might be a trello problem...
this user, had the wrong key by the sounds of things.
are you 100% sure that the key is correct.
Getting "App not found" from Trello Authentication
I had the same problem, the thing here is that OAuth is version 1.0
When you get the token and token secret from the first call you have to make your user to visit https://trello.com/1/OAuthAuthorizeToken not you.
In your case you have to redirect your user to https://trello.com/1/OAuthAuthorizeToken?oauth_token=8d0e43fd0cc67726567d49ae5e818852&scope=read,write,account
He will get a page where he can Allow the access. Then you will get a verification code in the page after the authorization to continue with your process (GetAccessToken).
You can try this as a test, in a real application you have to specify a callback url and an application name in the OAuthAuthorizeToken call.

OAuth Headers Twitter 1.1 C# Fetching Tweets

After Twitter deprecated their Twitter API 1.0, I've tried several methods in order to get the 1.1 API working for my Windows 8 application. However, what you see below is basically what I've ended up with:
public List<UserTweet.User> jsonFromTwitter;
private async void fetchTweet()
{
var jsonTwitter = new Uri("http://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=stackoverflow&result_type=recent");
HttpClient client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, jsonTwitter);
var oAuthHeader = "OAuth oauth_consumer_key=\"XXXXX\", oauth_nonce=\"XXXXX\", oauth_signature=\"XXXXX\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1318622958\", oauth_token=\"XXXXX-XXXXXX\", oauth_version=\"1.0\"";
request.Headers.Add("Authorization", oAuthHeader);
var response = await client.SendAsync(request);
var responseString = await response.Content.ReadAsStringAsync();
jsonFromTwitter = JsonConvert.DeserializeObject<List<UserTweet.User>>(await client.GetStringAsync(responseString));
//listbox.ItemsSource = jsonFromTwitter;
}
However, this won't do much good, and it switches between mainly a couple of errors. One of them can be seen below, and the other one is "Could not authenticate user" or similar, basically there's something wrong with the headers as far as I've understood.
Anyone got any ideas on how to construct a working OAuth header for this? I'm clueless at the moment.
There's a lot more you need to do for the value assigned to the Authorization header - plain text won't work. The following pages in the Twitter OAuth documentation might help you get started in the right direction.
Twitter's Docs have a section on Authentication
Authorizing a Request
Creating Signatures

Categories

Resources