Zoho Invoice API Error {"error":"invalid_client"} while requesting for token - zoho

While accessing Zoho api to get the token I'm getting the following error:
{"error":"invalid_client"}
Step 1: I'm requesting for Auth Code and the auth code is returned successfully.
This is the API I'm using.
https://accounts.zoho.com/oauth/v2/auth?scope=xxx&client_id=yyyyy&state=zzzz&response_type=code&redirect_uri=pppppp&access_type=offline
Step 2: Token Request
With the Auth Code obtained in Step-1 I'm doing a post request for the token at that time only I'm getting the below exception.
var authTokenRequestData = new
{
code= code,
client_id= _clientId,
client_secret =_clientSecret,
redirect_uri = _redirectUri,
grant_type = "authorization_code"
};
var data = new StringContent(JsonConvert.SerializeObject(authTokenRequestData), Encoding.UTF8, "application/json");
var url = "https://accounts.zoho.com/oauth/v2/token";
string result = "";
using (var client = new HttpClient())
{
var response = await client.PostAsync(url, data);
result = await response.Content.ReadAsStringAsync();
}
It's giving me the exception
{error:invalid_client}
I've verified my client_id and client_secret. It's correct only.
It's Server-Based-Application client I've registered.
Any help is highly appreciated on this.

There could be one more reason for this issue.
{"error":"invalid_client"}
Check if you're using the correct domain. (.in .com or...)
For example, you're using .in instead of .com or vice-versa
In my case when I was using .in domain but my domain was .com I was getting the same error {"error":"invalid_client"}
I was using this:
var url = "https://accounts.zoho.in/oauth/v2/token";
I replaced it as below and that solved my issue.
var url = "https://accounts.zoho.com/oauth/v2/token";

I could solve this issue by changing the request Content-Type
"Content-Type", "application/x-www-form-urlencoded"
Complete code is as follows:
string _domain = ".in"; /*Ensure you're using the correct .com or .in domain*/
var url = "https://accounts.zoho"+ _domain + "/oauth/v2/token";
string result = "";
using (var client = new HttpClient())
{
var data = new Dictionary<string, string>
{
{ "Content-Type", "application/x-www-form-urlencoded" },
{ "code", code },
{ "client_id", _clientId },
{ "client_secret", _clientSecret },
{ "redirect_uri", _redirectUri },
{ "grant_type", "authorization_code" },
{ "access_type", "offline" }
};
var response = await client.PostAsync(url, new FormUrlEncodedContent(data));
result = await response.Content.ReadAsStringAsync();
}

Related

How to Fetch Access token from my custom controller in asp.net web api 2

I have implemented the code for generating access token.I am able to get the token from default Token End Point Path(https://localhost:44312/token) when trying to get it from Postman.
However I want to implement Login Controller which internally should call the default token end point and send the response.
public async Task<IHttpActionResult> Login(UserModel userModel)
{
HttpResponseMessage response;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://localhost:44312/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Add("cache-control", "no-cache");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
userModel.grant_type = "password";
var parameters = new Dictionary<string, string> { { "username", userModel.UserName }, { "password", userModel.Password }, { "grant_type", "password" } };
var encodedContent = new FormUrlEncodedContent(parameters);
response = client.PostAsync("/token", encodedContent).Result;
}
return Ok(response);
}
I get an httpstatus OK response but not the access token. Any guidance in solving the issue would be helpful.

Getting 400 bad request when I use "ValidateAntiForgeryToken" and "Authorize"

