Yahoo Oauth API with OAuthBase.cs - c#

I am currently using the OAuthBase.cs helper class available on oauth.net to implement OAuth to talk to the Yahoo! fantasy API. I am currently stuck on Step 5 (Using the access token/access secret to call the API Services).
I successfully completed Step 4 but cannot seem to create the actual service call. The documentation is limited; what parameters am I supposed to be using? I'm getting either a 401 or 400 http error. I'm generating my signature by:
url = new Uri("http://query.yahooapis.com/v1/public/yql?q=select * from fantasysports.teams.roster.stats where team_key='nba.l.52669.t.5' and week='5' and stats_type='week' and stats_week='5'&format=json");
signature = oauth.GenerateSignature(url, string.Empty, consumerKey, consumerSecret, accessToken, accessTokenSecret, "GET", time, string.Empty, nonce, OAuth.OAuthBase.SignatureTypes.HMACSHA1, out normalizedUrl, out normalizedRequestParameters);
using (var y = WebRequest.Create(string.Format("{0}?{1}&oauth_signature={2}", normalizedUrl, normalizedRequestParameters, signature)).GetResponse())
{
....
}
where url is the api call i'm trying to make, consumerKey / consumerSecret are the keys given to me when I signed up for Yahoo!, and accessToken / accessTokenSecret are the response returned from request_auth in Step 4. What am I doing wrong?
Thanks in advance
EDIT: 12/14 - for those not familiar with OAuthBase, it is essentially a library that generates the signature by
1. Consolidating all the url/parameters (consumerkey, token, tokenSecret, httpMethod, nonce, time etc), sorting it, and normalizing the url/parameters;
2. Encodes the consumerSecret '&' tokenSecret as the HMACSHA1 key;
3. computing the hash of the hmacsha1 key

Here is some working code for accessing a Yahoo API using OAuth (in this case the BOSS Geo API)
[Test]
public void MakeCallToBossGeoApi()
{
string result;
var uri = new Uri(#"http://yboss.yahooapis.com/geo/placefinder?country=SE&flags=J&locale=sv_SE&postal=41311");
var o = new OAuthBase();
string nonce = o.GenerateNonce();
var timestamp = o.GenerateTimeStamp();
string normalizedUrl;
string normalizedParameters;
string signature = HttpUtility.UrlEncode(
o.GenerateSignature(uri,
"yourconsumerkeyhere",
"yourconsumersecrethere", null, null, "GET",
timestamp, nonce, out normalizedUrl,
out normalizedParameters));
uri = new Uri(normalizedUrl +"?"+ normalizedParameters + "&oauth_signature=" + signature );
using (var httpClient = new WebClient())
{
result = httpClient.DownloadString(uri.AbsoluteUri);
}
Console.WriteLine(result);
}

Related

HttpClient not returning json value of URI

I am trying to use HttpClient to GET information from Jira, but I am unable to see any of the information. I want to be able to get all the bugs that match certain filters so that I can add them to a table in my program.
I have tried to access Jira with the rest api, but every time I do it says that the issue or project doesn't exist. The thing is that if I enter the URI into the bar at the top of my browser I can see the JSON text that I want. This leads me to believe that the reason my code is not returning these values is because of an authorization issue. I am using basic auth to send my credentials. I also want to add that I used cURL in cmd to test my credentials with basic auth and it worked.
public async Task<JiraModel> GetBugs()
{
using (var client = new HttpClient())
{
string url = "https://myurl.atlassian.net/rest/api/3/project/VCMF";
String username = "username";
String password = "apikey";
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("UTF-8").GetBytes(username + ":" + password));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "Basic " + encoded);
client.BaseAddress = new Uri("https://myurl.atlassian.net/rest/api/3/project/VCMF");
var response = await client.GetAsync(url);
var content = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<JiraModel>(content);
}
}
I should be getting the json results in string form by the end of this length of code, but I keep getting a 404 error instead that for this code specifically says "No project could be found with key 'VCMF'".
The issue here is that you're creating the authorization header incorrectly.
The constructor you're using for AuthenticationHeaderValue class takes two arguments: scheme and parameter:
public AuthenticationHeaderValue(string scheme, string parameter)
{
}
The first argument should be the scheme (Basic in this case) and the second, the base64-encoded credentials:
So instead of:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", "Basic " + encoded);
It should be:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encoded);
Hope this helps!

