I'm trying to retrieve an access token from Google's authorization endpoint, however I keep getting 401: Unauthorized.
I'm pretty sure all the values being sent (authorization code, client's id, client's secret, redirect uri and grant type) are correct.
My code is the following:
using (HttpClient client = new HttpClient()) {
IEnumerable<KeyValuePair<string,string>> data = new List<KeyValuePair<string,string>>
{
new KeyValuePair<string,string>("code", "CODE_HERE"),
new KeyValuePair<string,string>("client_id", "CLIENT_ID_HERE"),
new KeyValuePair<string,string>("client_secret", "CLIENT_SECRET_HERE"),
new KeyValuePair<string,string>("redirect_uri", "REDIRECT_URI_HERE"),
new KeyValuePair<string,string>("grant_type", "authorization_code"),
}
HttpContent content = new FormUrlEncodedContent(data);
/* I'm getting 401 Unauthorized */
HttpResponseMessage response = await client.PostAsync("https://www.googleapis.com/oauth2/v3/token", content);
}
The response's JSON is:
{
"error": "invalid_client",
"error_description": "Unauthorized"
}
However, I'm copying & pasting the client's id and client's secret from my Google Developer control panel, so there is no way they are wrong.
Any help?
Here is what worked for me. In this sample, I'm using the RefreshToken to get an AccessToken.
var client_id = ConfigurationManager.AppSettings.Get("GoogleClientId");
var client_secret = ConfigurationManager.AppSettings.Get("GoogleSecret");
var grant_type = "refresh_token";
var url = "https://www.googleapis.com/oauth2/v4/token";
IEnumerable<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string,string>("client_id", client_id),
new KeyValuePair<string,string>("client_secret", client_secret),
new KeyValuePair<string,string>("grant_type", grant_type),
new KeyValuePair<string,string>("refresh_token", refreshToken),
};
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
HttpContent contentPost = new FormUrlEncodedContent(data);
HttpResponseMessage response = await client.PostAsync(url, contentPost);
var result = response.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<GoogleAPIAuth>(result);
Here is my GoogleAPIAuth class.
public class GoogleAPIAuth
{
public string client_secret { get; set; }
public string grant_type { get; set; }
public string refresh_token { get; set; }
public string client_id { get; set; }
public string access_token { get; set; }
public string expires_in { get; set; }
public string token_type { get; set; }
}
Related
I managed to get the token through this guide: https://platform.fatsecret.com/api/Default.aspx?screen=rapiauth2, but I couldn't get responce correctly. Where did I go wrong in the code?
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private async void BtnFoodApi_Click(object sender, RoutedEventArgs e)
{
// --- Get Token --
HttpClient client = new HttpClient();
var byteArray = Encoding.ASCII.GetBytes("9276456b47524b479cbdaf7cf5792bbf:0366d2fc646e4b6f89bf11bddbaec6a4");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
var values = new Dictionary<string, string>
{
{ "scope", "basic" },
{ "grant_type", "client_credentials" }
};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("https://oauth.fatsecret.com/connect/token", content);
var responseString = await response.Content.ReadAsStringAsync();
var serializer = new DataContractJsonSerializer(typeof(RootObject));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(responseString));
var data = (RootObject)serializer.ReadObject(ms);
// --- Get responce --
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", data.access_token);
var valuesRequest = new Dictionary<string, string>
{
{ "application", "json" },
};
var contentRequest = new FormUrlEncodedContent(valuesRequest);
var responseRequest = await http.PostAsync("https://platform.fatsecret.com/rest/server.api", contentRequest);
//Parameters: method=foods.search&search_expression=toast&format=json // How can I call Api 2.0 with these parameters?
//var responseRequestString = await responseRequest.Content.ReadAsStringAsync();
}
}
[DataContract]
public class RootObject
{
[DataMember]
public string access_token { get; set; }
[DataMember]
public int expires_in { get; set; }
[DataMember]
public string token_type { get; set; }
}
I would like to get to the responseRequest String string in Json string.
At the bottom of this page there is the guide about this step and I tried to write it in c # but incorrectly.
Thanks in advance!
You don't need to base64-encode your Bearer token - that's only used to obfuscate Basic authentication. You can use the string as-is.
http.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", data.access_token);
I have been searching solution for few hours and I can't find answer to my problem.
I want to send a post method to a web api and I've tried it first on postman using these json content and it is working.
{
"ETickets": [
{
"TicketName": "Weekend - Regular Day Pass",
"TicketAccessType": "PA",
"TicketGuest": "RDP",
"IsWeekday": true
},
{
"TicketName": "Weekend - Regular Day Pass",
"TicketAccessType": "PA",
"TicketGuest": "RDP",
"IsWeekday": true
}
],
"TransactDetails": {
"CompanyCode": "ONLINE",
"Surname": "Dela Cruz",
"FirstName": "Juan",
"BookingReference": "1113",
"BookingDate": "2018-08-16T11:31:20:04"
}
}
However, when I try it in coding style, I can't make it to work. It says 500 internal server error upon debugging.
Here's the error screenshot:
Here's my few codes related to my issue:
TransactionDetailsViewModel finale = new TransactionDetailsViewModel();
finale.TransacDetails = transacDetail;
finale.ETickets = lsTickets.ToArray();
client = new HttpClient();
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", System.Web.HttpContext.Current.Session["WebApiAccessToken"].ToString());
HttpResponseMessage responseMessage = await client.PostAsJsonAsync(url + "api/Transaction/SendTransaction/", finale);
And here's the model I'ved used:
public class TransactionDetailsViewModel
{
public TransactionDetails TransacDetails { get; set; }
public TicketDetailsModel[] ETickets { get; set; }
}
public class TransactionDetails
{
public string CompanyCode { get; set; }
public string Surname { get; set; }
public string FirstName { get; set; }
public string BookingReference { get; set; }
public DateTime? BookingDate { get; set; }
}
public class TicketDetailsModel
{
public string TicketAccessType { get; set; }
public string TicketGuest { get; set; }
public string TicketName { get; set; }
public bool IsWeekday { get; set; }
}
Do I send the data with the correct format or something to adjust to make it work on sending to a PostAsJsonAsync?
Any help will be much appreciated. Thanks.
Please, modify your code just like as
var data = new StringContent(JsonConvert.SerializeObject(finale, Encoding.UTF8, "application/json"));
HttpResponseMessage responseMessage = await client.PostAsJsonAsync("api/Transaction/SendTransaction/", data);
OR You can make request and then send like as
HttpResponseMessage response = null;
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Post, url+"/api/Transaction/SendTransaction"))
{
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", System.Web.HttpContext.Current.Session["WebApiAccessToken"].ToString());
var data = new StringContent(JsonConvert.SerializeObject(finale, Encoding.UTF8, "application/json"));
request.Content = data;
response = await client.SendAsync(request);
}
}
Please try below line to post data
httpClient.PostAsync(url + "/api /Transaction/SendTransaction/", new StringContent(JsonConvert.SerializeObject(finale).ToString(), Encoding.UTF8, "application/json")).Result;
I managed to get access token with my code,
private async Task<string> GetAccessToken()
{
string refreshToken = string.Empty;
string accessToken = string.Empty;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://demo.docusign.net/restapi/v2/oauth2/token");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
string body =
"username=user%40company.net&password=mypassword&client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxc&grant_type=password&scope=api";
HttpContent content = new System.Net.Http.StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded");
HttpResponseMessage messge = await client.PostAsync("https://demo.docusign.net/restapi/v2/oauth2/token", content);
//string description = string.Empty;
if (messge.IsSuccessStatusCode)
{
string result = messge.Content.ReadAsStringAsync().Result;
dynamic returnObj = JsonConvert.DeserializeObject(result);
var scope = returnObj.scope.Value;
accessToken = returnObj.access_token.Value;
}
return accessToken;
}
This gives me the access token,
Now I am trying to use that token and add a user to the account,
private async Task<string> AddUser(string accessToken, string usersBaseUri)
{
usersBaseUri = "https://demo.docusign.net/restapi/v2/accounts/<myaccountId>/users";
string resultStr = string.Empty;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(usersBaseUri);
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
DocuSignUser user = new DocuSignUser();
user.Email = "user2#company.net";
user.UserName = "user2#company.net";
user.FirstName = "user2";
user.LastName = "dev";
var json = JsonConvert.SerializeObject(user);
HttpContent content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage messge = await client.PostAsync(usersBaseUri, content);
//string description = string.Empty;
if (messge.IsSuccessStatusCode)
{
string result = messge.Content.ReadAsStringAsync().Result;
dynamic returnObj = JsonConvert.DeserializeObject(result);
var scope = returnObj.scope.Value;
accessToken = returnObj.access_token.Value;
}
return resultStr;
}
Here is the Docusign User class I use to serialize,
public class DocuSignUser
{
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("userName")]
public string UserName { get; set; }
[JsonProperty("firstName")]
public string FirstName { get; set; }
[JsonProperty("lastName")]
public string LastName { get; set; }
}
User api is not supported in the .Net SDK. Therefor I had to write this code by referring to Docusign Api test playground and checking the Request/Response with Fiddler.
Appreciate any help on this.
EDIT
Here is the POST request
POST https://demo.docusign.net/restapi/v2/accounts/156xxxx/users HTTP/1.1
Accept: application/json
Authorization: Bearer *******<AccessToken>
Content-Type: application/json; charset=utf-8
Host: demo.docusign.net
Content-Length: 100
Expect: 100-continue
{"email":"user1#company.net","userName":"user1#company.net","firstName":"Sam1","lastName":"Cooper1"}
Found the answer,
Issue was with the Json message.
Required Json format is in the following format as per Api Guide
{
"newUsers":[
{
"email":"user#company.net",
"firstName":"name1",
"lastName":"lastname1",
"password":"Password01",
"userName":"user1#bcompany.net"
}
]
}
So I create an HttpPut method in an ASP.NET web api.
[Route("api/Account/Save")]
[HttpPut]
public IHttpActionResult SaveAccount(Account acc) {
// do stuff
}
I pass in an instant of the Account class.
class Account
{
public int AccountID { get; set; }
public string AccountName { get; set; }
}
Now I want to call this from a console application. I am trying to do this but it's not working. It's not throwing any exception either.
var acc = new Account() { AccountID = 1234, AccountName = "zzzzP" };
string json = JsonConvert.SerializeObject(acc);
HttpContent content = new StringContent(json);
response = await client.PutAsync("api/Account/Save", content);
Json returned:
"{\"AccountID\":1234,\"AccountName\":\"zzzzP\"}"
You probably want something like this
static async Task PutAccount()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://yourWebSite.com");
var acc = new Account() { AccountID = 1234, AccountName = "zzzzP" };
string json = JsonConvert.SerializeObject(acc);
using (HttpResponseMessage response = await client.PutAsync("api/Account/Save", new StringContent(json)))
{
return response.EnsureSuccessStatusCode();
}
}
}
I am just beginning developing using RestSharp and have hit an early roadblock. I think once I understand this simple, but key, concept, I should be off and running. I need to return an Access Token before making my standard calls later. I have set up the following classes, generated from json2csharp.com:
public class AccessToken
{
public string Instance_Url { get; set; }
public string Token { get; set; }
public string Expiration_date { get; set; }
public string Refresh_Token { get; set; }
}
public class RootObject
{
public AccessToken Access_Token { get; set; }
}
I have coded the following on a button click:
var tokenclient = new RestClient();
tokenclient.BaseUrl = "https://url";
tokenclient.Authenticator = new HttpBasicAuthenticator("username", "password");
var tokenrequest = new RestRequest(Method.GET);
tokenrequest.RequestFormat = DataFormat.Json;
IRestResponse tokenresponse = tokenclient.Execute(tokenrequest);
var content = tokenresponse.Content;
RestSharp.Deserializers.JsonDeserializer deserial = new JsonDeserializer();
var des = deserial.Deserialize<AccessToken>(tokenresponse);
I am able to return the following JSON as a string:
{
"Access_Token": {
"Instance_Url": "https://url",
"Token": "StringToken",
"Expiration_date": "9/30/2015 6:15:27 PM",
"Refresh_Token": "StringToken"
}
}
However, when I pull des.Token, it returns a blank value. Can somebody kindly point out my error?
using Newtonsoft.Json;
var response = client.DownloadString(url + queryString);
ResponseModel<string> dataResponse = new ResponseModel<string>();
if (!string.IsNullOrEmpty(response))
{
dataResponse = JsonConvert.DeserializeObject<ResponseModel<string>>(response);
}