Unauthorized HTTP request .NET - c#

I'm trying to make HTTP request with Bearer authorization. I have a token, token is valid. Tried to do it 3 different ways: App, that request must be implemented in, POSTMAN, console app with a code generated with POSTMAN (C# - RestSharp) from the same POSTMAN call:
App POST method:
public async Task<TResponse> Post<TRequest, TResponse>(string requestUri, TRequest data)
{
LogInit(requestUri, HttpMethod.Post, data);
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
{
var token = await GetToken(_httpClient);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
request.Content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");
using (var response = await _httpClient.SendAsync(request))
{
if (!response.IsSuccessStatusCode)
{
throw await HandleErrorResponse(response);
}
var responseObj = await response.Content.ReadAsJsonAsync<TResponse>();
return responseObj;
}
}
}
Console POST method:
static void Main(string[] args)
{
var client = new RestClient("http://***");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer xxx");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Cookie", "ARRAffinity=xxx");
var body = #"{
" + "\n" +
#" ""amisPersonId"": ***,
" + "\n" +
#" ""name"": ""***"",
" + "\n" +
#" ""surname"": ""***"",
" + "\n" +
#" ""personalCode"": ""***"",
" + "\n" +
#" ""email"": ""***"",
" + "\n" +
#" ""phoneNumber"": ""***""
" + "\n" +
#"}";
request.AddParameter("application/json", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
}
Requests tracked with debugger:
App request
Console app request
POSTMAN request
POSTMAN gets 200/400 reponses, App and Console app gets 401 (Unauthorized). BOTH Apps are .NET CORE apps.

assuming that you have correct token.AccessToken ,try to replace
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
with
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);

Related

Error Creating Folder in Sharepoint using REST API C#