AWS Item LookUp URL Signature

I'm new to AWS, I'm trying to lookup an item by UPC within my UWP App. I'm having issues adding the signature to the request URL. I keep receiving "The request signature we calculated does not match the signature you provided."
Has any had any experience with making calls to Amazon? There api documentation isn't really aimed towards C# in most places.
public async void ItemLookup(string itemID)
{
Dictionary<string, string> fields = new Dictionary<string, string>();
fields.Add("AssociateTag", associateTag);
fields.Add("Condition", "All");
fields.Add("IdType", "UPC");
fields.Add("ItemId", itemID);
fields.Add("Operation", "ItemLookup");
fields.Add("ResponseGroup", "Large");
fields.Add("SearchIndex", "All");
fields.Add("Service", "AWSECommerceService");
// fields.Add("Timestamp", Uri.EscapeDataString(DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:sssZ")));
// Build Url for signing
string url = string.Empty;
foreach (var pair in fields)
{
url += "&" + pair.Key + "=" + pair.Value;
}
url = Uri.EscapeUriString(endpoint
+ "AWSAccessKeyId=" + accessKeyId
+ url);
// Add Timestamp
url += "&Timestamp=" + Uri.EscapeDataString(DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", CultureInfo.InvariantCulture));
// URL http://webservices.amazon.co.uk/onca/xml?AWSAccessKeyId=REMOVED&AssociateTag=REMOVED&Condition=All&IdType=UPC&ItemId=786936724943&Operation=ItemLookup&ResponseGroup=Large&SearchIndex=All&Service=AWSECommerceService&Timestamp=2017-11-22T11%3A34%3A42.602Z
// SCRATCHPAD http://webservices.amazon.co.uk/onca/xml?AWSAccessKeyId=REMOVED&AssociateTag=REMOVED&Condition=All&IdType=UPC&ItemId=786936724943&Operation=ItemLookup&ResponseGroup=Large&SearchIndex=All&Service=AWSECommerceService&Timestamp=2017-11-22T09%3A20%3A35.000Z
// &Signature=Lvqlenpx0wos4Hg6ZzSNHqOc1QwktXgt8nFHBTfTON4%3D
Byte[] secretBytes = UTF8Encoding.UTF8.GetBytes(secretKey);
HMACSHA256 hmac = new HMACSHA256(secretBytes);
Byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(url);
Byte[] hash = hmac.ComputeHash(dataBytes);
String signature = Convert.ToBase64String(hash);
// Full URL
string requestURL = url + "&Signature=" + signature;
HttpClient httpClient = new HttpClient();
HttpResponseMessage responseMessage = await httpClient.GetAsync(requestURL);
var response = await responseMessage.Content.ReadAsStringAsync();
}
}
I have the url from amazon scratchpad commented out against my own url, they are aligned but I'm not 100% sure if I'm working on the signature correctly.
Any help would be greatly appreciated
Kevin
I haven't tested the following yet. But there are doc about what you ruquest. Have you checked the following to create your signature?
First, the whole process listed here told us that you need to use a signed URL
Second, for how to create a URL Signature Using C# and the .NET, you can refer to the following doc: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateSignatureInCSharp.html
By the way, you can check the example code first.
You can use the following nuget package.
PM> Install-Package Nager.AmazonProductAdvertising
Lookup example
var authentication = new AmazonAuthentication();
authentication.AccessKey = "accesskey";
authentication.SecretKey = "secretkey";
var wrapper = new AmazonWrapper(authentication, AmazonEndpoint.UK);
var result = wrapper.Lookup("B00BYPW00I");

Why does my OAuth signature not match when connecting to WordPress via OAuth 1.0 in C#?

