C# Twitter request OAuth Token - c#

I am trying to request token from the Twitter API based on my consumer key and consumer secret key. However I am getting a The remote server returned an error: (403) Forbidden which I am not sure why?
This is my attempt so far
//Get Request Token
string oauth_consumer_key = "<consumer key>";
string oauth_consumer_secret = "<consumer secret>";
Uri requestToken = new Uri("https://api.twitter.com/oauth2/token?oauth_consumer_key=" + oauth_consumer_key + "&oauth_consumer_secret=" + oauth_consumer_secret);
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requestToken);
req.Method = "POST";
try
{
using (var response = req.GetResponse() as HttpWebResponse)
if (req.HaveResponse && response != null)
{
}
}
catch (WebException wex)
{
}
The code is incomplete however running through it I always seem to get a Forbidden exception?
If I post the URL request as follows, it works fine and returns the token
https://twitter.com/oauth/request_token?oauth_consumer_key=bidjtABOkF0b3mvw1UaHWDf7x&oauth_consumer_secret=qWO208QapZvckBoyWu3QET8uFnBXXlG3tSTWSS8oAOtoY8qwHD
Am I doing something wrong?

Solved my problem by using Task / Asyc and also adding authorization OAuth headers. Now able to get access token
Here is my solution:
public async Task<ActionResult> AccessToken()
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.twitter.com/oauth2/token");
string oauth_consumer_key = "<consumer key>";
string oauth_consumer_secret = "<consumer secret>";
string url = "https://api.twitter.com/oauth2/token?oauth_consumer_key=" + oauth_consumer_key + "&oauth_consumer_secret=" + oauth_consumer_secret;
var customerInfo = Convert.ToBase64String(new UTF8Encoding()
.GetBytes(oauth_consumer_key + ":" + oauth_consumer_secret));
// Add authorization to headers
request.Headers.Add("Authorization", "Basic " + customerInfo);
request.Content = new StringContent("grant_type=client_credentials", Encoding.UTF8,
"application/x-www-form-urlencoded");
HttpResponseMessage response = await httpClient.SendAsync(request);
string json = await response.Content.ReadAsStringAsync();
var serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(json);
ViewBag.access_token = item["access_token"];
return View();
}

Related

