OkHttp Post Body as JSON is throwing 404 - api

I recently moved into OKHTTP. I'm able to perform get request but while performing post i'm getting 404. Can someone help me out where I'm going wrong.
FYI:
auth token is correct & url is valid
public void PullRequest() throws IOException{
JSONObject jo = new JSONObject();
jo.put("head","patch-7");
jo.put("base","main");
MediaType JSON = MediaType.get("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jo.toString());
//RequestBody body = RequestBody.create(jo.toString(),JSON);
Request request = new Request.Builder()
.url(url)
.header("Authorization",authorization)
.post(body)
.build();
Call call = httpClient.newCall(request);
Response response = call.execute();
if (response.code()>300) {
System.out.println("error...");
System.out.println(response.body().string());
}else {
System.out.println(response.body().string());
}
}

Related

Requesting a API token with both basic authentication and application/x-www-form-urlencoded

I'm trying to create an application using MS Visual Studio in either vb.net or C# to receive a token for a web api that has both basic authentication and application/x-www-form-urlencoded. When I send the request from Postman the requested works. Please see Postman screen shots below. When is use the below code I receive and message "Request failed with status code NotFound" back and the request fails. Can any point in the the right direction to resolve this.
Thank you
Postman
postman body
`private void button1_Click(object sender, EventArgs e)
{
Uri baseurl = new Uri("https://api address/token");
RestClient client = new RestClient(baseurl);
//client.Timeout = -1;
RestRequest request = new RestRequest("post", Method.Post);
request.AddHeader("Authorization", "Basic M2U4Y");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("grant_type", "client_credentials",true);
request.AddParameter("scope", "https://?????????",true);
RestResponse response = client.Execute(request);
if (response.Content == "")
{
textBox1.Text = response.ErrorException.Message ;
}
else
{
textBox1.Text = response.Content;
}
}
`
I solved the problem. With the below code.
Uri baseurl = new Uri("https://api address/token");
RestClient client = new RestClient(baseurl);
RestRequest request = new RestRequest(baseurl, Method.Post);
request.AddHeader("Authorization", "Basic M2U4Y");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", "grant_type=client_credentials&scope=https://FED0C291",arameterType.RequestBody);RestResponse response = client.Execute(request);
if (response.Content == "")
{
textBox1.Text = response.ErrorException.Message ;
}
else
{
textBox1.Text = response.Content;
}

API test using RestSharp keeps returning 'Unauthorized Access, invalid API key'

I've been trying to figure this out for a couple of days now and that includes looking at similar posted questions but I can't seem to get it to work.
I am trying to post a request to retrieve a Token which I can then use for further API GET requests.
The request I am posting is the below:
[TestMethod]
public void GetToken()
{
var client = new RestClient(baseUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("Authorization", bearer, ParameterType.HttpHeader);
request.AddParameter("username", username);
request.AddParameter("password", password);
request.AddParameter("api_key", apiKey);
IRestResponse restResponse = client.Execute(request);
Console.WriteLine("Status code: " + (int)restResponse.StatusCode);
Console.WriteLine("Status message " + restResponse.Content);
}
When I run the request, I get the following:
Status code: 200
Status message {"content":null,"error":"Unauthorized Access, invalid API key","success":false}
I cannot figure out why I keep getting the invalid API Key value. In terms of all the variables I use, when I post the request in Postman, it works perfectly fine.
Ok, so I had a look at the code with a developer and turned out I needed to be passing in my apikey as part of the AddParameter value.
So my final code looked like:
[TestMethod]
public void GetToken()
{
var client = new RestClient(baseUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddParameter("Authorization", "Bearer " + apiKey, ParameterType.HttpHeader);
request.AddParameter("username", username);
request.AddParameter("password", password);
IRestResponse restResponse = client.Execute(request);
Console.WriteLine("Status code: " + (int)restResponse.StatusCode);
Console.WriteLine("Status message: " + restResponse.Content);
}

ModSecurity: Access denied with code 403 (phase 1) using woocomerce rest api

I am trying to use woocommerce rest api to update product stock quantity and price, using PUT Method, but after running the code, it gives me error:
Response Code 403 Forbidden. You don't have permission to access /wc-api/v2/products/15542
on this server.
I am using centos 6 server, i have commented on modsecurity_crs_30_http_policy.conf [id "960032"] by researching on web. but still it doesnt work.
public void updateStock() {
String nonce = RandomStringUtils.randomAlphanumeric(32);
Map<String, String> paramMap = new TreeMap<>();
paramMap.put("oauth_consumer_key", key);
paramMap.put("oauth_timestamp", "" + (System.currentTimeMillis() /
1000));
paramMap.put("oauth_nonce", nonce);
paramMap.put("oauth_signature_method", "HMAC-SHA1");
List<NameValuePair> qparams = new ArrayList<>();
for (Map.Entry<String, String> parameter : paramMap.entrySet()) {
qparams.add(new BasicNameValuePair(parameter.getKey(),
parameter.getValue()));
}
String encodedParams =
URLEncoder.encode(URLEncodedUtils.format(qparams, ENC), ENC);
String signature = getSignature("http://topvacuumparts.com/wc-
api/v2/products/15542", encodedParams, "PUT");
qparams.add(new BasicNameValuePair("oauth_signature", signature));
HttpClient httpclient = HttpClientBuilder.create().build();
URI uri = URIUtils.createURI("http", "topvacuumparts.com", -1, "wc-
api/v2/products/15542", URLEncodedUtils.format(qparams, ENC), null);
HttpPut httpget = new HttpPut(uri);
httpget.setHeader("X-Stream", "true");
httpget.setHeader("Content-Type", "application/json");
JSONObject obj = new JSONObject();
JSONObject ob = new JSONObject();
obj.put("stock_quantity", "20");
ob.put("product", obj);
StringEntity entity1 = new StringEntity(obj.toString());
httpget.setEntity(entity1);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
System.out.println("Response Code " +
response.getStatusLine().getStatusCode());
}
This is the Result:
Response Code 403
Json response
403 Forbidden
You don't have permission to access /wc-api/v2/products/15542
on this server

One Drive API returns invalid Access Token

The authentication process is not working now.(It was working earlier). By following the documentation I'm trying to get the access token from a refresh token. I successfully can get a access token. But it's not valid. I'm setting it as Bearer and send it in my GET request and it returns the following JSON
{"error":{"code":"accessDenied","message":"Access Denied"}}
Here is the code sample
String messageBody = "client_id=" + "9b1a6dbb-7e1f-41b5-b448-9f328169411e" + "&redirect_uri=" + returnURL + "&client_secret={cleindsecret}
+ "&refresh_token={refreshtoken}&grant_type=refresh_token";
RequestBody oAuthCodeRedeemBody = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"),
messageBody);
Request request = new Request.Builder().url("https://login.live.com/oauth20_token.srf")
.post(oAuthCodeRedeemBody).build();
String responseBody = null;
OkHttpClient client = new OkHttpClient();
client.setFollowRedirects(false);
Response response;
String accessToken = null;
try {
response = client.newCall(request).execute();
responseBody = response.body().string();
resp = (JSONObject) jsonParser.parse(responseBody);
} catch (IOException | ParseException e) {
e.printStackTrace();
}
accessToken = (String) resp.get("access_token");
I'm getting a Access Token here. But I can't use it to do any work.
Request request2 = new Request.Builder().url("https://api.onedrive.com/v1.0/drive/items/1ED8983F38E94F01!107/children").header("Authorization", "Bearer " + accessToken).get().build();
The response for the above code is returned as
{"error":{"code":"accessDenied","message":"Access Denied"}}
What is the reason here. Is the API returning me a invalid access token or is something wrong in my code?

dropbox access token for others to upload to my folder

I plan to have a server program fetching my dropbox account access token and pass to
client program to uplaod to my dropbox folder. Client does not need DB account or login and is able to send file to my DB folder (thus NOT using OAuth ...). Something similar to:
this
and this
but without user upload to server first, i.e., once user get the access token, they upload directly to DB.
I've tried to use Apache httpclient 4.3 to simulate a browser to perform getting request token, sending login-info to get acces token, but get stuck on upload the file via post to a form. Error is HTTP 400 Bad Request ...
executing request:GET https://www.dropbox.com/login HTTP/1.1
----------------------------------------
HTTP/1.1 200 OK
Request Token: moiejtzdLqTA_0sh3gQyNZAI
executing request:POST https://www.dropbox.com/login HTTP/1.1
----------------------------------------
HTTP/1.1 200 OK
Access Token: 5Ot52QKDbDPSsL1ApU4MIapJ
executing request:POST https://dl-web.dropbox.com/upload?
name=sample.jpg&dest=upload&cookie_t=5Ot52QKDbDP....SsJ&t=5Ot5...apJ HTTP/1.1
----------------------------------------
HTTP/1.1 400 Bad Request
I used Firefox LiveHttpHeader to capture the headers as I do the login and upload file, and saw the post to file upload actually is doing this (and reflect in the code):
https://dl-web.dropbox.com/chunked_upload?
name=tmp1.jpg
&chunk=0
&chunks=1
&bjar=W3sic2Vzc1..............Q%253D%253D
&blid=AAAw4tn................2cDxA
&cookie_t=32yq........nw6c34o
&dest=
&t=32yqVof........c34o
&reported_total_size=5611
&upload_id=1BKGRRP5TpCEjcWSu5tmpQ
&offset=0
So apparrently I missed some param but can't figure out what. The access token seems to be valid as I can see my account info in the return from a httpclinet post to https://www.dropbox.com/home, but the upload simply not working. Anyone has similar experience and getting HTTP 400 error ? .... Many Thanks !
Some code as below:
Constructor and main():
// constructor ...
public HttpClientExample() {
gcookies = new BasicCookieStore();
globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.BEST_MATCH)
.build();
// Create local HTTP context
ghttpContext = HttpClientContext.create();
ghttpContext.setCookieStore(gcookies);
//
redirectStrategy = new LaxRedirectStrategy(); // for http redirect ...
httpclient = HttpClients.custom()
.setDefaultRequestConfig(this.globalConfig)
.setDefaultCookieStore(this.gcookies)
.setRedirectStrategy(redirectStrategy)
.build();
} // constructor ...
public static void main(String[] args) throws Exception {
HttpClientExample myhttp = new HttpClientExample();
try {
this.localConfig = RequestConfig.copy(this.globalConfig)
.setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY)
.build();
String requestToken = this.getRequestToken(httpclient, loginurl);
theAccessToken = this.postForAccessToken(requestToken, loginurl);
String localFileTopassIn = this.localPath ;
this.postToUpload(httpclient, this.theAccessToken, localFileTopassIn , this.dropboxFolderOnlyName);
}
}
Get the request token:
private String getRequestToken(HttpClient client, String theURL) throws Exception {
HttpGet httpget = new HttpGet(theURL);
httpget.setConfig(localConfig);
httpget.setHeader("Connection", "keep-alive");
System.out.println("\nexecuting request:" + httpget.getRequestLine());
// Create a custom response handler
ResponseHandler responseHandler = new ResponseHandler() {
public String handleResponse(final HttpResponse response)
throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 ) { // && status cookies = gcookies.getCookies();
for (Cookie aCookie: cookies) {
String cookieName = aCookie.getName();
if ( !(cookieName.lastIndexOf(gvcString) == -1) ) {
gvc = aCookie.getValue();
} else if ( !(cookieName.lastIndexOf(tString) == -1) ) {
requestToken = aCookie.getValue();
}
}
System.out.println("Request Token: " + requestToken );
return requestToken;
}
postForAccessToken:
private String postForAccessToken(HttpClient client, String requestToken, String theURL) throws Exception{
/*
* Send a post together with request token and my login to get accessToken ...
*/
HttpPost httppost = new HttpPost(theURL); // loginurl);
httppost.setConfig(localConfig);
ghttpContext.setCookieStore(gcookies);
List params = new LinkedList();
params.add(new BasicNameValuePair("login_email", myemail));
params.add(new BasicNameValuePair("login_password", mypasswd));
params.add(new BasicNameValuePair("t", requestToken));
HttpEntity postentity = new UrlEncodedFormEntity(params);
httppost.setEntity(postentity);
System.out.println("\nexecuting request:" + httppost.getRequestLine());
// Create a custom response handler
ResponseHandler responseHandler = new ResponseHandler() {
public String handleResponse(final HttpResponse response)
throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 ) { // && status cookies = gcookies.getCookies();
for (Cookie aCookie: cookies) {
String cookieName = aCookie.getName();
if ( !(cookieName.lastIndexOf(tString) == -1) ) {
theAccessToken = aCookie.getValue();
}
}
System.out.println("Access Token: " + theAccessToken );
return theAccessToken;
}
postToUpload:
private String postToUpload(HttpClient client, String accessToken, String localFileInfo, String destPath) throws Exception{
String bjarString = "bjar";
String blidString = "blid";
String bjar=null;
String blid=null;
List cookies = gcookies.getCookies();
for (Cookie aCookie: cookies) {
String cookieName = aCookie.getName();
if ( !(cookieName.lastIndexOf(bjarString) == -1) ) {
bjar = aCookie.getValue();
} else if ( !(cookieName.lastIndexOf(blidString) == -1) ) {
blid = aCookie.getValue();
}
}
String[] fileNameArry = localFileInfo.split("(\\\\|/)");
String filename = fileNameArry[fileNameArry.length - 1]; // get the last part ...
URI uri = new URIBuilder()
.setScheme("https")
.setHost("dl-web.dropbox.com")
.setPath("/upload")
.setParameter("name", filename)
.setParameter("dest", destPath)
.setParameter("cookie_t", accessToken)
.setParameter("t", accessToken)
.build();
HttpPost httppost = new HttpPost(uri);
httppost.setConfig(localConfig);
ghttpContext.setCookieStore(gcookies);
FileBody bin = new FileBody(new File(localFileInfo));
StringBody comment = new StringBody("A binary file of some kind", ContentType.DEFAULT_BINARY);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("bin", bin)
.addPart("comment", comment)
.build();
httppost.setEntity(reqEntity);
// add header
httppost.setHeader("Host", "www.dropbox.com");
httppost.setHeader("User-Agent", USER_AGENT);
httppost.setHeader("Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
httppost.setHeader("Connection", "keep-alive");
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
httppost.setHeader("Pragma", "no-cache");
httppost.setHeader("Cache-Control", "no-cache");
// add entity
System.out.println("\nexecuting request:" + httppost.getRequestLine());
// Create a custom response handler
ResponseHandler responseHandler = new ResponseHandler() {
public String handleResponse(final HttpResponse response)
throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 ) { // && status
OAuth is the only way to use the Dropbox API. Once you have an OAuth access token (which you get by authenticating once, in this case with your account), you just need to do an HTTP PUT to https://api-content.dropbox.com/1/files_put/auto/<path> with the header Authorization: Bearer <token> and the contents of the file in the body.
Note that anyone who has your access token can also delete all your files, upload their personal DVD collection, etc. So it's not recommended that you share that access token.
There is files_get_temporary_upload_link:
Get a one-time use temporary upload link to upload a file to a Dropbox location.
This endpoint acts as a delayed upload. The returned temporary upload link may be used to make a POST request with the data to be uploaded. The upload will then be perfomed with the CommitInfo previously provided to get_temporary_upload_link but evaluated only upon consumption. Hence, errors stemming from invalid CommitInfo with respect to the state of the user's Dropbox will only be communicated at consumption time. Additionally, these errors are surfaced as generic HTTP 409 Conflict responses, potentially hiding issue details. The maximum temporary upload link duration is 4 hours. Upon consumption or expiration, a new link will have to be generated. Multiple links may exist for a specific upload path at any given time.
So you need to have an access token to call this function, but the uploader needs only the produced URL, without access to the rest of the Dropbox vault.