Code in Node.Js
var url = 'https://accounts.google.com/o/oauth2/token';
var params = {
client_id: req.body.clientId,
redirect_uri: req.body.redirectUri,
code: req.body.code,
grant_type: 'authorization_code',
client_secret: config.GOOGLE_SECRET
};
console.log(req.body.code);
request.post(url, {
json: true,
form: params
}, function (err, response, token) {
var accessToken = token.access_token;
)};
Code in Web Api
var clientd = new ClientD()
{
client_id = client_id,
redirect_uri = redirect_uri,
client_secret = client_secret,
code = code,
grant_type = grant_type
};
String url = "https://accounts.google.com/o/oauth2/token";
using (var client = new System.Net.Http.HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add
(new MediaTypeWithQualityHeaderValue("application/json"));
var json = Newtonsoft.Json.JsonConvert.SerializeObject(clientd);
HttpContent content = new StringContent(json);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpResponseMessage = await client.PostAsync(url, content);
if (httpResponseMessage.StatusCode == HttpStatusCode.OK)
{
return httpResponseMessage.StatusCode.ToString();
}
else
{
return httpResponseMessage.StatusCode.ToString();
}
}
I have a code for google authentication in node.js which is working fine. When I try to re-write the code in a controller of wep-api I get a bad request error.
Where am I going wrong ? Any help ?
Note: The client-id's and other info are perfectly set in both the cases.
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;
}
}
class Program
{
public static async Task<bool> Post(string siteUrl, string requestUri, HttpContent content)
{
var credential = new System.Net.NetworkCredential(
"User",
"Pass",
"Domain");
using (var handler = new HttpClientHandler() { Credentials = credential, UseProxy = false })
{
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Accept.Clear();
var mediaType = new MediaTypeWithQualityHeaderValue("application/json");
mediaType.Parameters.Add(new NameValueHeaderValue("odata", "nometadata"));
client.DefaultRequestHeaders.Accept.Add(mediaType);
client.DefaultRequestHeaders.Add("X-RequestDigest", await GetRequestDigest());
string url = string.Format(requestUri, siteUrl);
HttpResponseMessage response = await client.PostAsync(url, content);
response.EnsureSuccessStatusCode();
return true;
}
}
}
static async Task Main(string[] args)
{
string domain = "xxxx";
string SiteUrl = "https://SITE/";
string issuesListById = "{0}_api/web/lists/GetByTitle('issues')/items?$filter=ID eq 1";
string taskListUrlById = "{0}_api/web/lists/GetByTitle('tasks')/items?$filter=ID eq 932";
var credentials = new NetworkCredential("User", "Pass", domain);
var handler = new HttpClientHandler { Credentials = credentials };
using (var http = new HttpClient(handler))
{
var stringContent = new StringContent("", Encoding.UTF8, "application/json");
http.DefaultRequestHeaders.Accept.Clear();
http.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await http.GetAsync(string.Format(taskListUrlById, SiteUrl)).ConfigureAwait(false);
string jsonData = await response.Content.ReadAsStringAsync();
var obj = JsonConvert.DeserializeObject<Tasks>(jsonData);
var itemToEdit = obj.Value.First();
itemToEdit.Status = "Close";
var content = new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");
var update = await Post(SiteUrl, taskListUrlById, content);
}
}
}
I am trying to update the status of a task in a SharePoint list to "Close", I am using the post method to send the content, I am receiving "bad request" in the post method... I am using REST to communicate with SharePoint on Premise any idea on what causing this problem? (the GetRequestDigest function is working well). if someone can help... Thanks in Advance.
string taskListUrlById = "{0}_api/web/lists/GetByTitle('tasks')/items(932)"; //932 is the ID of the item to update
string SiteUrl = "yoursite";
string url = string.Format(taskListUrlById, SiteUrl);
string content = "{ '__metadata': { 'type': 'SP.Data.TasksListItem' }, 'Status': 'Close'}";
var credential = new System.Net.NetworkCredential("username",
"Password",
"domain");
using (var handler = new HttpClientHandler() { Credentials = credential, UseProxy = false })
{
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var request = new HttpRequestMessage(HttpMethod.Post, url);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Add("X-RequestDigest", await GetRequestDigest());
request.Headers.Add("X-HTTP-Method", "MERGE");
request.Headers.Add("IF-MATCH", "*");
HttpContent strContent = new StringContent(content);
strContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
strContent.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("odata", "verbose"));
request.Content = strContent;
var response = await client.SendAsync(request);
}
}
Thanks in advance.
We are working on an oAuth2 process and need some help. The requirement given is to POST to the server with form variables embedded, and expect a server response in JSON. The documentation has a similar sequence involving a GET request returning JSON and a very similar method grabs the response just fine. However, in this case it gives an object ref error saying the response is null. We are getting a 200 OK message from server with a content length of 1929, and it says content-type is application/json so I have every reason to believe the content is there somewhere.
public rsAccessToken Signup(string Code, string State, string redirect_uri)
{
HttpClient client = new HttpClient();
rsAccessToken rt = null;
HttpResponseMessage response = null;
client.BaseAddress = new Uri(URLtoken);
string grant_type = "authorization_code";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", clientid, secret));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URLtoken);
var parameters = new Dictionary<string, string> { { "grant_type", grant_type }, { "code", Code }, { "state", State }, { "redirect_uri", redirect_uri } };
var encodedContent = new FormUrlEncodedContent(parameters);
Task task = client.PostAsync(URLtoken, encodedContent)
.ContinueWith((taskwithresponse) =>
{
Task<string> jsonString = response.Content.ReadAsStringAsync();
jsonString.Wait();
rt = JsonConvert.DeserializeObject<rsAccessToken>(jsonString.Result);
});
task.Wait();
client.Dispose();
return rt;
}
the response captured at the taskwithresponse point is:
Id = 104, Status = RanToCompletion, Method = "{null}", Result = "StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:\r\n{\r\n Connection: keep-alive\r\n Date: Mon, 14 Sep 2020 14:41:55 GMT\r\n ETag: W/\"789-W2Me6TSLLmO4+fEmAtfH4YWXhxs\"\r\n Set-Cookie: TS0108eb76=0119a2687f0aa2133862c3de61eb2485030f83265a0e1bcb62403e1c777052fccfeacf2df6a14e78b161afc6a43cfc2622532765bc; Max-Age=900; Path=/\r\n Content-Length: 1929\r\n Content-Type: application/json; charset=utf-8\r\n}"
Appreciate the help.
The correct code is:
public rsAccessToken VeteranSignup(string Code, string State, string redirect_uri)
{
HttpClient client = new HttpClient();
rsAccessToken rt = null;
client.BaseAddress = new Uri(URLtoken);
string grant_type = "authorization_code";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", clientid, secret));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URLtoken);
var parameters = new Dictionary<string, string> { { "grant_type", grant_type }, { "code", Code }, { "state", State }, { "redirect_uri", redirect_uri } };
var encodedContent = new FormUrlEncodedContent(parameters);
Task task = client.PostAsync(URLtoken, encodedContent)
.ContinueWith((taskwithresponse) =>
{
Task<string> jsonString = taskwithresponse.Result.Content.ReadAsStringAsync();
jsonString.Wait();
rt = JsonConvert.DeserializeObject<rsAccessToken>(jsonString.Result);
});
task.Wait();
client.Dispose();
return rt;
}
You should use taskwithreponse
Also, you should use the pure aysnc chain. Don't make the aynsc call to sync call.
public async Task<rsAccessToken> Signup(string Code, string State, string redirect_uri)
{
using(HttpClient client = new HttpClient())
{
rsAccessToken rt = null;
client.BaseAddress = new Uri(URLtoken);
string grant_type = "authorization_code";
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
var byteArray = Encoding.ASCII.GetBytes(string.Format("{0}:{1}", clientid, secret));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var(HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, URLtoken))
{
var parameters = new Dictionary<string, string> { { "grant_type", grant_type }, { "code", Code }, { "state", State }, { "redirect_uri", redirect_uri } };
var encodedContent = new FormUrlEncodedContent(parameters);
HttpResponseMessage response = await client.PostAsync(URLtoken, encodedContent)
var jsonString = await response.Content.ReadAsStringAsync();
rt = JsonConvert.DeserializeObject<rsAccessToken>(jsonString.Result);
}
return rt;
}
}
So, because HttpClient is "better," I need to convert WebClient to HttpClient, but it just doesn't work as expected. The following function uses WebClient and works like a charm.
private static void Authenticate()
{
Console.WriteLine("Authenticating . . .");
var clientId = ConfigurationManager.AppSettings["AuthNClientId"];
var uri = ConfigurationManager.AppSettings["AuthNUri"];
var userName = ConfigurationManager.AppSettings["AuthNUserName"];
var password = ConfigurationManager.AppSettings["AuthNPassword"];
var client = new WebClient();
string formData = $"client_id={clientId}&grant_type=password&username={userName}&password={password}";
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
var response = client.UploadString($"{uri}", formData);
dynamic authResult = JsonConvert.DeserializeObject(response);
_accessToken = authResult.access_token;
if (_accessToken == null)
{
throw new ApplicationException("Unable to authenticate. Check your configuration file <appSettings>.");
}
Console.WriteLine("Authenticated.");
}
This code, on the other hand, returns a BadRequest response code.
static async Task<string> GetAuthenticationToken()
{
string token = string.Empty;
var clientId = ConfigurationManager.AppSettings["AuthNClientId"];
var uri = ConfigurationManager.AppSettings["AuthNUri"];
var userName = ConfigurationManager.AppSettings["AuthNUserName"];
var password = ConfigurationManager.AppSettings["AuthNPassword"];
client.BaseAddress = new Uri("https://myurl.com/oauth2/token");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("ContentType", "application/x-www-form-urlencoded");
var path = $"client_id={clientId}&grant_type=password&username={userName}&password={password}";
HttpResponseMessage response = await client.GetAsync($"https://myurl.com/oauth2/token?{path}");
if (response.IsSuccessStatusCode)
{
Console.WriteLine("success");
token = await response.Content.ReadAsStringAsync();
}
else { Console.WriteLine($"failure: {response.StatusCode}"); }
return token;
}
You can see that I've tried it a couple of ways, including setting the client BaseAddress as well as just try to pass the url into the GetAsync method.
Anyone see what I'm doing wrong here?
UploadString is a POST method in the first example. In the second example a GET method is being done.
static async Task<string> GetAuthenticationTokenAsync() {
string token = string.Empty;
var clientId = ConfigurationManager.AppSettings["AuthNClientId"];
var uri = ConfigurationManager.AppSettings["AuthNUri"];
var userName = ConfigurationManager.AppSettings["AuthNUserName"];
var password = ConfigurationManager.AppSettings["AuthNPassword"];
var client = new HttpClient();
client.BaseAddress = new Uri(uri);
client.DefaultRequestHeaders.Accept.Clear();
var nameValueCollection = new Distionary<string, string>() {
{ "client_id", clientId },
{ "grant_type", "password" },
{ "username", userName },
{ "password", password },
};
var content = new FormUrlEncodedContent(nameValueCollection);
var response = await client.PostAsync("", content);
if (response.IsSuccessStatusCode) {
Console.WriteLine("success");
var json = await response.Content.ReadAsStringAsync();
dynamic authResult = JsonConvert.DeserializeObject(json);
token = authResult.access_token;
}
else { Console.WriteLine($"failure: {response.StatusCode}"); }
return token;
}
I have got error with RestSharp component when i am call Paypal Rest API.
I have the following code using Xamarin for Android.
public async Task<PayPalGetTokenResponse> GetAccessToken()
{
var restRequest = new RestRequest("/oauth2/token", Method.POST);
// Add headers
restRequest.AddHeader("Accept", "application/json");
restRequest.AddHeader("Accept-Language", "en_US");
// Make Authorization header
restClient.Authenticator = new HttpBasicAuthenticator(Config.ApiClientId, Config.ApiSecret);
// add data to send
restRequest.AddParameter("grant_type", "client_credentials");
var response = restClient.Execute<PayPalGetTokenResponse>(restRequest);
response.Data.DisplayError = CheckResponseStatus(response, HttpStatusCode.OK);
return response.Data;
}
But got error :"Error: SecureChannelFailure (The authentication or decryption has failed.)"
I have Also use ModernHttpClient but got same error
public async Task<PayPalGetTokenResponse> GetAccessToken()
{
string clientId = Config.ApiClientId;
string secret = Config.ApiSecret;
string oAuthCredentials = Convert.ToBase64String(Encoding.Default.GetBytes(clientId + ":" + secret));
string uriString = Config.ApiUrl+"/oauth2/token";
PayPalGetTokenResponse result;
HttpClient client = new HttpClient(new NativeMessageHandler());
var h_request = new HttpRequestMessage(HttpMethod.Post, uriString);
h_request.Headers.Authorization = new AuthenticationHeaderValue("Basic", oAuthCredentials);
h_request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
h_request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue("en_US"));
h_request.Content = new StringContent("grant_type=client_credentials", UTF8Encoding.UTF8);
try
{
HttpResponseMessage response = await client.SendAsync(h_request);
//if call failed ErrorResponse created...simple class with response properties
if (!response.IsSuccessStatusCode)
{
var error = await response.Content.ReadAsStringAsync();
var errResp = JsonConvert.DeserializeObject<string>(error);
//throw new PayPalException { error_name = errResp.name, details = errResp.details, message = errResp.message };
}
var success = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject<PayPalGetTokenResponse>(success);
}
catch (Exception)
{
throw new HttpRequestException("Request to PayPal Service failed.");
}
return result;
}
Have you tried to force to modern day SSL protocol?
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
This works for me:
if (ServicePointManager.SecurityProtocol != SecurityProtocolType.Tls12)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var client = new RestClient(payPalURL) {
Encoding = Encoding.UTF8
};
var authRequest = new RestRequest("oauth2/token", Method.POST) {
RequestFormat = DataFormat.Json
};
client.Authenticator = new HttpBasicAuthenticator(clientId, secret);
authRequest.AddParameter("grant_type","client_credentials");
var authResponse = client.Execute(authRequest);