i am currently try to get information of an external API using RestSharp (Version 107.1.2). Unfortunately, in every request I get response Status Code 403 "Forbidden". I now have contact to the provider and he told me, to delete all cookies first and then add the cookie "SMCHALLENGE=YES".
I tried this in RestSharp, but when using the client.AddCookie extension, I receive ArgumentException. I now found another option, to add the cookie in header, but this doesn't work either.
Do you have an idea, how to delete all cookies and then add the SMCHALLENGE cookie?
var client = new RestClient("https://test.de/api/token");
string resource = null;
client.Authenticator = new HttpBasicAuthenticator("testUser", "testPW");
string apiKey = null;
var request = new RestRequest(resource, Method.Get);
//Following execution throws System.ArgumentException: "The {0} parameter cannot be an empty string. Parameter name: cookie.domain"
//client.AddCookie("SMCHALLENGE", "YES");
request.AddHeader("Cookie", "SMCHALLENGE=YES");
var response = client.ExecuteAsync(request);
response.Wait();
RestResponse rr = response.Result;
Thank you very much!
Cookies aren't headers. You need to add your cookies to the RestClient own cookie container. Cookies that are returned in the response will also be available in the cookie container. There's a function on RestClient to do that as a shortcut.
var client = new RestClient("https://test.de/api/token");
client.AddCookie("SMCHALLENGE", "YES");
You can also work with the cookie container:
client.CookieContainer.Add(new Cookie(...));
You'd need to avoid creating a new RestClient instance for each request. This way you'd also keep the cookies across requests.
Related
I am using GraphQL.client Nuget package to call the Graphql API which requires Content-Type header.
Following is what I am doing
Set GraphQL options. Note I have set options.MediaType
GraphQLHttpClientOptions options = new GraphQLHttpClientOptions();
options.MediaType = "application/json";
options.EndPoint = new Uri( "https://sample.api.com/graphql");
Initialize the client and Authorization header
var graphQLClient = new GraphQLHttpClient(options, new NewtonsoftJsonSerializer());
graphQLClient.HttpClient.DefaultRequestHeaders.Add("Authorization", "JWT <token>");
GraphQL query
var projectsQuery = new GraphQLRequest
{
Query = #"
query {
projects {
name
}
}"
};
Invoke the API and retrieve the response results
var graphQLResponse = await graphQLClient.SendQueryAsync<ProjectResponse>(projectsQuery);
var projects = graphQLResponse.Data.Projects;
However I am getting Bad request with error "{"errors":[{"message":"Must provide query string."}]}"
What am I doing wrong here? How do I set the content-type header correctly. I tried adding the content-type header as below but it does not allow giving the
Misused header name. Make sure request headers are used with
HttpRequestMessage, response headers with HttpResponseMessage, and
content headers with HttpContent objects.
graphQLClient.HttpClient.DefaultRequestHeaders.Add("content-type", "application/json");
I tried searching for a solution but did not find one. The same request works when I pass content-type header in the request headers via Postman client.
Does anybody have any pointer on the same?
If anyone is still looking for answer, please find below.
var graphQLClient = new graphQLHttpClient("https://www.example.com/graphql", new NewtonsoftJsonSerializer());
graphQLClient.HttpClient.DefaultRequestHeaders.Add("key", "value");
Please mind the HttpClient in graphQLClient.HttpClient.DefaultRequestHeaders.Add("key", "value");
I want to get cookies "Request Header" not "Reponse Header" of links "https://www.udemy.com/join/login-popup/"
I have used WebRequest and HttpClient but when I did not see Cookie debug in it
Please help me write it in C # I find trying to find every possible way but I still have not found.
Using System.Net.Http.HttpClient for example, we can get cookies like following:
var myClientHandler = new HttpClientHandler();
myClientHandler.CookieContainer = new CookieContainer();
var client = new HttpClient(myClientHandler);
var response = await client.GetAsync("https://www.udemy.com/join/login-popup/");
var cookieCollection = myClientHandler.CookieContainer.GetCookies(new Uri("https://www.udemy.com/join/login-popup/"));
foreach (var cookie in cookieCollection.Cast<Cookie>())
{
Debug.WriteLine(cookie);
}
HttpClient saves cookies that are sent by a server and automatically add them to subsequent requests to that URI within the same app container. So if we didn't modify cookies manually, the cookies in "Request Header" should be the same as what returned in previous reponse.
I can get an access token of Office 365. I can not make a REST request (GET) attaching this token in the header.
I'm using this code:
RestClient client = new RestClient();
client.EndPoint = #"https://outlook.office365.com/api/v1.0/me/folders/inbox/messages?$top=10";
client.Method = HttpVerb.GET;
client.ContentType = "application/json";
client.PostData = "authorization: Bearer " + myAccesToken.ToString();
String json = client.MakeRequest();
I've tested the access token in http://jwt.calebb.net and it's ok.
But it's always returning:
The remote server returned an error: (400) Bad Request.
I'm kind a knewby to REST and my english is not that good... Sorry! :)
(RE)EDIT
I've tried with RestSharp and I've simplified a bit my code...
Now I'm using my access token to make the GET request.
How do I add the "authorization bearer" to my request?
Is it like this?
//Ask for the token
var client = new RestClient("https://login.windows.net/common/oauth2/token");
var request = new RestRequest(Method.POST);
request.AddParameter("grant_type", "authorization_code");
request.AddParameter("code", Request.QueryString["code"]);
request.AddParameter("redirect_uri", myRedirectUri);
request.AddParameter("client_id", myClientID);
request.AddParameter("client_secret", myClientSecret);
IRestResponse response = client.Execute(request);
string content = "[" + response.Content + "]";
DataTable dadosToken = (DataTable)JsonConvert.DeserializeObject<DataTable>(content);
//I don't need a DataTable, but it was a way to retrieve my access token... :)
//Ask for info with the access token
var client2 = new RestClient("https://outlook.office365.com/api/v1.0/me");
var request2 = new RestRequest(Method.GET);
request2.AddHeader("authorization", myToken.ToString());
//I've tried this way also:
//client2.Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(dadosToken.Rows[0]["access_token"].ToString(), "Bearer");
IRestResponse response2 = client2.Execute(request2);
string content2 = "[" + response2.Content + "]";
Response.Write(content2); //this returns NOTHING!
Thanks again!
You can also use Fiddler to figure out if the Request is well formed.
Try a simpler endpoint first like: https://outlook.office365.com/api/v1.0/me
and check if the right data comes back. You can call this endpoint just from the browser and also look at the request/respond inside Fiddler.
The first thing to check: Is it a bad request. This usually means the method can't be found or the given parameters cannot be located. Check the deploy and make sure it is the most up to date version and also check that your server is actually running.
I am trying to pass username and password to the following URL :
https://maxcvservices.dnb.com/rest/Authentication
According to the documentation the user_id and password must be passed as headers with the keys: x-dnb-user, x-dnb-pwd respectively.
I thus far have the following code which seems to work but I am unable to retrieve the auth token returned by the response object:
public static void Main (string[] args)
{
var client = new RestClient ("https://maxcvservices.dnb.com/rest/Authentication");
var request = new RestRequest (Method.POST);
request.AddHeader("x-dnb-user", myEmail);
request.AddHeader("x-dnb-pwd", myPassword);
IRestResponse resp = client.Execute(request);
var content = resp.Content;
Console.WriteLine (resp.StatusDescription);
Console.WriteLine (resp.StatusCode);
}
When I try printing the content I get a blank line but what I am actually expecting is the auth token that is returned by the service. A couple of things I think I am doing in the code (but not sure), is passing the userid and password as headers in the POST request which is what is required. The token is returned as the value of the 'Authorization' field in the response object. I was wondering how I might print the token. Also the statusDescription,statusCode both print OK which tells me I have the correct request but am unable to locate the auth token in the response. Any help would be much appreciated in guiding me on how to access the auth token in the Authorization field of the returned POST response.
So you're trying to get the HttpHeader values for Authorization from the IRestResponse object?
You could use e.g. use LINQ for that:
var authroizationHeaderFromResponse = resp.Headers.FirstOrDefault(h => h.Name == "Authorization");
if (authroizationHeaderFromResponse != null)
{
Console.WriteLine(authroizationHeaderFromResponse.Value);
}
Which yields
INVALID CREDENTIALS
You assume that if the response status code is 200 - OK, then there must be a response body accompanying it.
Does the documentation specifically state that you should expect a token in the response body in return?
The D&B developers could send a 200 - OK response with no response body if they want, or they can add their serialized token (JSON, XML etc) elsewhere, e.g. in a header field.
An example of this can be seen in this code from an ASP.NET Web API returning a response from a successful PUT
if (result.Success)
{
var dto = Mapper.Map<TEntity, TDto>(result.Data as TEntity);
var response = Request.CreateResponse(HttpStatusCode.Created, dto);
var uri = Url.Link("DefaultApi", new {id = dto.Id});
response.Headers.Location = new Uri(uri);
return response;
}
This would return a 200 - OK with a serialized object (result.Data) in the response body, but there's nothing wrong with me changing the following
var response = Request.CreateResponse(HttpStatusCode.Created, dto);
To something like
var response = Request.CreateResponse(HttpStatusCode.Created);
That way you would still get a 200 - OK response, but without a response body. This of course is against the recommendations of the HTTP/1.1 Standard for PUT verbs, but it would still work.
I could even do this for giggles
throw new HttpResponseException(HttpStatusCode.Created);
And you would still get a 200 - OK response. Somewhat evil, but possible.
I would suggest trying to fetching data from another resource with the x-dnb-user and x-dnb-pwd header fields set, and check if a response body is returned then. Perhaps D&B was inspired by Basic Authentication when implementing these header fields, and as such require them to be present in every request?
It's worth a try.
Let me know how that works out.
Look in the Headers collection of IRestResponse. It will probably be there rather than the content.
Hth
Oli
It could be that the AUTHTOKEN comes back with the cookies, as this is a common approach.
In this case, you'll need to attach a CookieContanier to your IRestClient, then this container will store the cookies. Provided you use the same client for subsequent requests, that auth cookie will let you in.
private CookieContainer _cookieJar;
...
_cookieJar = new CookieContainer();
_client.CookieContainer = _cookieJar;
You can then inspect the container after a request
_client.PostAsync(MyRequest, (r, h) =>
{
r.Cookies... // inspect em
I'm trying to get access token from LinkedIn.
I'm follwing this URL https://developer.linkedin.com/documents/authentication
I am able to get an authorization code.
But when I'm passing the authorization code to this URL
https://www.linkedin.com/uas/oauth2/accessToken?grant_type=authorization_code &code=AUTHORIZATION_CODE &redirect_uri=YOUR_REDIRECT_URI &client_id=YOUR_API_KEY &client_secret=YOUR_SECRET_KEY
I get an error in the below format
{"error":"invalid_request","error_description":"missing required parameters, includes an invalid parameter value, parameter more then once. : Unable to retrieve access token : appId or redirect uri does not match authorization code or authorization code expired"}
Any ideas? Thanks in advance.
This is because authorization code expires in 20 seconds. So you have to get the Access Token within that time frame.
I got the same error as you. I also met the following conditions:
My request was a POST request.
My redirect_uri's were the same in /authorization and /accessToken calls.
The /accessToken call was executed immediately after receiving the authorization code, so
it wouldn't expire.
What finally did the trick for me was revoking the access token generated on the application details page on https://www.linkedin.com/secure/developer.
This is an access token for oAuth 1.a and is not compatible with oAuth 2.0 on which the linkedIn api is currently running.
After revoking this access token I was able to get a new one with the /authorization and /accessToken calls.
I see this is an older thread, however if it will help anyone, here is my working solution, working on MVC core 2.0 as of december 2018:
first, redirect to LinkedIn like this
var url = "https://" + Request.Host + "/Login/LoginLinkedIn";
url = WebUtility.UrlEncode(url);
var redirectLinkedIn = "https://www.linkedin.com/oauth/v2/authorization?response_type=code&client_id=*ClientId*&client_secret=*ClientSecret*&redirect_uri=" + url + "&state=*random required nummeric value*";
return Redirect(redirectLinkedIn);
after that, you will receive the answer in your Login/LoginLinkedIn action (don't forget to specify this path in your app settings Authorized Redirect URLs).
There you will use this private method to get a dynamic object filled with user data
private dynamic GetLinkedInUser(string code)
{
dynamic jresult;
NameValueCollection parameters = new NameValueCollection {
{"client_id", *ClientId*},
{"client_secret", *ClientSecret*},
{"grant_type", "authorization_code"},
{"redirect_uri", "https://" + Request.Host + "/Login/LoginLinkedIn"},
{"code", code}
};
WebClient client = new WebClient();
byte[] result = client.UploadValues("https://www.linkedin.com/oauth/v2/accessToken", "POST", parameters);
string response = System.Text.Encoding.Default.GetString(result);
string accessToken = JsonConvert.DeserializeObject<dynamic>(response).access_token;
WebRequest webReq = WebRequest.Create("https://api.linkedin.com/v1/people/~:(id,email-address,first-name,last-name)?format=json");
webReq.Method = "GET";
webReq.Headers.Add("Authorization","Bearer "+accessToken);
HttpWebResponse webResponse = (HttpWebResponse)webReq.GetResponse();
using (StreamReader reader = new StreamReader(webResponse.GetResponseStream())) {
string objText = reader.ReadToEnd();
jresult = JsonConvert.DeserializeObject<dynamic>(objText);
}
return jresult;
}
hope it helps someone :)