I can accomplish all other tasks with the rest API, like uploading and downloading files, navigating through the file directory. I just keep getting either 400 Bad Request or sometimes with some tries I'll get 500 Internal Server Error. Also, I can create the request on postman and its successful
this is what the request should look like the rest is me creating it in c#
POST https://{site_url}/_api/web/folders
Authorization: "Bearer " + accessToken
Accept: "application/json;odata=verbose"
Content-Type: "application/json"
Content-Length: {length of request body as integer}
X-RequestDigest: "{form_digest_value}"
{
"__metadata": {
"type": "SP.Folder"
},
"ServerRelativeUrl": "/document library relative url/folder name"
}
private async Task PostFolderSharePoint(string url, string serverRelativeUrl)
{
string accessToken = GetAccessToken().GetAwaiter().GetResult();
string jsoncontent = JsonConvert.SerializeObject("{\"__metadata\": {\"type\": \"SP.Folder\"},\"ServerRelativeUrl\": serverRelativeUrl}");
var content = new StringContent(jsoncontent, Encoding.UTF8, "application/json");
var FormDiGestValue = await GetFormDigestValue(accessToken);
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var requestMessage = new HttpRequestMessage(HttpMethod.Post,url) { Content = content };
requestMessage.Headers.Add("X-RequestDigest", FormDiGestValue);
HttpResponseMessage response = await _httpClient.SendAsync(requestMessage).ConfigureAwait(false);
return response;
}
This is how I create a folder with the Sharepoint REST API:
public async Task<string> CreateFolder(string folderName, string relativeUrl)
{
try
{
var url = "https://your.sharepoint.com/sites/devsite/_api/web/folders";
var json = "{\"ServerRelativeUrl\": \"" + relativeUrl + "/" + folderName + "\"}";
var payload = new StringContent(json, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("accept", "application/json;odata=verbose");
client.DefaultRequestHeaders.Add("X-User-Agent", "spoc");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var response = await client.PostAsync(url, payload);
return await response.Content.ReadAsStringAsync();
}
catch (WebException we)
{
throw new SomethingException(we);
}
}
and to use it:
var modFolder = await spocRest.CreateFolder("MOD1", "Shared Documents");

Deserializing JSON using RESTSHARP

I have called an API request and serialized the response using RESTSHARP.
However, when im deserializing it's throwing the error
Error MSG Data at the root level is invalid. Line 1, position 1.
I know that the correct value has been serialized because in my console.WriteLine section it displays the auth token that i need to pull out.
Here is my code:
static void Main(string[] args)
{
var URL = "****/login/";
IRestClient restClient = new RestClient();
IRestRequest restRequest = new RestRequest(URL);
restRequest.AddHeader("Content-Type", "application/json");
restRequest.AddParameter("application/json", "{\r\n \"UserName\": \"****\",\r\n \"Password\": \"*****\"\r\n}", ParameterType.RequestBody);
IRestResponse restResponse = restClient.Post(restRequest);
if (restResponse.IsSuccessful)
{
Console.WriteLine("Status Code " + restResponse.StatusCode);
Console.WriteLine("Response Content " + restResponse.Content);
JsonDeserialize();
}
}
public static void JsonDeserialize()
{
var URL = "****/login/";
IRestClient restClient = new RestClient();
IRestRequest restRequest = new RestRequest(URL);
restRequest.AddHeader("Content-Type", "application/json");
restRequest.AddParameter("application/json", "{\r\n \"UserName\": \"****\",\r\n \"Password\": \"****\"\r\n}", ParameterType.RequestBody);
IRestResponse<List<MySuilvisionAuth>> restResponse = restClient.Post<List<MySuilvisionAuth>>(restRequest);
if (restResponse.IsSuccessful)
{
Console.WriteLine("Status Code " + restResponse.StatusCode);
Console.WriteLine("Response Content " + restResponse.Data.Count);
}
else
{
Console.WriteLine("Error Msg " + restResponse.ErrorMessage);
Console.WriteLine("Stack Trace " + restResponse.ErrorException);
}

Sending a JSON request to ebay API

Ok so I'm having a bit of trouble getting these JSON requests through to the Ebay API.
Here is the json request:
string jsonInventoryRequest = "{" +
"\"requests\": [";
int commaCount = 1;
foreach (var ep in productsToProcess)
{
jsonInventoryRequest += "{\"offers\": [{" +
"\"availableQuantity\":" + ep.EbayProductStockQuantity + "," +
"\"offerId\":\"" + ep.EbayID.ToString() + "\"," +
"\"price\": {" +
"\"currency\": \"AUD\"," +
"\"value\":\"" + ep.EbayProductPrice.ToString() + "\"" +
"}" +
"}],";
jsonInventoryRequest += "\"shipToLocationAvailability\": " + "{" +
"\"quantity\":" + ep.EbayProductStockQuantity +
"},";
jsonInventoryRequest += "\"sku\": " + ep.EbayProductSKU.ToString() + "}";
if (commaCount < productsToProcess.Count())
jsonInventoryRequest += ",";
commaCount++;
sendEbayApiRequest = true;
}
jsonInventoryRequest +=
"]" +
"}";
And the Debug.WriteLine() output of the above JSON request is :
json string = {"requests": [{"offers": [{"availableQuantity":0,"offerId":"098772298312","price": {"currency": "AUD","value":"148.39"}}],"shipToLocationAvailability": {"quantity":0},"sku": 135779},{"offers": [{"availableQuantity":1,"offerId":"044211823133","price": {"currency": "AUD","value":"148.39"}}],"shipToLocationAvailability": {"quantity":1},"sku": 133607}]}
Here is the code in C# to send the request:
var ebayAppIdSetting = _settingService.GetSettingByKey(
"ebaysetting.appid", "");
var ebayCertIdSetting = _settingService.GetSettingByKey(
"ebaysetting.certid", "");
var ebayRuNameSetting = _settingService.GetSettingByKey(
"ebaysetting.appid", "");
var stringToEncode = ebayAppIdSetting + ":" + ebayCertIdSetting;
HttpClient client = new HttpClient();
byte[] bytes = Encoding.UTF8.GetBytes(stringToEncode);
var base64string = "Basic " + System.Convert.ToBase64String(bytes);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", base64string);
var stringContent = "?grant_type=client_credentials&" + "redirect_uri=" + ebayRuNameSetting + "&scope=https://api.sandbox.ebay.com/oauth/api_scope";
var requestBody = new StringContent(stringContent.ToString(), Encoding.UTF8, "application/json");
requestBody.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
var response = client.PostAsync("https://api.sandbox.ebay.com/identity/v1/oauth2/token", requestBody);
The output I get when I do Debug.WriteLine("response.Content = " + response.Result); is:
response.Content = StatusCode: 401, ReasonPhrase: 'Unauthorized',
Version: 1.1, Content: System.Net.Http.StreamContent, Headers: {
RlogId:
t6ldssk%28ciudbq%60anng%7Fu2h%3F%3Cwk%7Difvqn*14%3F0513%29pqtfwpu%29pdhcaj%7E%29fgg%7E%606%28dlh-1613f3af633-0xbd
X-EBAY-C-REQUEST-ID: ri=HNOZE3cmCr94,rci=6kMHBw5dW0vMDp8A
X-EBAY-C-VERSION: 1.0.0 X-EBAY-REQUEST-ID:
1613f3af62e.a096c6b.25e7e.ffa2b377!/identity/v1/oauth2/!10.9.108.107!r1esbngcos[]!token.unknown_grant!10.9.107.168!r1oauth-envadvcdhidzs5k[]
Connection: keep-alive Date: Mon, 29 Jan 2018 00:04:44 GMT
Set-Cookie: ebay=%5Esbf%3D%23%5E;Domain=.ebay.com;Path=/
WWW-Authenticate: Basic Content-Length: 77 Content-Type:
application/json }
Can anyone see where I'm going wrong. Cheers
Ok so the authentication was failing because I was sending wrong authentication token. Needed to get oauth token from application tokens.
So instead of base64 encoding token like this:
var base64string = "Basic " + System.Convert.ToBase64String(bytes);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", base64string);
I needed to do the following:
url = "https://api.sandbox.ebay.com/sell/inventory/v1/bulk_update_price_quantity";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
//request.ContentType = "application/json; charset=utf-8";
request.Headers.Add("Authorization", "Bearer **OAUTH TOKEN GOES HERE WITHOUT ASTERIKS**");
// Send the request
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write(jsonInventoryRequest);
streamWriter.Flush();
streamWriter.Close();
}
// Get the response
HttpWebResponse response = (HttpWebResponse) request.GetResponse();
if (response != null)
{
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
// Parse the JSON response
var result = streamReader.ReadToEnd();
}
}

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();

C# Twitter request OAuth Token

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();
}

Categories

Resources