HTTP response code: 411 for LinkedIn with ApacheOltu - oauth-2.0

Looking at the https://developer.linkedin.com/docs/oauth2 I try here to get an access token.
What can be wrong with this piece of code ?
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
TokenRequestBuilder r = OAuthClientRequest
.tokenLocation("https://www.linkedin.com/oauth/v2/accessToken")
.setCode(code)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(LinkedInClientID)
.setClientSecret(LinkedInClientSecret)
.setRedirectURI("http://localhost:8080/authenticatedLinkedIn");
Map<String,String> m = new HashMap<String,String>();
m.put("Content-Type", "application/x-www-form-urlencoded");
int bodyLength = r.buildBodyMessage().getBody().length();
System.out.println("Body l = " + bodyLength);
m.put("Content-Length", Integer.toString(bodyLength));
r.buildHeaderMessage().setHeaders(m);
OAuthClientRequest request = r.buildQueryMessage();
OAuthJSONAccessTokenResponse tk = oAuthClient.accessToken(request, OAuth.HttpMethod.POST);
I get the following error :
Server returned HTTP response code: 411 for URL:
https://www.linkedin.com/oauth/v2/accessToken?code=AQSZfSXpQ6z3575474fhfbZmxJQofGiwtpw53Y1FnlALvKBWJgQKfJH8kvHM-3f5ZtOqndit594S2cmZrFuiNaXcBOHuSf8yMgFgr4uh-a40Ag&grant_type=authorization_code&client_secret=gHPiGTTyb1KKHPEP&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2FauthenticatedLinkedIn&client_id=86txkd469mat

You need to send a POST request with params in body urlenconded... so
First change:
OAuthClientRequest request = r.buildQueryMessage();
With:
OAuthClientRequest request = r.buildBodyMessage();
Then you do not need to put any header Oltu will manage this for U.
Hope it will help.

Related

QuickBooks Authentication error when getting basic company information

