HTTPClient Post Request and get User Token - c#

I have created a function which takes the username, password and the endpoint (url) and returns the token.
Here is the function:
public string GetToken(KiaaaAuthClient authClient)
{
Debug.Log("GetToken function executed");
// HttpClient object
HttpClient client = new HttpClient();
Debug.Log("62");
// Creating values for the request
var values = new Dictionary<string, string>
{
{"username", authClient.userName},
{"password", authClient.password},
};
Debug.Log("70");
// Encoding request in Http form
var data = new FormUrlEncodedContent(values);
Debug.Log("74");
// Response message
HttpResponseMessage responseMessage = client.PostAsync(authClient.endPoint, data).Result;
Debug.Log("78");
// Json string content
var jsonContent = responseMessage.Content.ReadAsStringAsync().Result;
Debug.Log("82");
// Getting a dictrionary from the JSON string
var jsonDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonContent);
Debug.Log("86");
// if 'error' is not present in jr (dictionary)
if (!jsonDict.ContainsKey("error"))
{
authClient.token = jsonDict["access_token"];
return authClient.token;
}
else
{
Debug.Log("Error: failed to acquire token");
return null;
}
It gave the webexception error (name resolution failure). Can anyone give me the reason for this? Moreover, I am very new to this, I am not sure whether it is a correct way to post a request and get the user authentication token. Please guide!

Related

Get access token back from Onelogin using Authorization Code Flow with PKCe in step 2

I'm Trying to get the access token form OneLogin using the Authorization Code with PKCE. I'm able to go through step1 for PKCe and getting the authorization code back from OneLogin. But when i try to get the token using the authorization code sent by one login i keep getting 400 bad request error. I'm not sure what is wrong. I followed the info provided by oneLogin website to all required parameters in the request for Step 2. below the code i'm using. I will appreciate if some one can help on this
public async Task GetAccessToken(string redirecturl, string authCode) { HttpClientHandler clientHandler = new HttpClientHandler(); clientHandler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; };
var client = new HttpClient(clientHandler);
var body = JsonConvert.SerializeObject(new
{
grant_type = "authorization_code",
code = authCode, //The code returned from OneLogin in step 1
client_id="XXXXXXXXXXXXXXXXXX386d707215718",
redirect_uri=redirecturl,//The redirect URL registered in onelogin account
code_verifier=GetCacheEntry(CodeKey)// The code verifier used in step one
});
var req = new HttpRequestMessage
{
Method = HttpMethod.Post,
RequestUri = new Uri("https://MySubdomain.onelogin.com/oidc/2/token"),
Content = new StringContent(body)
};
req.Content.Headers.ContentType= new MediaTypeHeaderValue(#"application/x-www-form-urlencoded");
var response = await client.SendAsync(req);
if (response.StatusCode == HttpStatusCode.OK)
{
var responseBody =await response.Content.ReadAsStringAsync();
var json = JsonConvert.DeserializeObject<OAuthTokenResponse>(responseBody);
memoryCache.Remove(CodeKey);
return Ok(json);
}
return BadRequest(response);
}

Xero: Unable to exchanging the code for the access token once a user has authorised my app

