OAuth RequestToken returning 403 - c#

I'm trying to implement the OAuth using a simple class but I'm getting an error
public OAuthResponse AcquireRequestToken(string uri, string method)
{
NewRequest();
var authzHeader = GetAuthorizationHeader(uri, method);
// prepare the token request
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(uri);
request.Headers.Add("User-Agent", "MyAppId/1.0.3 +http://example.pt/");
request.Headers.Add("Authorization", authzHeader);
request.Method = method;
request.ContentLength = 0;
using (var response = (System.Net.HttpWebResponse)request.GetResponse())
{
using (var reader = new System.IO.StreamReader(response.GetResponseStream()))
{
var r = new OAuthResponse(reader.ReadToEnd());
this["token"] = r["oauth_token"];
// Sometimes the request_token URL gives us an access token,
// with no user interaction required. Eg, when prior approval
// has already been granted.
try
{
if (r["oauth_token_secret"] != null)
this["token_secret"] = r["oauth_token_secret"];
}
catch { }
return r;
}
}
}
The error it's in this line
var response = (System.Net.HttpWebResponse)request.GetResponse()
and the error is
Aditional information: The remote server returned an error: (403)
Forbidden.
Any Help? Here is the full OAuth class https://cropperplugins.codeplex.com/SourceControl/changeset/view/65377#1710422
Also the service that i'm trying to access it's Discogs.com API DOCS: http://www.discogs.com/developers
UPDATE 1
I've added the user-agent header the discogs Staff said it was needed but now I have another error on the User-Agent line request.Headers.Add("User-Agent", "BandFollowerWD/1.0.3 +http://pcdev.pt/");
The 'User-Agent' header must be modified with the appropriate property or method.

After searching furder more I've found the answer....
Instead of using request.Headers.Add("User-Agent", "MyAppId/1.0.3 +http://example.pt"); I've used request.UserAgent = "MyAppId/1.0.3 +http://example.pt";

Related

Bing Webmaster Tools API OAuth code exchange issues, changes?

This is part of a desktop application.
Based on https://learn.microsoft.com/en-us/bingwebmaster/oauth2
The following code to exchange the authorization code for the access and refresh tokens was working as of a few months ago...
try
{
HttpWebRequest req = WebRequest.CreateHttp("https://www.bing.com/webmasters/oauth/token");
req.Method = WebRequestMethods.Http.Post;
req.ContentType = "application/x-www-form-urlencoded";
StringBuilder content = new StringBuilder();
content.AppendFormat("code={0}&", Uri.EscapeDataString(code));
content.AppendFormat("client_id={0}&", Uri.EscapeDataString(clientId));
content.AppendFormat("client_secret={0}&", Uri.EscapeDataString(clientSecret));
content.AppendFormat("redirect_uri={0}&", Uri.EscapeDataString(redirectUri));
content.AppendFormat("grant_type={0}", Uri.EscapeDataString("authorization_code"));
var data = Encoding.ASCII.GetBytes(content.ToString());
using (var stream = await req.GetRequestStreamAsync())
{
await stream.WriteAsync(data, 0, data.Length);
}
string json;
using (var res = await req.GetResponseAsync())
{
using (var stream = res.GetResponseStream())
using (var sr = new StreamReader(stream))
{
json = await sr.ReadToEndAsync();
}
}
if (!string.IsNullOrWhiteSpace(json))
{
tokenResponse = JsonConvert.DeserializeObject<TokenResponse>(json);
}
}
catch (WebException wex)
{
using (var stream = wex.Response.GetResponseStream())
using (var sr = new StreamReader(stream))
{
var t = await sr.ReadToEndAsync();
}
}
catch (Exception ex)
{
}
However, await req.GetResponseAsync() now returns
400 Bad Request, Origin and Referer request headers are both
absent/empty
I tried adding req.Referer = redirectUri; and then it returns
400 Bad Request, Could not extract expected anti-forgery token
I've tried passing a random state parameter to the authorization endpoint, and received the same in the callback. I've both included it in, and excluded it from, the token exchange with no change in the above results.
I'm not an OAuth expert, but I've done a few integrations and I haven't seen this before.
The user grants authorization via a Window with a WebView2 control, which returns the code. This part still works well. I did some quick poking around in the response to see if anything related to anti-forgery/CSRF was being returned from the server, but I didn't notice anything. And anyway, the documentation hasn't change regarding what is needed to request the tokens so everything is basically trial and error at this point.
So my question is, if you have seen this referer/anti-forgery problem in any OAuth implementation how did you fix it or work around it? Or if you're using a Bing Webmaster Tools API solution (custom or otherwise) is it still working?
Beyond that, I'm open to ideas and I appreciate your time.