I'm writing a simple desktop application to get information from QuickBooks(developer account using demo account(UK) data) and in this regard I've been able to go past the OAuth flow. However, I've not been able to get the basic company information
The below is a capture of the Fiddler request and response:
GET https://quickbooks.api.intuit.com/v3/company/123145829830639/companyInfo/123145829830639 HTTP/1.1
Authorization: oauth_token="****", oauth_nonce="z4x0a196", oauth_consumer_key="****", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1499283607", oauth_version="1.0", oauth_signature="EGw6Ty%2BKFAawrH1%2FSxQuFwaMcEo%3D"
Content-Type: application/json
Host: quickbooks.api.intuit.com
The generation of the header is similar to https://developer.intuit.com/v2/apiexplorer?apiname=V3QBO#?id=CompanyInfo but I end up getting the following response(Fiddler partial response) based on the request
intuit_tid: gw-c4e19f89-df78-42a5-ae7e-216187421143
Set-Cookie: JSESSIONID=21BF1FFEE48B39538E82485FD25C4280.c51-pprdsbxas901; Path=/; Secure; HttpOnly
QBO-Version: 1706.912
ErrorCode: 100
ErrorCause: AuthenticationErrorGeneral: SRV-110-Authentication Failure , statusCode: 401
Message: General Authentication Error
The code to access company information is as below:
string companyInfo = String.Format("company/{0}/companyInfo/{0}", authenticator.OAuthProfile.realmId);
string ciUrl = BASE_URL + companyInfo; //https://quickbooks.api.intuit.com/v3/
var sb = new System.Text.StringBuilder();
sb.AppendFormat("oauth_token=\"{0}\", oauth_nonce=\"{1}\", oauth_consumer_key=\"{2}\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"{3}\", oauth_version=\"1.0\", oauth_signature=\"{4}\"",
Manager.UrlEncode(_token),
Manager.UrlEncode(_nonce),
Manager.UrlEncode(_consumer_key),
Manager.UrlEncode(_timestamp),
Manager.UrlEncode(_signature));
var authorisationHeader = sb.ToString().TrimEnd(' ').TrimEnd(',');
// Request Company Information
var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(ciUrl);
request.Headers.Add("Authorization", authorisationHeader);
request.Method = "GET";
request.ContentType = "application/json";
using (var response = (System.Net.HttpWebResponse)request.GetResponse())
{
// get 401
}
Used sandbox URL and added minorversion to the base URL
I attempted setting BASE_URL set to the sandbox url(https://sandbox-quickbooks.api.intuit.com/v3) and also set minorversion to be 4.
Any help is much appreciated.
Hopefully this helps, but here is a Java snippet using their SDK that works for me:
OAuthAuthorizer oauth = new OAuthAuthorizer(System.env.QB_OAUTH_CONSUMER_KEY, System.env.QB_OAUTH_CONSUMER_SECRET,
vendor.intuitOAuthAccessToken, vendor.intuitOAuthAccessSecret);
UUID trackingID = UUID.randomUUID()
log.info("About to init Context companyID=" + vendor.realmId + ", app_token=" + System.env.QB_APP_TOKEN + ", uuid=" + trackingID.toString())
Context context = new Context(oauth, System.env.QB_APP_TOKEN, ServiceType.QBO, vendor.realmId)
context.setMinorVersion("4")
context.setTrackingID(trackingID)
log.info("About to set BaseURL")
Config.setProperty(Config.BASE_URL_QBO, System.env.QB_BASE_URL + "/v3/company");
log.info("About to init DataService")
// get all customers
log.info("About to executeQuery")
DataService service = new DataService(context)
QueryResult queryResult = service.executeQuery("select * from customer");
In my case, QB_BASE_URL=https://sandbox-quickbooks.api.intuit.com
*NOTE there isn't a trailing slash
vendor.intuitOAuthAccessToken and vendor.intuitOAuthAccessSecret are the values you get back after the oauth flow

OAuth 1.0 A Invalid Signature when requesting request token (SalesForce/JIRA Integration)

I've been trying my darndest to avoid asking a question. I'm recieving an invalid signature error when trying to request a request token from JIRA from within Salesforce. The response I'm getting is:
08:15:24:201 USER_DEBUG [30]|DEBUG|
oauth_problem=signature_invalid
&oauth_signature=RaOPaBPznmS7aDUuJN1pOclcyHWP4uRYYx4j%2F%2BdtKB1SD4l1JcCCys3P3RAa8P7377MwLsIMBtkHfL62jaXr5LV30RndjVUSlCsVl3h47CvinHgDtTMwWGukQJXhOmSsLPvccCqD7qsRmiQnnjSJCwd9YKJEi2cxNcwMqhnceqAwJdzn3RD%2FBBeNpf3G97wqWhJx%2FtyEhQGk35OTu00fhtw%2BIX025STN3iiGNbyANlmoImAGWqAJeqJOPUVva7TR2OAInysL9%2BHmYkQTOcb7a9sn5rRWUqE4Jua6EoVyPgzJnSgZ4pFEIMzU0eTWQqhSFdQwOdnoq5EQU8W%2BPJM8uA%3D%3D
&oauth_signature_base_string=POST%26https%253A%252F%252F.atlassian.net%252Fplugins%252Fservlet%252Foauth%252Frequest-token%26oauth_consumer_key%253D3MVG9KI2HHAq33RwCPH5bNzAHbOgfiicjJ6HjvVfNhGU8aWXGl6ps.vsEzobCPqRXuDcmeV2Baw%25253D%25253D%2526oauth_nonce%253D-6826921263934288296%2526oauth_signature_method%253DRSA-SHA1%2526oauth_timestamp%253D1492182924
&oauth_signature_method=RSA-SHA1
The code I'm using to try to generate the signature is:
// GitHub OAuth Playground: https://github.com/jesperfj/sfdc-oauth-playground/blob/master/OAuth/src/classes/OAuth.cls
// OAuth Bible: http://oauthbible.com/
// Static Values
String consumerKey = '3MVG9KI2HHAq33RwCPH5bNzAHbOgfiicjJ6HjvVfNhGU8aWXGl6ps.vsEzobCPqRXuDcmeV2Baw==';
String endpoint = 'https://<AtlassianSiteName>.atlassian.net/plugins/servlet/oauth/request-token';
// Params
String callbackParam = '&oauth_callback=' + EncodingUtil.urlEncode('https://localhost/', 'UTF-8');
String consumerKeyParam = '&oauth_consumer_key=' + EncodingUtil.urlEncode(consumerKey, 'UTF-8');
String signatureMethodParam = '&oauth_signature_method=RSA-SHA1';
String timestampParam = '&oauth_timestamp=' + String.valueOf(DateTime.now().getTime()/1000);
String nonceParam = '&oauth_nonce=' + String.valueOf(crypto.getRandomLong());
String versionParam = '&oauth_version=1.0';
String paramString = consumerKeyParam + nonceParam + signatureMethodParam + timestampParam + versionParam + callbackParam;
// Get baseString
String baseString = 'POST&' + encodingUtil.urlEncode(endpoint, 'UTF-8') + paramString;
system.debug(baseString);
blob sig = crypto.signWithCertificate('RSA-SHA1', blob.ValueOf(baseString), 'SelfSignedCert_26Oct2015_184625');
String signature = EncodingUtil.urlEncode(EncodingUtil.base64encode(sig), 'UTF-8');
httpRequest req = new httprequest();
http http = new http();
req.setEndPoint(endpoint);
req.setMethod('GET');
req.setBody(paramString +
'&oauth_signature=' + signature);
httpresponse res = http.send(req);
system.debug(res.getBody());
Note: Yes I understand that I probably shouldn't be sharing some of this information but these are my personal test orgs that contain nothing important and I'm not providing the SSL used. You'll notice some comments at the top of my code containing a few urls to my favorite resources that have gotten me this far. These are not the only resources I've used, just the most useful ones.

Post with Robospice and okHttp

I perform a POST using Robospice and okHttp :
public String loadDataFromNetwork() throws Exception {
uriBuilder = Uri.parse(url).buildUpon();
uri = new URI(uriBuilder.build().toString());
tmp = "user=" + user + "&password=" + pwd
HttpURLConnection connect = new OkUrlFactory(client).open(uri.toURL());
// Send post request
connect.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(connect.getOutputStream());
wr.writeBytes(tmp);
wr.flush();
wr.close();
// Read the response
in = connect.getInputStream();
}
Is there a better way to send a post (with Robospice/okHttp) ?
NB : my code is working fine, just want to know if it's correct or not...
The problem is that if I want to use the okHttp POST like that :
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.github.com/markdown/raw")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, parameters))
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
with Robospice, RequestBody and newCall and isSuccessful cannot be resolved !
Do I have a solution to use okHttp post WITH Robospice ? (I know how to make a GET, but not a POST...)

Connecting to Twitter - RestSharp OAuth2

I am attempting to connect to the Twitter API with these instructions
https://dev.twitter.com/docs/auth/application-only-auth
Here is my code:
var baseUrl = "http://api.twitter.com/";
var client = new RestClient(baseUrl);
var request = new RestRequest("/oauth2/token", Method.POST);
var concat = ConfigurationManager.AppSettings["TwitterConsumerKey"] + ":" +
ConfigurationManager.AppSettings["TwitterConsumerSecret"];
string encodeTo64 = concat.EncodeTo64();
request.AddHeader("Authorization", "Basic " + encodeTo64);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
request.AddBody("grant_type=client_credentials");
IRestResponse restResponse = client.Execute(request);
EncodeTo64
static public string EncodeTo64(this string toEncode)
{
byte[] toEncodeAsBytes
= System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
string returnValue
= System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
Response.Content is the following
"{\"errors\":[{\"code\":170,\"label\":\"forbidden_missing_parameter\",\"message\":\"Missing required parameter: grant_type\"}]}"
Is this part wrong?
request.AddBody("grant_type=client_credentials");
I have verified that my credentials are correct (I got that error before, but resolved it, so it should be OK).
The instructions on the Twitter page confused me. "The body of the request must be grant_type=client_credentials."
As for Restsharp, it's not AddBody, but AddParameter.
So:
request.AddParameter("grant_type", "client_credentials");

Google Places API: Adding a new Place: Java/Groovy

Can't get the POST working? What's wrong?
Note: This works for a GET with autocomplete
GET works without signing the url
I'm following the Web services steps to Sign the URL with my "API Key"
Docs say"client id" still?
http://code.google.com/apis/maps/documentation/webservices/
2.Try sending the POST data with the signed URL (tried the unsigned signature aswell)
def signedUrl = "https://maps.googleapis.com/maps/api/place/add/json?key=xxxxxkeyxxxxxx&sensor=false&signature=xxxxxxxxxxsignaturexxxxxx"
String postData = "{'location': { 'lat': '-33.8669710','lng': '151.1958750'},'accuracy': '50','name': 'Google Shoes!'}"
URL urlPost = new URL(signedUrl);
URLConnection connection = urlPost.openConnection();
connection.addRequestProperty("Referer", "http://www.mysite.com");
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("CONTENT-TYPE", "text/json");
connection.setRequestProperty("CONTENT-LENGTH", postData.length() + "");
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(postData);
out.close();
String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while((line = reader.readLine()) != null) {
builder.append(line);
}
JSONObject json = new JSONObject(builder.toString());
println json
Returns a 403
"java.io.IOException: Server returned HTTP response code: 403 for URL:"
Simular to the "Java Access"section under they give an example of a GET
http://code.google.com/apis/websearch/docs/#fonje
Ok solved.
No signing the URL required
postData string was wrong
should have been
String postData = "{\"location\": { \"lat\": -33.8669710,\"lng\": 151.1958750},\"accuracy\": 50,\"name\": \"Google Shoes!\", \"types\":[\"bar\"]}"

Resources