I am trying to authenticate RESTful service (sabre REST api) using RESTsharp library but i am not able to authenticate it. I am using my Client id and secret. Please tell me how to authenticate using oAuth 2.0 authenticator.
I have tried this code. ( sabre is using OAuth 2.0 authentication )
public ActionResult Index()
{
var client = new RestClient("https://api.test.sabre.com");
client.Authenticator = new HttpBasicAuthenticator("myclientid", "myclientsecret");
RestRequest request = new RestRequest("/v1/auth/token", Method.POST);
request.AddHeader("Authorization", "Basic " + client);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials");
IRestResponse response = client.Execute(request);
var content = response.Content;
ViewBag.R = content;
return View();
}
i got this result
{"error":"invalid_client","error_description":"Credentials are missing or the syntax is not correct"}
please tell what i am doing wrong.
Thanks
Snapshot of Fiddler Comparison of Running code (not with RestSharp) and code using RestSharp is shown
With RestSharp
Seems to me like you are adding the Authorization header twice. The documentation here says
The authenticator’s Authenticate method is the very first thing called
upon calling RestClient.Execute
Looking at the implementation of HttpBasicAuthenticator, the Authenticate method adds the appropriate header to the request.
So remove the following line from your example:
request.AddHeader("Authorization", "Basic " + client);
You need to first obtain access token from Sabre that you can later use while making rest api calls.
The access token POST request looks like this:
POST https://api.test.sabre.com/v2/auth/token
Authorization: Basic ZVc5MWNtTnNhV1Z1ZEdsazplVzkxY21Oc2FXVnVkSE5sWTNKbGRBPT0=
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
where the value of Authorization after Basic is the Base64 encoded string based on your clientId and secret
Refer to Sabre Authentication on how this string is created
So, in order to get the access token you just need to send a POST request with required header and request parameters and you do not need to use the Authenticator
Related
I developped an api using spring boot withuser authentication and authorizations with spring securtiy.
And I am using spring security login form for user authentication.
I tested it with postman and it is working perfectly.
But when I implemented the api in asp.net mvc 5 project the login works and return the connected user but i get unauthorized message after any other request that needs authenticated user.
I think it works in postman because he generates or get headers from response of login.
How can i get them so i can integrate them in other requests.
Edit:
It seems that JSESSIONID Cookie header is needed and I took it from login response header and added it to my request header but it still doesn't work
Here is my code that adds the header:
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Cookie", loginResponse.Headers.GetValues("Set-Cookie").First().Split(';')[0].Trim());
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
client.BaseAddress = new Uri("http://localhost:8080/api/");
HttpResponseMessage response = client.GetAsync("customer/users").Result;
This line give me the Cookie header value from login response i need:
loginResponse.Headers.GetValues("Set-Cookie").First().Split(';')[0].Trim()
HttpClient will ignore header Cookie
when creating an instance to it you need to pass an HttpClientHandler with UseCookies to false so it will not ignore it
HttpClient httpClient = new HttpClient(new HttpClientHandler { UseCookies = false })
Answer found here
I have read the documentation for OAuth on this website.
But I am still confused about the format in which the request url is supposed to be in.
Any help would be amazing.
You may use the following request url to generate the Access Token,
String URL = "https://outpost.mapmyindia.com/api/security/oauth/token?grant_type=client_credentials&client_id="+clientid+"&client_secret="+clientsecret;
And, add the following Headers in the POST Method,
("accept", "application/json")
("Content-Type", "application/x-www-form-urlencoded")
If you are using Volley Library to get the Access Token using the POST request,
you may pass the parameters as a HashMap as follows:
Map<String, String> params = new HashMap<String, String>();
params.put("accept", "application/json");
params.put("Content-Type", "application/x-www-form-urlencoded");
It looks like they use Spring. And it requires grant_type to be passed as application/x-www-form-urlencoded. And the credentials in a header:
{
'Authorization': `Basic ${base64Encode(clientId:clientSecret)}`,
}
I hope someone can help me.
I am trying to retrieve a Product Review for a product using the Trustpilot Api's and am having some success but not getting the results I would expect.
The approach I have taken is as follows:
Get an OAUTH2 token - (Returns a successful response)
Retrieve my business units from a config file and for each business unit get the product reviews using the endpoint: https://api.trustpilot.com/v1/private/business-units/{business-unit}/review?token={OAUTH2 token from step 1} - (Returns a successful response)
For each product review I attempt to retrieve the product review detail. For this I have a couple of options.
(i) Each product review has meta-links and so I can get the product review using the corresponding meta-link and tagging the apikey on e.g. https://api.trustpilot.com/v1/reviews/1234567890abcdefg?apikey={apikey} where the apikey is the one provided up when I registered for a developer account - (Returns a successful response)
(ii) Call the endpoint as documented in the developers.trustpilot.api website (https://developers.trustpilot.com/product-reviews-api#get-private-product-review) : https://api.trustpilot.com/v1/private/product-reviews/{reviewId} - (Returns an Unauthorised status code)
For option (ii) above I have tried multiple ways of passing the apikey (according to the documentation, the endpoint requires the apikey as authorisation.
I am using C# as the language for accessing the Trustpilot apis so the following snippets are how I have tried to call the method.
Set the GetProductReview endpoint as follows:
var url = $"https://api.trustpilot.com/v1/private/product-reviews/" + review.Id.ToString();
using (var client = new HttpClient())
{
var uri = new Uri(url, UriKind.Absolute);
client.BaseAddress = uri;
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new system.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("apikey", apiKey);
try
{
var response = client.GetAsync(uri).Result;
.
.
.
In the above code snippet, the apikey is passed in to the method and passed to the endpoint as a RequestHeader value.
Set the endpoint as follows:
var url = $"https://api.trustpilot.com/v1/private/product-reviews/" + review.Id + $"?apikey={apiKey}";
and call the HttpClient as follows:
using (var client = new HttpClient())
{
var uri = new Uri(url, UriKind.Absolute);
client.BaseAddress = uri;
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
try
{
var response = client.GetAsync(uri).Result;
.
.
.
In both cases I receive an HttpStatus 401 - Unauthorized.
The documentation indicates that I should pass the apikey (which I have done in two different ways).
I have also tried calling the endpoint replacing the ?apikey={apiKey} with ?token={token} in case the documentation is incorrect and requires a token.
Additionally, I have also tried passing the token as a RequestHeader value and receieve the same result (Unauthoirised)
I would really like to use the endpoint:
https://api.trustpilot.com/v1/private/product-reviews/{review}
as this returns more information (for example the sku which would allow me to get access back to the product).
Can anyone please tell me where I am going wrong here?
Thanks in advance
The documentation for the /v1/private/product-reviews/{reviewId} endpoint is indeed incorrect, since it actually requires a Business user OAuth Token instead of an API Key.
In this case, you have two options (and the first one you have used before for the /v1/private/business-units/{businessUnitId}/reviews endpoint):
You can pass the access token in the query string: /v1/private/product-reviews/{reviewId}?token={token}. You mentioned you have tried this. Maybe it did not work for you because your token expired before you tried this approach. Can you try again after refreshing the token?
You can also pass the access token as a Bearer authorization header:
var url = $"https://api.trustpilot.com/v1/private/product-reviews/{review.Id.ToString()}";
using (var client = new HttpClient())
{
...
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
...
}
In any case, you caught an error in the documentation that should be fixed soon. As a rule of thumb, all private endpoints (the ones that have /private/ in the path) require a Business user OAuth Token.
EDIT: The documentation for the /v1/private/product-reviews/{reviewId} endpoint has been fixed. Now it shows that a Business user OAuth Token is required.
I am using Restlet2.3 to run REST API test automation.
The new feature has a customer HTTP header to pass a token to the service.
Form headers = (Form)resource.getRequestAttributes().get("org.restlet.http.headers");
if (headers == null) {
headers = new Form();
resource.getRequestAttributes().put("org.restlet.http.headers", headers);
}
...
headers.add(key, value);
The code works. Now, the customer HTTP header is defined as "Authorization". The above code seems not passing the header properly. And this is not challengeScheme involved.
I tested this scenario on SoapUI and Postman. Both work.
Anyone knows that restlet support this?
In fact, you can't override standard headers like Authorization with Restlet when doing a request.
If you want to provide a security token, you could use this approach:
String pAccessToken = "some token";
ChallengeResponse challengeResponse = new ChallengeResponse(
new ChallengeScheme("", ""));
challengeResponse.setRawValue(pAccessToken);
clientResource.setChallengeResponse(challengeResponse);
This way you'll have only the token in the Authorization header (with a space at the beginning - so don't forget to trim the value).
I am using the JsonServiceClient client to talk to a RESTful service hosted on IIS 7 by an external vendor.
Here is some sample code I am using to call their Get method.
ServiceStack.ServiceClient.Web.JsonServiceClient client = new ServiceStack.ServiceClient.Web.JsonServiceClient("UrlToVendor"));
client.SetCredentials("userName", "password");
client.AlwaysSendBasicAuthHeader = true;
DTOReturn result = client.Get<DTOReturn>(string.Empty);
I always get an authorization failure. We put a sniffer and the Authorization header is being sent as:
basic userName:password
instead of
Basic userName:password
We were able to use standard .Net calls to get it to work
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(
"UrlToVendor");
string authInfo = "userName:password";
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
req.Accept = "application/json"; //text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
req.PreAuthenticate = true;
req.Method = "GET";
req.Headers["Authorization"] = string.Format("Basic {0}", authInfo);
System.Net.HttpWebResponse res = (System.Net.HttpWebResponse)req.GetResponse();
And these standard calls failed the same as the JasonServiceClient if we changed "Basic" to "basic".
Any suggestions?
Looks like someone had the same problem. This recent commit changed the auth-scheme from "basic" to "Basic". https://github.com/ServiceStack/ServiceStack/commit/d4f21c5355ab87d7315e142372eef9a40e096b5f
You should be able to just update your dlls.
According to RFC 2617 sec 1.2 the auth-scheme is case-insensitive.
See https://www.rfc-editor.org/rfc/rfc1945#page-47. I would be curious as to why the vendor service won't accept it.