LinkedIn API failed to connect when trying to get companies informations - c#

When I try to get profile information, using HttpWebRequest, it works perfectly, it returns the response I need.
But when I try to get company informations, the LinkedIn web service returns the following error.
{ "errorCode": 0,
"message": "Unknown authentication scheme",
"requestId": [RequestID],
"status": 401,
"timestamp": 1479383163405 }
I used the same access token in both queries. And I can't figure why I have a failed authentication in the second query.
There are the 2 functions :
//Get profile :
private void GetPeopleProfile(string accessToken) {
var peopleUrl = String.Format("https://api.linkedin.com/v1/people/~?oauth2_access_token={0}&format=json",accessToken);
HttpWebRequest webRequest = WebRequest.Create(peopleUrl) as HttpWebRequest;
StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
string responseData = responseReader.ReadToEnd();
JObject updates = JObject.Parse(responseData);
responseReader.Close();
webRequest.GetResponse().Close();
}
//Get profile's Company :
private void GetUserCompanies(string accessToken){
var copaniesUrl = String.Format("https://api.linkedin.com/v1/companies?format=json&is-company-admin=true?oauth2_access_token={0}&format=json", accessToken);
HttpWebRequest webRequest = WebRequest.Create(copaniesUrl) as HttpWebRequest;
StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream());
string responseData = responseReader.ReadToEnd();
JObject updates = JObject.Parse(responseData);
responseReader.Close();
webRequest.GetResponse().Close();
}

Maybe wrong URL?
Parameters separators are wrong here (two ? in a URL seems wrong, you are also repeating format=json) :
"https://api.linkedin.com/v1/companies?format=json&is-company-admin=true?oauth2_access_token={0}&format=json"
This looks better:
"https://api.linkedin.com/v1/companies?format=json&is-company-admin=true&oauth2_access_token={0}"
You can try the REST api here without your code noise.

It seems that the Linkedin API now expects an authorization HTTP header instead of a querystring parameter oauth2_access_token.
This is accomplished by including an "Authorization" header in your HTTP call to LinkedIn's API.
https://developer.linkedin.com/docs/oauth2
Try this and remove the access token from the querystring:
webRequest Headers.Add("Authorization", "Bearer " + accessToken);

Related

OneLogin Create Session Login Token API returns status 400 with message: Bad Request

I am developing a C# application which needs to use the onelogin API to retrieve a session token. I am able to authenticate and and create a token with the following code:
WebRequest Authrequest = WebRequest.Create("https://api.us.onelogin.com/auth/oauth2/token");
Authrequest.Method = "POST";
Authrequest.ContentType = "application/json";
Authrequest.Headers.Add("cache-control", "no-cache");
Authrequest.Headers.Add("Authorization: client_id:XXXXXXX7bbf2c50200d8175206f664dc28ffd3ec66eef0bfedb68c3366420dc, client_secret:XXXXXXXXXX6ba2802187feb23f6450c6812b8e6639361d24aa83f12010f ");
using (var streamWriter = new StreamWriter(Authrequest.GetRequestStream()))
{
string Authjson = new JavaScriptSerializer().Serialize(new
{
grant_type = "client_credentials"
});
streamWriter.Write(Authjson);
}
WebResponse AuthReponse;
AuthReponse = Authrequest.GetResponse();
Stream receiveStream = AuthReponse.GetResponseStream ();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader (receiveStream);
JObject incdata = JObject.Parse(readStream.ReadToEnd());
string sToken = incdata["data"][0]["access_token"].Value<string>();
AuthReponse.Close();
However, when running the Create Session Login Token with the following code, it only returns a 400 error, and the message has no detail. Just Bad Request:
//Get the session token for the specified user, using the token recieved from previous web request
WebRequest request = WebRequest.Create("https://api.us.onelogin.com/api/1/login/auth");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("authorization", "bearer:" + sToken);
using (var streamWriter2 = new StreamWriter(request.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(new
{
username_or_email = sUsername,
password = sPassword,
subdomain = "comp-alt-dev"
});
streamWriter2.Write(json);
}
WebResponse response;
response = request.GetResponse();
string streamText = "";
var responseStream = response.GetResponseStream();
using (responseStream)
{
var streamReader = new StreamReader(responseStream);
using (streamReader)
{
streamText = streamReader.ReadToEnd();
streamReader.Close();
//
}
responseStream.Close();
}
Any ideas?
-Thank you
Also for anyone who may be getting this error. in C# the email is case sensitive. I tried User.email.com. In onelogin it was saved as user#email.com. changing the c# to lower case fixed it.
Can you let us know what payload you're sending across the wire to the .../1/login/auth endpoint as well as the response (either as others have suggested as packet snoop, or just as a debug output from the code)
400 means either bad json or the endpoint requires MFA, so this will narrow it down.
~thanks!
Just joining the troubleshooting effort =) -- I can replicate a 400 Bad Request status code with a "bad request" message when the request body contains a username_or_email and/or subdomain value that does not exist, or if the request body is empty.
Can you post what goes over the wire to the OneLogin endpoint...
OK Thanks. So it appears your subdomain does not exist. If you give me an email in the account I can find the correct subdomain value for you.