How to get access token, refresh token in .NET Core (C#) without using SDK (Manually) in QuickBooks Online API?

I have created a simple console app in C#, I need to request access token without using SDK. I have managed to launch a URL to request code. I get code but trying to call the access_token endpoint is a challenge. I need help on how I can get access_token and refresh_token. Attached is the screenshot of codes having all the request details and the endpoint I used as follows.
Endpoint used: https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer
Parameters: code,=[codeReceived] grant_type = authorization_code and redirect_uri = [RedirectUrl]
Headers:Authorization: Basic [Base64EncodedBytes], Accept: application/json, Host: oauth.platform.intuit.com, Content-Type: application/x-www-form-urlencoded
I have created a simple console app in C#, I need to request access token without using SDK. I have managed to launch a URL to request code. I get code but trying to call the access_token endpoint is a challenge. I need help on how I can get access_token and refresh_token. Attached is the screenshot of codes having all the request details and the endpoint I used as follows.
Posting
Endpoint used: https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer
Parameters:[enter image description here][1]
code,=[codeReceived] grant_type = authorization_code and redirect_uri = [RedirectUrl]
Headers:
Authorization: Basic [Base64EncodedBytes], Accept: application/json, Host: oauth.platform.intuit.com, Content-Type: application/x-www-form-urlencoded
This is the Client Class I've created:
public class RestClient
{
public string ClientID;
public string ClientSecret;
public string RedirectUrl = "https://devices.pythonanywhere.com/";
public string Environment = "sandbox";
private async Task<string> GetAccessTokenAsync(string Url, string code, string ClientId, string ClientSecret)
{
var stringBytes = Encoding.UTF8.GetBytes($"{ClientId}:{ClientSecret}");
var encodedBytes = Convert.ToBase64String(stringBytes);
var uriBuilder = new UriBuilder(Url);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query["grant_type"] = "authorization_code";
query["code"] = $"{code}";
query["redirect_uri"] = $"{RedirectUrl}";
uriBuilder.Query = query.ToString();
Url = uriBuilder.ToString();
var DecodedUrl = HttpUtility.UrlDecode(Url);
Console.WriteLine(encodedBytes);
HttpRequestMessage request = new(HttpMethod.Post, DecodedUrl);
request.Headers.Add("Accept", "application/json");
request.Headers.Add("Authorization", $"Basic {encodedBytes}");
request.Headers.Add("Host", "oauth.platform.intuit.com");
request.Content = new StringContent("application/x-www-form-urlencoded");
using HttpClient client = new();
using HttpResponseMessage response = await client.SendAsync(request);
var body = response.Content.ReadAsStringAsync();
return body.Result;
}
public string GetTokens(string Url, string code, string ClientId, string ClientSecret)
{
try
{
var response = GetAccessTokenAsync(Url, code, ClientId, ClientSecret).Result;
if (response.Length>0)
{
return "There is data";
}
return "No data";
}
catch (Exception ex)
{
return ex.Message;
}
}
}
and this here is where I'm calling it
class Program
{
static void Main(string[] args)
{
var client = new RestClient();
client.ClientID = "AB8EMz5arbI**************************************";
client.ClientSecret = "4y4vsz*********************************";
var OauthUrl = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
var code = "AB11644908535RgJ**************************";
Console.WriteLine($"Response: {client.GetTokens(OauthUrl, code, client.ClientID, client.ClientSecret)}");
}
}
I was making a mistake in my C# code. Here is the working code that I used in GetAccessTokenAsync:
private async Task<string> GetAccessTokenAsync(string Url, string code, string ClientId, string ClientSecret)
{
var stringBytes = Encoding.UTF8.GetBytes($"{ClientId}:{ClientSecret}");
var encodedBytes = Convert.ToBase64String(stringBytes);
HttpRequestMessage request = new(HttpMethod.Post, Url);
request.Headers.TryAddWithoutValidation("Accept", "application/json");
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {encodedBytes}");
var contentList = new List<string>();
contentList.Add("grant_type=authorization_code");
contentList.Add($"code={code}");
contentList.Add($"redirect_uri={RedirectUrl}");
request.Content = new StringContent(string.Join("&", contentList));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
using HttpClient client = new();
using HttpResponseMessage response = await client.SendAsync(request);
var body = response.Content.ReadAsStringAsync();
return body.Result;
}
I hate reviving old threads, but your answer helped me a lot. I had to change it a little bit to accept the refresh token rather than authorization code and thought I would post it here. I banged my head around for quite some time trying to figure this out without any useful documentation that I could find on the matter. I hope it helps someone in the same way that your code has helped me. Thanks!
public async Task<string> RefreshAccessToken(string Url, string RefreshToken, string ClientId, string ClientSecret)
{
var stringBytes = Encoding.UTF8.GetBytes($"{ClientID}:{ClientSecret}");
var encodedBytes = Convert.ToBase64String(stringBytes);
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, Url);
request.Headers.TryAddWithoutValidation("Accept", "application/json");
request.Headers.TryAddWithoutValidation("Authorization", $"Basic {encodedBytes}");
var contentList = new List<string>();
contentList.Add("grant_type=refresh_token");
contentList.Add($"refresh_token={RefreshToken}");
request.Content = new StringContent(string.Join("&", contentList));
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.SendAsync(request))
{
var body = response.Content.ReadAsStringAsync();
return body.Result;
}
}
}
Alternatively, I find that something like this works too. Using RestSharp..
public string RefreshAccessToken()
{
try
{
var stringBytes = Encoding.UTF8.GetBytes($"{strClientID}:{strClientSecret}");
var encodedBytes = Convert.ToBase64String(stringBytes);
var client = new RestClient("https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer");
client.UseJson();
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", $"Basic {encodedBytes}");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "refresh_token");
request.AddParameter("refresh_token", CurrentRefreshToken);
IRestResponse response = client.Execute(request);
return response.Content;
}
catch (Exception ex)
{
WriteError("RefreshAccessToken() - " + ex.Message);
return ex.Message;
}
}

C# eBay OAuth Compliance API Authentication Problems

