I can explain what I think the problem is/was.
I wasn't providing adequate information for the server to respond correctly to me.
This all started working when I appended "%26" to theend of the oauh_signature since I am using PLAINTEXT.
I have to admit, this whole OAuth process has thrown me for a loop.
At the moment, I need to figure out how to send this in HMAC-SHA1 form.
Anyways, for those who are in my spot, and want to try OAuth in C# in a really ad-hoc manner, here is my code, which I dont back in the least.
CODEBOX
namespace oauth {
/// <summary>
/// Used to authenticate OAuth to Yahoo Services
/// </summary>
public class YahooOAuth {
/// <summary>
/// Encoding to use for talking to services
/// </summary>
private static Encoding m_encoding;
/// <summary>
/// Initialize Static Members
/// </summary>
static YahooOAuth() {
m_encoding = Encoding.ASCII;
}
/// <summary>
/// Consumer Context, generated / updated by responses from yahoo services
/// </summary>
public class consumer_context {
/// <summary>
/// initialize request qoken response
/// </summary>
/// <param name="source">Output from service response</param>
public consumer_context(string source) {
refresh(source);
return;
}
/// <summary>
/// Update Parameters from service response
/// </summary>
/// <param name="source">Output from service response</param>
public void refresh(string source) {
string[] strTok = source.Split(new string[] { "&" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string parameter in strTok) {
string[] pair = parameter.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries);
typeof(consumer_context).GetProperty(pair[0]) //member names conveniently named from responses
.SetValue(this, HttpUtility.UrlDecode(pair[1]), null);
}
}
public string oauth_token { get; set; }
public string oauth_token_secret { get; set; }
public string oauth_expires_in { get; set; }
public string xoauth_request_auth_url { get; set; }
public string oauth_callback_confirmed { get; set; }
public string oauth_session_handle { get; set; }
public string xoauth_yahoo_guid { get; set; }
public string oauth_authorization_expires_in { get; set; }
}
/// <summary>
/// Step 1: Get Request Token,
///
/// </summary>
/// <param name="consumer_key">Yahoo Application Consumer Key</param>
/// <param name="consumer_secret">Yahoo Application Consumer Secret</param>
/// <returns>Token response</returns>
public static consumer_context get_request_token(string consumer_key, string consumer_secret) {
OAuthBase oauth = new OAuthBase();
string url = Resources.url_get_request_token;
string token_response;
string timestamp = oauth.GenerateTimeStamp();
string nonce = oauth.GenerateNonce();
//Build parameters to post to get_request_token
StringBuilder parameters = new StringBuilder();
parameters.Append("oauth_consumer_key="); parameters.Append(consumer_key);
parameters.Append("&oauth_signature="); parameters.Append(consumer_secret); parameters.Append("%26"); //%26 must be appended for plaintext
parameters.Append("&oauth_nonce="); parameters.Append(nonce);
parameters.Append("&oauth_signature_method="); parameters.Append("PLAINTEXT");
parameters.Append("&oauth_timestamp="); parameters.Append(timestamp);
parameters.Append("&oauth_version="); parameters.Append("1.0");
parameters.Append("&oauth_callback="); parameters.Append("oob");
byte[] data = m_encoding.GetBytes(parameters.ToString());
//Post Parameters to get_request_token
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (Stream request_stream = request.GetRequestStream()) {
request_stream.Write(data, 0, data.Length);
request_stream.Flush();
}
//Grab response from service
using (WebResponse response = request.GetResponse()) {
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
token_response = reader.ReadToEnd();
}
}
return new consumer_context(token_response);
}
/// <summary>
/// Get/Refresh Access Token
/// </summary>
/// <param name="consumer_key">Yahoo Application Consumer Key</param>
/// <param name="consumer_secret">Yahoo Application Consumer Secret</param>
/// <param name="get_request_token">Request Token Obtained</param>
/// <param name="verifier_token">verifier token manually obtained, may be null</param>
/// <returns></returns>
public static consumer_context get_access_token(string consumer_key, string consumer_secret, consumer_context context, string verifier_token) {
OAuthBase oauth = new OAuthBase();
string url = Resources.url_get_access_token;
string token_response;
string timestamp = oauth.GenerateTimeStamp();
string nonce = oauth.GenerateNonce();
string normal_url, normal_parameters,
signature = oauth.GenerateSignature(
new Uri(url),
consumer_key,
consumer_secret,
context.oauth_token,
context.oauth_token_secret,
"POST",
timestamp,
nonce, OAuthBase.SignatureTypes.PLAINTEXT,
out normal_url,
out normal_parameters);
//Build parameters to post to get_request_token
StringBuilder parameters = new StringBuilder();
parameters.Append("oauth_consumer_key="); parameters.Append(consumer_key);
parameters.Append("&oauth_signature_method="); parameters.Append("PLAINTEXT");
parameters.Append("&oauth_signature="); parameters.Append(signature);
parameters.Append("&oauth_version="); parameters.Append("1.0");
if (verifier_token != null) {
parameters.Append("&oauth_verifier="); parameters.Append(verifier_token);
} else {
parameters.Append("&oauth_session_handle="); parameters.Append(context.oauth_session_handle);
}
parameters.Append("&oauth_token="); parameters.Append(context.oauth_token);
parameters.Append("&oauth_timestamp="); parameters.Append(timestamp);
parameters.Append("&oauth_nonce="); parameters.Append(nonce);
byte[] data = m_encoding.GetBytes(parameters.ToString());
//Post Parameters to get_request_token
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
using (Stream request_stream = request.GetRequestStream()) {
request_stream.Write(data, 0, data.Length);
request_stream.Flush();
}
//Grab response from service
using (WebResponse response = request.GetResponse()) {
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
token_response = reader.ReadToEnd();
}
}
//Update Consumer Context
context.refresh(token_response);
return context;
}
}
}
This of course has a dependency on OAuthBase, while I figure out how to use it. =)
The resources, are just the two urls,
https://api.login.yahoo.com/oauth/v2/get_tokenand
https://api.login.yahoo.com/oauth/v2/get_request_tokenrespectively
So, as far as OAuth sessions, this works fine.
I've yet to figure out how to apply this to a service call, but I think it works in the same way,
Make a web request to the service call url, and add the oauth parameters (as done for get_token),
except I believe the service call requires it to be encrypted, I dont think I can use PLAINTEXT.
If anyone wants to review that, or amend/clarify for my understanding, I would be profoundly grateful..