Calling Eventbrite API from .Net results in 401

I am trying to retrieve an order from the Eventbrite API. I have a valid OAuth token and order number. I have verified this by using postman which successfully returns the correct JSON.
However when I make the call using the following c# code, I get a 401 Unauthorised:
var client = new HttpClient();
var req = new HttpRequestMessage(HttpMethod.Get, "https://www.eventbriteapi.com/v3/orders/{orderNo}");
req.Headers.Add("Authorization", "Bearer {authToken}");
var response = await client.SendAsync(req);
I've tried replacing the header with:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("{authToken}");
I have also tried:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.eventbriteapi.com/v3/orders/{orderNo}");
request.Headers.Add("Authorization", "Bearer {authToken}");
request.Accept = "application/json";
using(WebResponse response = request.GetResponse())
{
using(Stream dataStream = response.GetResponseStream())
{
using(StreamReader reader = new StreamReader(dataStream))
{
string responseFromServer = reader.ReadToEnd();
}
}
}
All of these get a 401 response.
I know the authtoken and the eventid are correct, so there must be something wrong with my code.
Am I doing something wrong with the authroisation token?
Have you tried ?token={authToken} option on the EventBrite API?
This would at least confirm if it's a problem with the way the header is being sent across.
http://developer.eventbrite.com/docs/auth/
You omitted the trailing '/' in the URL, which caused a subsequent redirect from "eventbriteapi.com/v3/orders/{orderNo}" to "eventbriteapi.com/v3/orders/{orderNo}/". The authorization header was dropped in the redirect.

Can't access Web of Trust (WoT) API w/ JSON.Net

I'm new to JSON & am using VS 2013/C#. Here's the code for the request & response. Pretty straightforward, no?
Request request = new Request();
//request.hosts = ListOfURLs();
request.hosts = "www.cnn.com/www.cisco.com/www.microsoft.com/";
request.callback = "process";
request.key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string output = JsonConvert.SerializeObject(request);
//string test = "hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create("http://api.mywot.com/0.4/public_link_json2?);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = output;
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
MessageBox.Show(e.ToString());
}
//response = true.
//no response = false
return true;
}
When I run this, I get a 405 error indicating method not allowed.
It seems to me that there are at least two possible problems here: (1) The WoT API (www.mywot.com/wiki/API) requires a GET request w/ a body, & httpWebRequest doesn't allow a GET in the httpWebRequest.Method; or (2) the serialized string isn't serialized properly.
NOTE: In the following I've had to remove the leading "http://" since I don't have enough rep to post more than 2 links.
It should look like:
api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx
but instead looks like:
api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}.
If I browse to:api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx; I get the expected response.
If I browse to: api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}; I get a 403 denied error.
If I hardcode the request & send as a GET like below:
var httpWebRequest = (HttpWebRequest) WebRequest.Create("api.mywot.com/0.4/public_link_json2? + "test"); it also works as expected.
I'd appreciate any help w/ this & hope I've made the problem clear. Thx.
Looks to me like the problem is that you are sending JSON in the URL. According to the API doc that you referenced, the API is expecting regular URL encoded parameters (not JSON), and it will return JSON to you in the body of the response:
Requests
The API consists of a number of interfaces, all of which are called using normal HTTP GET requests to api.mywot.com and return a response in XML or JSON format if successful. HTTP status codes are used for returning error information and parameters are passed using standard URL conventions. The request format is as follows:
http://api.mywot.com/version/interface?param1=value1&param2=value2
You should not be serializing your request; you should be deserializing the response. All of your tests above bear this out.

LinkedIn - How to get access token?

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 :)

Why is the google server returning error 401 when trying to get token?

i'm currently trying to develop an api for google reader and when i'm trying to get the token, the following error is being generated:
System.Net.WebException: The remote server returned an error: (401) Unauthorized.
at System.Net.HttpWebRequest.GetResponse()
first i'm getting the session... and this works perfectly. then the following method i being called to get the token:
public String setToken()
{
HttpWebResponse response;
HttpWebRequest request;
cookie = new Cookie("SID", this.sessionID, "/", ".google.com");
String url = "http://www.google.com/reader/api/0/token";
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(this.cookie);
response= (HttpWebResponse)request.GetResponse();
using (var stream = response.GetResponseStream())
{
StreamReader r = new StreamReader(stream);
this.token = r.ReadToEnd();
}
return this.token;
}
the exception is being generated in this line:
response= (HttpWebResponse)request.GetResponse();
does anyone know what might be causing this error please?
PS. I read the question : Why am I getting a 401 (Unauthorized) error when POSTing to Google Reader API? however he was getting this error when he tried to post.
Google has changed, according to Eric Mann:
"As it turns out, Google has changed the authentication portion of the Reader API. Now, instead of passing the SID in a cookie when you make a request, you set an authentication header with the “Auth” key originally passed with the SID."
Source

Categories

Resources