After many struggles, I was finally able to get the OAuth Authentication/Refresh token process down. I am certain that the tokens I am using in this process are good. But I am struggling to communicate with the Compliance API and I think it may have more to do with my headers authentication process than it does specifically the Compliance API but I am not certain. I've tried so many different combinations of the below code unsuccessfully. I've tried to do the call as a GET and a POST (the call should be a GET). I've tried it with the access token encoded and not encoded. With all of my different code combinations tried I've been getting either an authorization error or a bad request error. You can see some of the various things I've tried from commented out code. Thank you for your help.
public static string Complaince_GetViolations(string clientId, string ruName, string clientSecret, string accessToken, ILog log)
{
var clientString = clientId + ":" + clientSecret;
//byte[] clientEncode = Encoding.UTF8.GetBytes(clientString);
//var credentials = "Basic " + System.Convert.ToBase64String(clientEncode);
byte[] clientEncode = Encoding.UTF8.GetBytes(accessToken);
var credentials = "Bearer " + System.Convert.ToBase64String(clientEncode);
var codeEncoded = System.Web.HttpUtility.UrlEncode(accessToken);
HttpWebRequest request = WebRequest.Create("https://api.ebay.com/sell/compliance/v1/listing_violation?compliance_type=PRODUCT_ADOPTION")
as HttpWebRequest;
request.Method = "GET";
// request.ContentType = "application/x-www-form-urlencoded";
//request.Headers.Add(HttpRequestHeader.Authorization, credentials);
//request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + codeEncoded);
request.Headers.Add(HttpRequestHeader.Authorization, credentials);
//request.Headers.Add("Authorization", "Bearer " + codeEncoded);
request.Headers.Add("X-EBAY-C-MARKETPLACE-ID", "EBAY-US");
log.Debug("starting request.GetRequestStream");
string result = "";
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream())) //FAILS HERE
{
result = streamReader.ReadToEnd();
}
//DO MORE STUFF BELOW
return "STUFF";
}
And I finally figured out a resolution to this problem. The HTML encoding of the entire bearer string was the issue. If anyone needs this in the future your welcome. =)
HttpWebRequest request = WebRequest.Create("https://api.ebay.com/sell/compliance/v1/listing_violation?compliance_type=PRODUCT_ADOPTION")
as HttpWebRequest;
request.Method = "GET";
request.Headers.Add(HttpRequestHeader.Authorization, System.Web.HttpUtility.HtmlEncode("Bearer " + accessToken));
request.Headers.Add("X-EBAY-C-MARKETPLACE-ID", "EBAY-US");
log.Debug("starting request.GetRequestStream");
string result = null;
var response = (HttpWebResponse)request.GetResponse();
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
result = streamReader.ReadToEnd();
}

Not getting access_token by calling https://login.microsoftonline.com/{tenant}/oauth2/token

I want to get user email from user id (object identifier) from web api, but getting blank response while calling api for token. I am running this code from my Web API. Please help. Below is the code.
Given full permission to APIs
Getting Blank response in below line.
var responseBytes = await webClient.UploadValuesTaskAsync(url, "POST", requestParameters);
Below is code
var tenant = "tenant ID";
var clientID = "app ID";
// I've tried graph.microsoft.com and graph.microsoft.com/.default
var resource = "https://graph.microsoft.com";
var secret = "client secret";
string token;
using (var webClient = new WebClient())
{
var requestParameters = new NameValueCollection();
requestParameters.Add("scope", resource);
requestParameters.Add("client_id", clientID);
requestParameters.Add("grant_type", "client_credentials");
requestParameters.Add("client_secret", secret);
var url = "https://login.microsoftonline.com/{tenant}/oauth2/token";
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
var responseBytes = await webClient.UploadValuesTaskAsync(url, "POST", requestParameters);
var responseBody = Encoding.UTF8.GetString(responseBytes);
var jsonObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(responseBody);
token = jsonObject.Value<string>("access_token");
}
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
var response = await client.GetAsync(new Uri("https://graph.microsoft.com/v1.0/user/" + ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")));
Your error is here:
requestParameters.Add("scope", resource);
It needs to be resource rather than scope:
requestParameters.Add("resource", resource);
Can you help me understand what documentation or tutorial you followed to make this mistake? I have seen it happen before and I am trying to understand the patterns here.
The documentation and authentication flow you should be following is here.

HTTP Request with Basic Auth always returns 401

I'm trying to do a GET in an UWP (Windows 10) app. I've tried several ways but all always return 401.
In Postman it works fine, but I can' seem to get it to work in my app. What am I missing.
These are the methods I tried (all return 401):
Method 1:
var request = WebRequest.Create("http://api.fos.be/person/login.json?login=200100593&password=pass");
request.Headers["Authorization"] = "Basic MYAUTHTOKEN";
var response = await request.GetResponseAsync();
Method 2:
const string uri = "http://api.fos.be/person/login.json?login=200100593&password=pass";
var httpClientHandler = new HttpClientHandler();
httpClientHandler.Credentials = new System.Net.NetworkCredential("MYUSERNAME", "MYPASSWORD");
using (var client = new HttpClient(httpClientHandler))
{
var result = await client.GetAsync(uri);
Debug.WriteLine(result.Content);
}
Method 3:
var client = new RestClient("http://api.fos.be/person/login.json?login=200100593&password=pass");
var request = new RestRequest(Method.GET);
request.AddHeader("postman-token", "e2f84b21-05ed-2700-799e-295f5470c918");
request.AddHeader("cache-control", "no-cache");
request.AddHeader("authorization", "Basic MYAUTHTOKEN");
IRestResponse response = await client.Execute(request);
Debug.WriteLine(response.Content);
The third method is code generated straight from Postman, so why is it working there and not in my app?
This thread helped me figure out the solution. I was using http:// but I had to make it https://. HTTPS with the code in that thread was the solution.
This is my final code:
public static async void GetPerson()
{
//System.Diagnostics.Debug.WriteLine("NetworkConnectivityLevel.InternetAccess: " + NetworkConnectivityLevel.InternetAccess);
//use this, for checking the network connectivity
System.Diagnostics.Debug.WriteLine("GetIsNetworkAvailable: " + System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable());
//var msg = new Windows.UI.Popups.MessageDialog("GetIsNetworkAvailable: " + System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable());
//msg.ShowAsync();
HttpClient httpClient = new HttpClient();
// Assign the authentication headers
httpClient.DefaultRequestHeaders.Authorization = CreateBasicHeader("MYUSERNAME", "MYPASS");
System.Diagnostics.Debug.WriteLine("httpClient.DefaultRequestHeaders.Authorization: " + httpClient.DefaultRequestHeaders.Authorization);
// Call out to the site
HttpResponseMessage response = await httpClient.GetAsync("https://api.fos.be/person/login.json?login=usern&password=pass");
System.Diagnostics.Debug.WriteLine("response: " + response);
string responseAsString = await response.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine("response string:" + responseAsString);
}
public static AuthenticationHeaderValue CreateBasicHeader(string username, string password)
{
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(username + ":" + password);
String logindata = (username + ":" + password);
System.Diagnostics.Debug.WriteLine("AuthenticationHeaderValue: " + new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)));
return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
}
I would try this first:
Check your "MYAUTHTOKEN", it is usually a combo of username:password and is base 64 encoded. So if your username was "user" and password was "pass" you would need to base64 encode "user:pass"
var request = WebRequest.Create("https://api.fos.be/person/login.json");
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Text.Encoding.UTF8.GetBytes("user:pass"));
var response = await request.GetResponseAsync();