I really been struggling with exchanging the code received from Xero after a user from another Xero organisation has authorised my app.
Whatever I tried I consistently receive a 400 - Bad Request, For obvious security reasons "Bad Request" is all the information in the response.
I have tried using StringContent. Setting the accept headers of the HttpClient. Using httpClient.PostAsync().
Here's the what the request headers and body need to contain:
POST https://identity.xero.com/connect/token
authorization: "Basic " + base64encode(client_id + ":" + client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=xxxxxx
&redirect_uri=https://myapp.com/redirect
where xxxxx is the code returned to the callback method.
Below is the the method in my service which handles the App authorisation callback. I'd be super appreciative if someone could point out what I'm not doing right.
public async Task<string> AuthoriseApp(string code, string state)
{
try
{
var clientState = TokenUtilities.GetCurrentState();
if (state != clientState)
{
return "Cross site forgery attack detected!";
}
var paramss = new Dictionary<string, string>
{
{ "grant_type", "authorization_code" },
{ "code", code },
{ "redirect_uri", xeroConfig.CallbackUri.AbsoluteUri }
};
var body = new FormUrlEncodedContent(paramss);
var httpClient = new HttpClient();
using var requestMessage = new HttpRequestMessage(HttpMethod.Post, xeroConfig.XeroIdentityBaseUri + "/connect/token")
{
Content = body
};
requestMessage.Headers.Authorization = new BasicAuthenticationHeaderValue(xeroConfig.ClientId, xeroConfig.ClientSecret);
var response = await httpClient.SendAsync(requestMessage);
return "Success"; // This will change when I actually receive a 200 and the access token
}
catch (Exception ex)
{
logger.LogError(ex.Message);
return ex.Message;
}
}
Thanks in advance
Jon

Simple HttpRequestMessage but not working

I'm writing a simple dotnet core API, under search controller which like below :
[HttpGet("order")]
public async Task <Order> SearchOrder(string ordername, int siteid) {
return await service.getorder(ordername,siteid)
}
The swagger UI where the path https://devehost/search/order test pretty work, but when I use another client to call this api by below
client = new HttpClient {
BaseAddress = new Uri("https://devehost")
};
var request = new HttpRequestMessage(HttpMethod.Get, "Search/order") {
Content = new FormUrlEncodedContent(
new List<KeyValuePair<string, string>> {
new("ordername", "pizza-1"),
new("siteid", "1"),
})
};
var response = await client.SendAsync(request);
The status code always return bad request. But the postman is work, can I know the problem inside?
Thank you
For a GET request, the parameters should be sent in the querystring, not the request body.
GET - HTTP | MDN
Note: Sending body/payload in a GET request may cause some existing implementations to reject the request — while not prohibited by the specification, the semantics are undefined.
For .NET Core, you can use the Microsoft.AspNetCore.WebUtilities.QueryHelpers class to append the parameters to the URL:
Dictionary<string, string> parameters = new()
{
["ordername"] = "pizza-1",
["siteid"] = "1",
};
string url = QueryHelpers.AppendQueryString("Search/order", parameters);
using var request = new HttpRequestMessage(HttpMethod.Get, url);
using var response = await client.SendAsync(request);

Rewriting a Java HttpURLConnection method using C# HttpClient

I've got a working Java method that uses java.net.HttpURLConnection that I should re-implement in C# using the .NET HttpClient.
Java method:
public static String getMyThingAPIToken() throws IOException{
URL apiURL = new URL("https://myThingAPI/token");
HttpURLConnection apiConnection = (HttpURLConnection) apiURL.openConnection();
apiConnection.setRequestMethod("POST");
apiConnection.setDoOutput(true);
String apiBodyString = "myThingAPI login id and secret key";
byte[] apiBody = apiBodyString.getBytes(StandardCharsets.UTF_8);
OutputStream apiBodyStream = apiConnection.getOutputStream();
apiBodyStream.write(apiBody);
StringBuffer apiResponseBuffer;
try (BufferedReader in = new BufferedReader(new InputStreamReader(apiConnection.getInputStream()))){
String inputline;
apiResponseBuffer = new StringBuffer();
while((inputline = in.readLine()) != null) {
apiResponseBuffer.append(inputline);
}
}
}
So far, my C# looks like below, and you'll notice that this early form of my implementation does not interpret the response. Nor does it have a string return type required for the token string.
This is because when I test it, the response has:
StatusCode: 400
ReasonPhrase: 'Bad Request'
So something in my apiBody byte array or use of PostAsync must be different to what the Java method does, but I cannot work out what it could be.
public async static Task<HttpResponseMessage> getMyThingAPIToken(HttpClient client)
{
var apiURI = new Uri("https://myThingAPI/token");
string apiBodystring = "myThingAPI login id and secret key";
byte[] apiBody = System.Text.Encoding.UTF8.GetBytes(apiBodystring);
var response = await client.PostAsync(apiURI, new ByteArrayContent(apiBody));
return response;
}
The Java code doesn't specify a type which means that by default the request uses application/x-www-form-urlencoded. This is used for FORM POST requests.
The default content type for ByteArrayContent on the other hand is application/octet-stream while for StringContent it's text/plain.
FORM content is used through the FormUrlEncoodedContent class which can accept any Dictionary<string,string> as payload.
The input in the question is not in a x-www-form-urlencoded form so either it's not the real content or the API is misusing content types.
Assuming the API accepts proper x-www-form-urlencoded content, the following should work:
var data=new Dictionary<string,string>{
["login"]=....,
["secret"]=.....,
["someOtherField"]=....
};
var content= new FormUrlEncodedContent(data);
var response=await client.PostAsync(apiURI,content);
To send any text using application/x-www-form-urlencoded, we need to specify the content type in StringContent's constructor:
var contentType="application/x-www-form-urlencoded";
var content= new StringContent(apiBodyString, Encoding.UTF8,contentType);
var response=await client.PostAsync(apiURI,content);
Can you try using following code:
client.BaseAddress = new Uri("https://myThingAPI/");
var message = new HttpRequestMessage(HttpMethod.Post, "/token");
// Add your login id and secret key here with the format you want to send
message.Content = new StringContent(string.Format("userName={0}&password={1}", UserName, Password));
var result = await client.SendAsync(message);
return result;

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
}
}

Categories