I'm having an issue creating a POST request from C# to generate a token. There's nothing wrong with the service because I can consume it using Postman.
Can someone help my out.
Following my coding. Every time I get a 403 error.
public async Task<string> LoginAsync(string userName, string password)
{
try
{
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "client_credentials")
};
var request = new HttpRequestMessage(HttpMethod.Post, login_url);
request.Content = new FormUrlEncodedContent(keyValues);
var client = new HttpClient();
var authenticationBytes = System.Text.Encoding.ASCII.GetBytes("----------username-------- : ----------pwd----------");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(authenticationBytes));
//request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(authenticationBytes));
var response = await client.SendAsync(request);
var jwtResponse = await response.Content.ReadAsStringAsync(); // contains access token
JObject jwtDynamic = JsonConvert.DeserializeObject<dynamic>(jwtResponse);
accessToken = jwtDynamic.Value<string>("access_token");
Debug.WriteLine(jwtResponse);
}
catch (Exception e)
{
Console.WriteLine(e);
}
return accessToken;
}
Following are the screenshots of Postman.
Thanks a lot.
you can use generating code from postman using RestSharp Library for .Net as you can see by clicking on code button below in the picture .
best regards
Related
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;
}
}
How do I pass request content in the HttpClient.GetAsync method? I need to fetch data depending upon request content.
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch()
{
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch");
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
If you are using .NET Core, the standard HttpClient can do this out-of-the-box. For example, to send a GET request with a JSON body:
HttpClient client = ...
...
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("some url"),
Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
If you want to send content, then you need to send it as query string (According to your API route)
HttpResponseMessage response =await client.GetAsync("http://localhost:8080/document/quicksearch/paramname=<dynamicName>¶mValue=<dynamicValue>");
And in API check for "paramName" and "paramValue"
this works for me:
using (var httpClient = new HttpClient())
{
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("your url"),
Content = new StringContent("your json", Encoding.UTF8, ContentType.Json),
};
using (var response = await httpClient.SendAsync(request))
{
string apiResponse = await response.Content.ReadAsStringAsync();
}
}
EDITED:
This is minor different then #SonaliJain answer above:
MediaTypeNames.Application.Json instead of ContentType.Json
I'm assuming that your "request content" would be POST data, no?
If you're sending it using the standard form content way of doing it, you would first have to build the content:
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "theperplexedone"),
new KeyValuePair<string, string>("password", "mypassword123"),
});
And then submit it using PostAsync instead:
var response = await client.PostAsync("http://localhost:8080/document/quicksearch", content);
Hi all thank you for your comments, i got the solution
[HttpGet]
public async Task<HttpResponseMessage> QuickSearch(HttpRequestMessage Query)
{
Debugger.Launch();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
Console.WriteLine(Query);
HttpResponseMessage response = await client.GetAsync("http://localhost:8080/document/quicksearch/"+ Query.RequestUri.Query);
if (response.IsSuccessStatusCode)
{
Console.Write("Success");
}
else
{
Console.Write("Failure");
}
return response;
}
}
catch (Exception e)
{
throw e;
}
I have a bot running on http://localhost:3978/api/messages.
Instead of debugging it using an emulator, can I go about using a http post request to the messaging endpoint of the bot?
If so, how do I go about doing it?
I am using c# microsoft bot framework, and I am new to this application.
I do not want to use any channels or DirectLine api, just using Httpclient.
You can do this with C# using code similar to below. Note that you would have to construct an Activity to send by setting the appropriate properties for your needs, which is not included in this code.
//make a call to get an auth token
string token;
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["grant_type"] = "client_credentials";
values["client_id"] = "YOUR APP ID";
values["client_secret"] = "NcOXRwb51joibEfzUuNE04u";
values["scope"] = "YOUR APP ID/.default";
var response =
client.UploadValues("https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token", values);
var responseString = Encoding.Default.GetString(response);
var result = JsonConvert.DeserializeObject<ResponseObject>(responseString);
token = result.access_token;
}
//you will need to adjust this value for your project.
//this example for a proxy project so the service url here is
//just an arbitrary endpoint I was using to send activities to
activity.ServiceUrl = "http://localhost:4643/api/return";
var jsonActivityAltered = JsonConvert.SerializeObject(activity);
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", $"Bearer {token}");
try
{
var btmResponse = client.UploadString("http://localhost:3971/api/messages", jsonActivityAltered);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
Have you tried using something like postman? (it's free and easy to use)
https://www.getpostman.com/
You can also write scripts in postman
otherwise you can just go to the endpoint of your API in the browser
http://localhost:3978/api/
I see you mentioned you wanted to make a console application.
You could do that. I'd suggest using postman though.
Here is an example of sending a file as well as some querystring data and Authentication using a Bearer token.
Sorry it may not be exact. Had to do a bit of copy pasting/deleting from some code examples if have
using (HttpClient client = new HttpClient())
{
JObject jsonModel = new JObject();
client.BaseAddress = new Uri("http://localhost:3978/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
using (var multipartFormDataContent = new MultipartFormDataContent())
{
var values = new[]
{
new KeyValuePair<string, string>("firstname", lastname),
new KeyValuePair<string, string>("lastname", lastname),
new KeyValuePair<string, string>("payloadFile", FileName)
};
foreach (var keyValuePair in values)
{
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
String.Format("\"{0}\"", keyValuePair.Key));
}
ByteArrayContent fileContent = new ByteArrayContent(File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
string FullxmlString = File.ReadAllText(Path.Combine(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("payloadFile") { FileName = "payloadFile" };
multipartFormDataContent.Add(fileContent);
HttpResponseMessage response = client.PostAsync("api/message", multipartFormDataContent).Result;
string returnString = response.Content.ToString();
using (HttpContent content = response.Content)
{
string res = "";
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}
}
}
I want connect to jira server using C# Rest api
https://jira.myserver.co.kr/rest/auth/1/session
enter code here
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ContentType = "application/json";
request.Method = method;
... more
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
the remote server returned an error (404)
I tried different work arounds but all went in vain. May I know why this error is coming? What could be the resolution of this error?
You can search for a reason of this error in different ways:
by looking at logs of JIRA server, there might be some messages/stacktraces there (for example, atlasian-jira.log);
by using some tool to perform/debug/test REST calls (for example, postman), and when it's start working in tool you can write code to do it programmatically. JIRA can return description of error in the response, and tool can show it to you.
When you get this information it can give you exact reason why it is not working. Once I got 403 error and it was because threshold of unsuccessful login attempts was exceeded, I logged into JIRA server using web browser (and entered captcha), and after that I was able to obtain session through application code.
I can successfully obtain session from JIRA in the following way using postman:
Request type: POST
URL: https://myjiraserver.com/rest/auth/1/session
Body: {"username":"myusername","password":"mypassword"}
Headers: Content-Type:application/json
you can do something like this:
namespace YOUR_NAME_SPACE
{
public class jira
{
public static string createTicket(string url, string data)
{
try
{
var client = new System.Net.Http.HttpClient();
string base64Credentials = GetEncodedCredentials();
var header = new AuthenticationHeaderValue("Basic", base64Credentials);
client.DefaultRequestHeaders.Authorization = header;
var content = new StringContent(data, Encoding.UTF8, "application/json");
var result = client.PostAsync(url, content).Result;
var response = result.Content.ReadAsStringAsync().Result;
// You can call putIssue if you want
return response;
}
catch (System.Net.WebException ex)
{
Console.WriteLine("Exception Occurred" + " : {0}", ex.Message);
throw;
}
}
private static string GetEncodedCredentials()
{
string mergedCredentials = string.Format("{0}:{1}", "LOGIN", "PASSWD");
byte[] byteCredentials = UTF8Encoding.UTF8.GetBytes(mergedCredentials);
return Convert.ToBase64String(byteCredentials);
}
public static string jiraSerialise(string project, string summary, string description, string issutype, string author)
{
JObject valuesToJson =
new JObject(
new JProperty("fields",
new JObject(
new JProperty("project",
new JObject(new JProperty("key", project))),
new JProperty("summary", summary),
new JProperty("description", description),
new JProperty("issuetype",
new JObject(new JProperty("name", issutype))),
new JProperty("assignee",
new JObject(new JProperty("name", author))))));
return valuesToJson.ToString();
}
public static string putSerialize(string key, string value)
{
JObject valueToJson =
new JObject(
new JProperty(key, value));
return valueToJson.ToString();
}
public static string putIssue(string response, string author, System.Net.Http.HttpClient client)
{
JObject jsonResponse = JObject.Parse(response);
Dictionary<string, string> dictResponse = jsonResponse.ToObject<Dictionary<string, string>>();
string issueUrl = dictResponse.Last().Value;
string issueAssignee = issueUrl + "/assignee";
var authorContent = new StringContent(author, Encoding.UTF8, "application/json");
var authorResult = client.PutAsync(issueAssignee, authorContent).Result;
var authorResponse = authorResult.Content.ReadAsStringAsync().Result;
Console.WriteLine(authorResponse);
return authorResponse;
}
}
}
And now you can call this class like that:
string data = jira.jiraSerialise("lala", "nameVulnerabilty", "descriptionField", "Bug", "author");
string url = "http://YOUR_URL/rest/api/2/issue/";
Console.WriteLine(jira.createTicket(url, data));
Hope it helps :)
I am trying to figure out what I can do (logging, things to check) before having to read server logs as I don't want to miss something stupid before requesting that.
Here is my code:
const string URL = "https://SomeURL/api/security/";
string urlParameters = string.Format("grant_type=password&username={0}&password={1}", username, password);
StringContent content = new StringContent(urlParameters, Encoding.UTF8, "application/x-www-form-urlencoded");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(URL);
StringContent content = new StringContent(urlParameters, Encoding.UTF8, "application/x-www-form-urlencoded");
var tokenResponse = client.PostAsync("token", content).Result;
I am a little newer to this so I'm not sure what to check next but have tried the same request using postman and get a response with my token so it looks like I am missing something or maybe formatting something incorrectly?
I was following an online course, and the code for setting the URL parameters were set like this:
public async Task<AuthenticatedUser> Authenticate(string userName, string password)
{
var data = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username ", "userName"),
new KeyValuePair<string, string>("password", "password")
});
using (HttpResponseMessage response = await apiClient.PostAsync("/Token", data))
{
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsAsync<AuthenticatedUser>();
return result;
}
else
{
throw new Exception(response.ReasonPhrase);
}
}
}
When testing, found that 500 error was being returned for the PostAsync call. I checked my URL address and parameters and they all looked correct. If I tested in Swagger, then I received a 200 status and token was shown.
Following the link by Thomas Levesque I changed how the data variables were set to :
var data = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "password",
["username"] = username,
["password"] = password
});
Now the response status is 200 and the AuthenticatedUser model is populated correctly. However I couldn't understand why Dictionary seem to work and KeyValuePair didn't. So I created the list and then encoded it:
var dataList = new[]
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", username),
new KeyValuePair<string, string>("password", password)
};
var content = new FormUrlEncodedContent(dataList);
using (HttpResponseMessage response = await apiClient.PostAsync(requestUrl, content))
This also worked. I freely admit that I do not fully understand why.....yet.
I did not URL encode my parameters, here's the fix (probably a better way of doing it).
string urlParameters = string.Format("grant_type=password&username={0}&password={1}", Uri.EscapeDataString(username), Uri.EscapeDataString(password));