RestSharp - Authorization Header not coming across to WCF REST service

I am trying to call a locally hosted WCF REST service over HTTPS with basic auth.
This works and the Authorization header comes thru just fine and all is happy:
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertficate;
var request = (HttpWebRequest)WebRequest.Create("https://localhost/MyService/MyService.svc/");
request.Method = "GET";
request.ContentType = "application/json";
request.Headers.Add(
System.Net.HttpRequestHeader.Authorization,
"Basic " + this.EncodeBasicAuthenticationCredentials("UserA", "123"));
WebResponse webResponse = request.GetResponse();
using (Stream webStream = webResponse.GetResponseStream())
{
if (webStream != null)
{
using (StreamReader responseReader = new StreamReader(webStream))
{
string response = responseReader.ReadToEnd();
}
}
}
When I try to use RestSharp however, the Authorization header never comes thru on the request:
ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertficate;
var credentials = this.EncodeBasicAuthenticationCredentials("UserA", "123");
var client = new RestSharp.RestClient("https://localhost/MyService/MyService.svc/");
var restRq = new RestSharp.RestRequest("/");
restRq.Method = Method.GET;
restRq.RootElement = "/";
restRq.AddHeader("Authorization", "Basic " + credentials);
var restRs = client.Execute(restRq);
What am i doing wrong with the RestSharp method?
I know that the AddHeader method works because this:
restRq.AddHeader("Rum", "And Coke");
will come thru, only "Authorization" seems stripped out/missing.
instead of adding the header 'manually' do the following:
var client = new RestSharp.RestClient("https://localhost/MyService/MyService.svc/");
client.Authenticator = new HttpBasicAuthenticator("UserA", "123");
I used milano's answer to get my REST service call to work (using GET)
Dim client2 As RestClient = New RestClient("https://api.clever.com")
Dim request2 As RestRequest = New RestRequest("me", Method.GET)
request2.AddParameter("Authorization", "Bearer " & j.access_token, ParameterType.HttpHeader)
Dim response2 As IRestResponse = client2.Execute(request2)
Response.Write("** " & response2.StatusCode & "|" & response2.Content & " **")
The key was making sure there was a space after the word 'Bearer' but this may apply to any type of custom token authorization header
You have to use ParameterType.HttpHeader parameter:
request.AddParameter("Authorization", "data", ParameterType.HttpHeader);
I was able to get the response from my rest API using this piece of code:
My API was returning server error and I used:
request.AddHeader("Authorization", $"Bearer {accessToken}");
var request = new RestRequest("/antiforgerytokensso", Method.Get);
restClient.Authenticator = new JwtAuthenticator(accessToken);
var response = await restClient.ExecuteAsync(request);
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));

Categories

Resources