How to send request to the HTTP Header using the json webservice in windows store app

I'm working on a windows store app where I am using a web service which has parameters for downloading videos that are given below.
[request addValue:Token Id forHTTPHeaderField:#"Authorization"];
Through log_in web services I get the access token which I have to pass as value in the Authorization a request to the HTTP Header.
Token token="hgmgmhmhgm6dfgffdbfetgjhgkj4mhh8dghmge"
I have to send both these parameters with the web service given to me but I am unable to send them as I'm getting the error status code 404 unauthorized.
Here is my code:
System.Net.Http.HttpClient httpClient1 = new System.Net.Http.HttpClient();
httpClient1.DefaultRequestHeaders.Date = DateTime.Now;
httpClient1.DefaultRequestHeaders.Add("Authorization",acesstoken);
var httpResponse1 = await httpClient.GetAsync("http://gbdfbbnbb#gfdh.co/appi/fdbfdses/3/videos");
string vale = await httpResponse1.Content.ReadAsStringAsync();
string responses = vale;
I know my code is wrong and I need to correct it. Help me with your valuable suggestions.
Try this code
using (var client = new HttpClient())
{
try
{
String url = "https://www.example-http-request.com/json";
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("Authorization", acesstoken)
};
HttpResponseMessage response = await httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
var responsesStr = await response.Content.ReadAsStringAsync();
if (!responsesStr.Equals(""))
{
//http request data now capture in responseToken string.
//you can change name as per your requirement.
String responseOutput = responsesStr;
//now convert/parse your json using Newtonsoft JSON library
// Newtonsoft JSON Librar link : { http://james.newtonking.com/json }
//LoggingModel is a class which is the model of deserializing your json output.
LoggingModel array = JsonConvert.DeserializeObject<LoggingModel>(responseOutput);
bool isSuccess = array.IsSuccessful;
if (isSuccess == true)
{
//if success
}else{
//if login failed
}
}else{
//no response in http request failed.
}
}
catch (Exception ex)
{
//catch exceptio here
}
}

About: get REST - returning a NotFound exception C#