I'm using asp.net core in the server side and xamarin in the client side.I use JWT token and I want to validate forgery token at the same time.
This is my client side code :
public async Task<string> PostAsync(object model, string url)
{
var cookieContainer = new CookieContainer();
var handlerhttps = new HttpClientHandler
{
UseCookies = true,
UseDefaultCredentials = true,
CookieContainer = cookieContainer
};
var clientPage = new HttpClient(handler: handlerhttps)
{
BaseAddress = new Uri(uriString: Application.Current.Resources[index: "Domain"] + "/api/token")
};
var pageWithToken = await clientPage.GetAsync(requestUri: clientPage.BaseAddress);
var verificationToken = await pageWithToken.Content.ReadAsStringAsync();
using (var handler = new HttpClientHandler
{
CookieContainer = cookieContainer,
UseDefaultCredentials = true,
UseCookies = true
})
{
using (var client = new HttpClient(handler: handler) {BaseAddress = new Uri(uriString: url)})
{
client.DefaultRequestHeaders.Add(name: "RequestVerificationToken", value: verificationToken);
if (Application.Current.Properties[key: "Token"] != null)
{
var token = Application.Current.Properties[key: "Token"].ToString();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue(scheme: "Bearer", parameter: token);
}
var json = JsonConvert.SerializeObject(value: model);
var content = new StringContent(content: json, encoding: Encoding.UTF8,
mediaType: "application/json");
var response = await client.PostAsync(requestUri: client.BaseAddress, content: content);
var result = await response.Content.ReadAsStringAsync();
return result;
}
}
}
My problem is when I use [ValidateAntiForgeryToken] and [Authorize] in the server side at the same time, I get 400 bad request.
But when I remove [ValidateAntiForgeryToken], It will authorize without any problem.
When I remove [Authorize] , I don't get 400 bad request and it validate forgery token successfully.
I don't know how to solve this problem.
If you are using Microsoft.AspNetCore.Mvc.TagHelpers it will add a input field with a 'difficult to guess' code:
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PXv-VNSuRBLvOlUgHlQcf4p8B29vW6EKn4ENesSgHR79kWTvbnQ9a1Taj90b-e66-79H7Nx5ljHnvPbwqfSNqHMRMaBkoRKGsTxtbZZlq0rSl2zbGK2aKpPQc0qnoNuRehSNhP097P5-Vlp-3OSPYdIqLQJSqIsPDaQsEOXsNU4qIIDrj-tIhqk5EW9tTYc6g">
Anyways, even if you add #Html.AntiForgeryToken() it wouldn't conflict. However you cannot decorate the 'first' controller action with [ValidateAntiForgeryToken], only the final one with will get the POST.
Example:
Action 1
[HttpPost]
[AllowAnonymous]
[ActionName("SpecialSignUp")]
public IActionResult Index([FromForm] string email)
{
// TODO : code in here
return View(email);
}
Users will be redirect to above action through a POST.
Let's say that the view above displays a form with the email field pre-filled and other fields to be filled.
If you decorate it with [ValidateAntiForgeryToken] you will get a 400 (Bad Request). Removing it, all will be fine.
Action 2
[HttpPost]
[AllowAnonymous] // It could be [Authorized]
[ActionName("SpecialSignUp")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LaunchSignUpAsync([FromForm] SpecialSignUpViewModel model)
{
// TODO : Code in here
return RedirectToAction("OtherActionX", data);
}
Form will be posted by the above View
Now all it's working, no conflict is happening anymore. If you respect that sequence, it will work for you!
I had the same issue, and it was happening because I decorated the 'Action 1' with [ValidateAntiForgeryToken] as well.
Hopefully it helps!
I faced a similar issue but got it resolved by adding "RequestVerificationToken" on my request
My controller code (sample)
HttpPost("SignOut")
Authorize ==> using JWT
ValidateAntiForgeryToken
*/
You can try making a custom method for validation of JWT token to replace the
[Authorize] by
public void ValidateJWT(string token, out bool status)
{
if (token == null)
{
status = false;
}
byte[] secretKey = System.Text.Encoding.UTF8.GetBytes("your jwt secret key");
var tokenHandler = new JwtSecurityTokenHandler();
try
{
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(secretKey),
ValidateIssuer = false,
ValidateAudience = false,
ClockSkew = TimeSpan.Zero
}, out SecurityToken validatedToken);
status = true;
}
catch
{
status = false;
}
}

Dynamics WEB API returns on post -StatusCode: 401, ReasonPhrase: 'Unauthorized'