I am trying to complete the first step in the OAuth 1.0 authentication process and retrieve an unauthorized request token.
I keep getting a 401 OAuth signature does not match error from WordPress. I know the problem is with the way I am hashing my signature because when I use Postman, the signature I calculate is different than the signature that Postman calculates. Also I can successfully retrieve and unauthorized request token via Postman.
Where I am going wrong in computing my hash? I'm using HMAC-SHA1.
private void AuthorizeWP()
{
string requestURL = #"http://mywordpressurl.com/oauth1/request";
UriBuilder tokenRequestBuilder = new UriBuilder(requestURL);
var query = HttpUtility.ParseQueryString(tokenRequestBuilder.Query);
query["oauth_consumer_key"] = "myWordPressKey";
query["oauth_nonce"] = Guid.NewGuid().ToString("N");
query["oauth_signature_method"] = "HMAC-SHA1";
query["oauth_timestamp"] = (Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds)).ToString();
string signature = string.Format("{0}&{1}&{2}", "GET", Uri.EscapeDataString(requestURL), Uri.EscapeDataString(query.ToString()));
string oauth_Signature = "";
using (HMACSHA1 hmac = new HMACSHA1(Encoding.ASCII.GetBytes("myWordPressSecret")))
{
byte[] hashPayLoad = hmac.ComputeHash(Encoding.ASCII.GetBytes(signature));
oauth_Signature = Convert.ToBase64String(hashPayLoad);
}
query["oauth_signature"] = oauth_Signature;
tokenRequestBuilder.Query = query.ToString();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tokenRequestBuilder.ToString());
request.Method = "GET";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
}
I realize now what I was doing wrong.
With OAuth 1.0 when you generate the bytes for your hash key, you have to concatenate your consumer/client secret and the token with an '&' in the middle even if you don't have a token.
Source: https://oauth1.wp-api.org/docs/basics/Signing.html
So in my code above:
using (HMACSHA1 hmac = new HMACSHA1(Encoding.ASCII.GetBytes("myWordPressSecret")))
needs to be:
using (HMACSHA1 hmac = new HMACSHA1(Encoding.ASCII.GetBytes("myWordPressSecret&"))

Unable to query Yahoo! Fantasy Sports API

I am trying to pull details from Yahoo! Fantasy Sports API using OAuth2.0. I got the access_token to query using YQL. My code
using (var client = new System.Net.WebClient())
{
client.Headers.Add("Authorization", "Bearer " + response.access_token);
var query = "select%20*%20from%20fantasysports.games%20where%20game_key%3D'nfl'";
Response.Write(query);
var url = String.Format("https://query.yahooapis.com/v1/yql?q={0}&format=json&diagnostics=true&callback=", query);
output = client.DownloadString(url);
}
My response
{
"query": {
"count": 0,
"created": "2015-09-27T17:39:48Z",
"lang": "en-US",
"diagnostics": {
"publiclyCallable": "true",
"url": {
"execution-start-time": "4",
"execution-stop-time": "137",
"execution-time": "133",
"http-status-code": "401",
"http-status-message": "Authorization Required",
"content": "http://fantasysports.yahooapis.com/fantasy/v2/games;game_keys=nfl"
},
"user-time": "138",
"service-time": "133",
"build-version": "0.2.240"
},
"results": null
}
}
I am getting an Authorization Required status message.
I think it has got to do something with my request header. Can someone help me on understanding why my request is rejected here?
Yahoo! has two OAuth Authorization Flows
Two legged flow
Three legged flow
Yahoo notes,
Most of the Fantasy API data relies on 3-legged OAuth, as much of the
data is specific to a certain Yahoo! user. However, you can use
2-legged OAuth to request purely public data. 2-legged OAuth
effectively boils down to making a request without setting an access
token through the default PHP OAuth library, or effectively using your
consumer key/secret as the token.
So we should go for three-legged flow of OAuth authorization as exactly described in the Yahoo! documentation. At the end of the authorization flow, you will get a oauth_token and oauth_token_secret.
Yahoo have provided this code in C# (Link here).
public static string GetUserDataFromYahoo(string requestEndPoint, string token, string tokenSecret)
{
var data = String.Empty;
var uri = new Uri(requestEndPoint);
string url, param;
var oAuth = new OAuthBase();
var nonce = oAuth.GenerateNonce();
var timeStamp = oAuth.GenerateTimeStamp();
var signature = oAuth.GenerateSignature(
uri,
consumerKey,
consumerSecret,
token,
tokenSecret,
"GET",
timeStamp,
nonce,
OAuthBase.SignatureTypes.HMACSHA1,
out url,
out param);
data = String.Format("{0}?{1}&oauth_signature={2}", url, param, signature);
var requestParametersUrl = String.Format("{0}?{1}&oauth_signature={2}", url, param, signature);
var request = WebRequest.Create(requestParametersUrl);
using (var response = request.GetResponse())
using (Stream dataStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(dataStream))
{
data = reader.ReadToEnd();
}
return data;
}
This code uses this OAuthBase.cs class.
And when you use this code, you will get a
OST_OAUTH_SIGNATURE_INVALID_ERROR
That is because, OAuthBase.cs has a bug that's been noted here. To correct that you have to do this.
Line 199 (in NormalizeRequestParameters method) must change from:
sb.AppendFormat("{0}={1}", p.Name, p.Value);
to
sb.AppendFormat("{0}={1}", UrlEncode(p.Name), UrlEncode(p.Value));
Happy coding!
I suggest that you have not correctly received the access_token. This is why you get Authorization Required on the call to the server.
You need to check your code that gets the access_token

Access Etsy API oauth using c# RestSharp

I set up a developer acct under our shop, to access our sales receipts. I decided to use RestSharp to make my requests. I have proved it works for none Oauth required calls. I have successfully received my accessToken and accessTokenSecret. So i use those along with the customerKey and customerSecret to make a ForProtectedResource call, for a oauth request as follows but always receive "This method requires authentication".
I'm hoping its something simple I'm missing. I thought, all I need to make any call are those four items correct? Once I have those four items I don't have to request or access token anymore, correct? Thanks
var access_token = "#########################";
var access_token_secret = "########";
var baseUrl = "https://openapi.etsy.com/v2";
var client = new RestClient(baseUrl);
client.Authenticator = OAuth1Authenticator.ForProtectedResource(consumerKey,
consumerSecret,
access_token,
access_token_secret);
var request = new RestRequest("shops/########/receipts");
request.Method = Method.GET;
request.AddParameter("api_key", consumerKey);
client.ExecuteAsync(request, response =>
{
var r = response;
});
After some trial and error I finally wrapped my head around OAuth and the way Etsy implements it. The api_key parameter is only to be used when you're calling a none OAuth required method. Otherwise you have to send it all the required OAuth params. Below is working code. I leveraged RestSharp, as well as this OAuth base I found here. Hope this help some poor sap from staring at crappy code for 3 days (like yours truly).
var restClient = new RestClient(baseUrl);
OAuthBase oAuth = new OAuthBase();
string nonce = oAuth.GenerateNonce();
string timeStamp = oAuth.GenerateTimeStamp();
string normalizedUrl;
string normalizedRequestParameters;
string sig = oAuth.GenerateSignature(new Uri(baseUrl + MethodLocation), consumerKey, consumerSecret, Accesstoken, AccessTokenSecret, "GET", timeStamp, nonce, out normalizedUrl, out normalizedRequestParameters);
// sig = HttpUtility.UrlEncode(sig);
var request = new RestRequest(MethodLocation);
request.Resource = string.Format(MethodLocation);
request.Method = Method.GET;
// request.AddParameter("api_key", consumerKey);
request.AddParameter("oauth_consumer_key", consumerKey);
request.AddParameter("oauth_token", Accesstoken);
request.AddParameter("oauth_nonce", nonce);
request.AddParameter("oauth_timestamp", timeStamp);
request.AddParameter("oauth_signature_method", "HMAC-SHA1");
request.AddParameter("oauth_version", "1.0");
request.AddParameter("oauth_signature", sig);
restClient.ExecuteAsync(request, response =>
{
var r = response;
});

Categories