Attempting to retrieve quota information from Google Drive via REST in C#. Here is a code snippet:
public async Task<string> HasQuota(string accessToken) {
var url = string.Concat(new string[] {
" https://www.googleapis.com/drive/v2/about",
"?access_token=" + accessToken,
"&fields=quotaBytesTotal%2CquotaBytesUsed"
});
// Create the request.
var request = WebRequest.Create(url) as HttpWebRequest;
request.Method = "GET";
// Create the response.
var response = await Task<WebResponse>.Factory.FromAsync(
request.BeginGetResponse,
request.EndGetResponse,
request
);
if (((HttpWebResponse)response).StatusDescription == "OK") {
using (Stream stream = response.GetResponseStream()) {
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
return null;
}
When I obtained the access_token I scoped the authentication request with https://www.googleapis.com/auth/drive.file and my test user granted permissions. So as far as I aware I have the code requirements to execute this call.
However I get an NotFound exception when I attempt to execute this method. The documentation says I can pass the access_token in the query string or add the Authorization header to the request i.e
request.Headers["Authorization"] = string.Format("Bearer {0}", accessToken);
Any ideas why I might be getting this exception?
Thanks
I hadn't enabled the Drive API option in the console...

Live connect SDK REST request for updating token

I'm trying to update token, but I get error "The remote server returned an error: (400) Bad Request."
My code is:
public static object Refresh_token(string client_id, string redirect_uri, string client_secret, string refresh_token, string scope)
{
var requestUrl = new StringBuilder("https://login.live.com/oauth20_token.srf");
requestUrl.Append("?grant_type=refresh_token");
requestUrl.AppendFormat("&client_id={0}", client_id);
requestUrl.AppendFormat("&redirect_uri={0}", HttpUtility.UrlEncode(redirect_uri));
requestUrl.AppendFormat("&client_secret={0}", HttpUtility.UrlEncode(client_secret));
requestUrl.AppendFormat("&refresh_token={0}", refresh_token);
WebRequest request = HttpWebRequest.Create(requestUrl.ToString());
request.Method = "GET";
request.ContentType = "application/x-www.form-urlencoded;charset=UTF-8";
WebResponse response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
var json = reader.ReadToEnd();
return JsonConvert.DeserializeObject<Offline_access>(json);
}
}
If I send it from browser I get
{"error":"invalid_scope","error_description":"The provided request must include a 'scope' input parameter."}
I tried to do it with POST, but it was the same problem.
Have some ideas?
Seems like the spec changed on the web server side and it's expecting you to send a scope parameter. I don't know what the scope parameter is and what you need to supply to it but essentially you'll need to add a line for the requestUrl to add it.
requestUrl.AppendFormat("&scope={0}", {whatever value the scope is suppose to be});

Getting signature_invalid calling oauth/request_token for Etsy's API using RestSharp

I'm trying to use RestSharp to access Etsy's API. Here's the code I'm using attempting to get an OAuth access token:
var authenticator = OAuth1Authenticator.ForRequestToken(
ConfigurationManager.AppSettings["ApiKey"],
ConfigurationManager.AppSettings["ApiSecret"]);
// same result with or without this next line:
// authenticator.ParameterHandling = OAuthParameterHandling.UrlOrPostParameters;
this.Client.Authenticator = authenticator;
var request = new RestRequest("oauth/request_token")
.AddParameter("scope", "listings_r");
var response = this.Client.Execute(request);
Etsy tells me that the signature is invalid. Interestingly enough, when I enter the timestamp and nonce values generated by the request into this OAuth signature validation tool, the signatures don't match. Moreover, the URL generated by the tool works with Etsy where the one generated by RestSharp doesn't. Is there something I'm doing wrong or something else I need to configure with RestSharp?
Note: I'm using the version of RestSharp provided by their Nuget package, which at the time of this posting is 102.5.
I finally was able to connect to the Etsy API with RestSharp using OAuth. Here is my code -- I hope it works for you...
RestClient mRestClient = new RestClient();
//mRestClient.BaseUrl = API_PRODUCTION_URL;
mRestClient.BaseUrl = API_SANDBOX_URL;
mRestClient.Authenticator = OAuth1Authenticator.ForRequestToken(API_KEY,
API_SHAREDSECRET,
"oob");
RestRequest request = new RestRequest("oauth/request_token", Method.POST);
request.AddParameter("scope",
"shops_rw transactions_r transactions_w listings_r listings_w listings_d");
RestResponse response = mRestClient.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
return false;
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(response.Content);
string oauth_token_secret = queryString["oauth_token_secret"];
string oauth_token = queryString["oauth_token"];
string url = queryString["login_url"];
System.Diagnostics.Process.Start(url);
// BREAKPOINT HERE
string oauth_token_verifier = String.Empty; // get from URL
request = new RestRequest("oauth/access_token");
mRestClient.Authenticator = OAuth1Authenticator.ForAccessToken(API_KEY,
API_SHAREDSECRET,
oauth_token,
oauth_token_secret,
oauth_token_verifier);
response = mRestClient.Execute(request);
if (response.StatusCode != System.Net.HttpStatusCode.OK)
return false;
queryString = System.Web.HttpUtility.ParseQueryString(response.Content);
string user_oauth_token = queryString["oauth_token"];
string user_oauth_token_secret = queryString["oauth_token_secret"];
The user_oauth_token and user_oauth_token_secret are the user's access token and access token secret -- these are valid for the user until the user revokes access.
I hope this code helps!

Categories