I am trying to create a lead in CRM from via web api , but its throwing unauthorized access error. I am able to login to CRM but from Web Api , It's throwing error
Below is my code
var credentials = new NetworkCredential("username", "password");
var client = new HttpClient(new HttpClientHandler() { Credentials = credentials })
{
BaseAddress = new Uri("https://*******.dynamics.com/XRMServices/2011/Organization.svc/api/data/v8.2/")
};
Entity lead1 = new Entity();
lead1["firstname"] = "TestFirstName";
lead1["lastname"] = "TestLastName";
lead1["emailaddress1"] = "%%%%%%%%%";
lead1["companyname"] = "&&&&&&";
string output = new JavaScriptSerializer().Serialize(lead1).ToString();
HttpRequestMessage request = null;
try
{
request = new HttpRequestMessage(HttpMethod.Post, "leads");
request.Content = new StringContent(output);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
Task<HttpResponseMessage> response = client.SendAsync(request);
response.Wait();
if (response.Result.IsSuccessStatusCode)
{
//retrievedContact1 = JsonConvert.DeserializeObject<JObject>(rep .Content.ReadAsStringAsync());
}

Resharpe.portable get Twitter request token

Hello i'm doing an xamarin.form application and i'm implementing the twitter login using oauth.
I have problem to get the request_token folowing the link:
https://dev.twitter.com/oauth/reference/post/oauth/request_token
using restsharp.portable for the request POST i arrive at this point:
public async void GetTwitterToken()
{
try
{
TwitterLogin tw = new TwitterLogin();
RestClient client = new RestClient("https://api.twitter.com");
RestRequest request = new RestRequest("/oauth/request_token", Method.POST);
client.Authenticator = OAuth1Authenticator.ForRequestToken(tw.oauth_consumer_key, tw.oauth_consumer_secret);
IRestResponse response = await client.Execute(request);
}
catch (Exception e)
{
}
}
Parameter "response" it's ok but i'don't know how to parse to get token (it's not json).
i have seen this example:
public void GetRequestToken()
{
var client = new RestClient("https://api.twitter.com"); // Note NO /1
client.Authenticator = OAuth1Authenticator.ForRequestToken(
_consumerKey,
_consumerSecret,
"http://markashleybell.com" // Value for the oauth_callback parameter
);
var request = new RestRequest("/oauth/request_token", Method.POST);
var response = client.Execute(request);
var qs = HttpUtility.ParseQueryString(response.Content);
_token = qs["oauth_token"];
_tokenSecret = qs["oauth_token_secret"];
}
But i don't have HttpUtility.ParseQueryString(response.Content) whith xamarin.form framework

wp7 - POST http request with parameters in request body using RestSharp

I am trying to POST parameters through the request, to a service that returns a JSON object. The service works well for android and iOS. I am trying to get this working for wp7. The service requires the content type to be 'application/json' I have pasted the code that sets up the http request below:
var client = new RestClient(baseurl);
var request = new RestRequest();
request.Resource = "login";
request.Method = Method.POST;
request.AddHeader("Accept", "application/json");
request.AddHeader("content-type", "application/json");
request.RequestFormat = DataFormat.Json;
var postData = new Dictionary<string, string>()
{
{"key1",value1},
{"key2",value2}
};
request.AddBody(postData);
client.ExecuteAsync(request, response =>
{
var jsonUser = response.Content;
});
The response error I get from the server is an internal server error. Is anything wrong with the code above. I also tried request.AddParameter method but ended with the same result. The code for that is below:
var client = new RestClient(baseurl);
var request = new RestRequest();
request.Resource = "login";
request.Method = Method.POST;
request.AddHeader("Accept", "application/json");
request.AddHeader("content-type", "application/json");
request.RequestFormat = DataFormat.Json;
var postData = new Dictionary<string, string>()
{
{"key1",value1},
{"key2",value2}
};
var json = JsonConvert.SerializeObject(postData);
request.AddParameter("application/json", json, ParameterType.RequestBody);
client.ExecuteAsync(request, response =>
{
var jsonUser = response.Content;
});
Is there anything that I am doing wrong in either of the cases?

Resources