Not authorized to access scope - Amazon Advertising API - java

My purpose is to download the advertising report using existing application details such as AMAZON_CLIENT_ID, AMAZON_CLIENT_SECRET & Access tokens to other java application.
I was able to get the new access token using AMAZON_CLIENT_ID, AMAZON_CLIENT_SECRET & refresh_token. Below is the code to fetch a new access token.
OkHttpClient client = new OkHttpClient();
Response response;
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=refresh_token&refresh_token=" + refreshToken + "&client_id=" + amzClientId + "&client_secret=" + amzClientSceret);
Request request = new Request.Builder()
.url(“https://api.amazon.com/auth/o2/token”)
.post(body)
.addHeader("content-type", "application/x-www-form-urlencoded")
.build();
response = client.newCall(request).execute();
After sending the api request to fetch the campaign level stats data, is gives the following error
{"code":"UNAUTHORIZED","
details":"Not authorized to access scope XXXXXXXXXXXXXXXXXX","
requestId":"xxxxxxxxxxxxx"}"
My question here is, Can I use the same existing AMAZON_CLIENT_ID, AMAZON_CLIENT_SECRET & Access tokens to fetch stats to different java applications(without using login with amazon)?
Any help would be appreciated. Thank you!!

You need to include the access token and client ID for subsequent requests.
.addHeader("Authorization", "Bearer " + access_token)
.addHeader("Amazon-Advertising-API-ClientId", client_id)

Related

How to upload file with Okhttp3 (REST API)

I'm trying to upload an image with uploading bytes of Google Photos API .
So here is my request with OkHttp3:
Request request = new Request.Builder()
.addHeader("Authorization", "Bearer " + token)
.addHeader("Content-type:", "application/octet-stream")
.addHeader("X-Goog-Upload-Content-Type:",mimeType)
.addHeader("X-Goog-Upload-Protocol:", "raw")
.url("https://photoslibrary.googleapis.com/v1/uploads")
.post(requestBody) // how to build request body?
.build();
the documentation says: "In the request body, include the binary of the file:"
media-binary-data
What does it means?
For a given file, I assume that it is:
byte[] data = FileUtils.readFileToByteArray(new File(myPath));
But how do you build this requestBody with data array?
EDIT
I already tried :
MediaType mType = MediaType.parse("application/octet-stream; charset=utf-8");
RequestBody requestBody = RequestBody.create(mType,new File(path));
Exception :
okhttp3.internal.http2.StreamResetException: stream was reset: PROTOCOL_ERROR
Thank you in advance for putting me on the track!
RequestBody has a few overloaded factory methods:
create(MediaType, byte[])
create(MediaType, File)
It looks like you're supplying the second parameter in either case correctly.
As for the MediaType parameter, I usually use the MIME type of the underlying image rather than specifying general binary content, e.g.:
MediaType.parse("image/jpeg")
or
MediaType.parse("image/png")
...
unfortunately I left the ":" after the parameter keys !!!!
Request request = new Request.Builder()
.addHeader("Authorization", "Bearer " + token)
.addHeader("Content-type", "application/octet-stream")// and no X-Goog-Upload-Content-Type :
.addHeader("X-Goog-Upload-Content-Type",mimeType)//same
.addHeader("X-Goog-Upload-Protocol", "raw")//same
.url("https://photoslibrary.googleapis.com/v1/uploads")
.post(requestBody)
.build();
And for the requestBody:
byte [] data = FileUtils.readFileToByteArray(file);
RequestBody requestBody = RequestBody.create(mimeTypeOfFile,data);

How to set OAuth realm in RestAssured

I am using RestAssured library for automating NetSuite Restlets. This Restlets are using OAuth 1.0 for authentication. Apart from consumer key, consumer secret, access token and token secret, I need to set advanced fields like REALM. But I couldn't find any way to set that in RestAssured.
RequestSpecification request = new RequestSpecBuilder()
.addHeader("Content-Type", ContentType.JSON.toString())
.setBaseUri(url).build()
.auth().oauth(
netsuiteConfig.getNetsuiteConsumerKey(),
netsuiteConfig.getNetsuiteConsumerSecret(),
netsuiteConfig.getNetsuiteTokenId(),
netsuiteConfig.getNetsuiteTokenSecret()
);
Here is the api call using Postman
RestAssured does not support this. Create OAuth 1.0 string using some library (I have used com.github.seratch:signedrequest4j) and set Authorization header in RestAssured RequestSpecification.
OAuthConsumer consumer = new OAuthConsumer(consumerKey, consumerSecret);
OAuthAccessToken accessToken = new OAuthAccessToken(tokenId, tokenSecret);
OAuthRealm realm = new OAuthRealm(myRealm);
SignedRequest request =
SignedRequestFactory.create(realm, consumer, accessToken);
request.readQueryStringAndAddToSignatureBaseString(url);
request.setHeader("Content-Type", "application/json");
String oAuthNonce = String.valueOf((new SecureRandom()).nextLong());
Long oAuthTimestamp = System.currentTimeMillis() / 1000L;
String signature = request.getSignature(url,
HttpMethod.POST, oAuthNonce, oAuthTimestamp);
String authorizationHeader = request
.getAuthorizationHeader(signature, oAuthNonce, oAuthTimestamp);
I was using the library mentioned in the previous answer but then I realised I needed to use PATCH requests which wasn't supported.
I started using the google oauth client instead and after days of trying, finally got this example working:
val signer = OAuthHmacSigner()
signer.clientSharedSecret = CONSUMER_SECRET
signer.tokenSharedSecret = TOKEN_SECRET
val oauthParameters = OAuthParameters()
oauthParameters.consumerKey = CONSUMER_KEY
oauthParameters.token = ACCESS_TOKEN
oauthParameters.signer = signer
val genericUrl = GenericUrl("https://{ACC_ID}.suitetalk.api.netsuite.com/path/to/endpoint")
oauthParameters.version = "1.0"
oauthParameters.computeNonce()
oauthParameters.computeTimestamp()
oauthParameters.computeSignature("GET", genericUrl)
oauthParameters.realm = REALM
val authHeader = oauthParameters.authorizationHeader
RestAssured.with()
.log().all()
.header("Authorization", authHeader)
.urlEncodingEnabled(false)
.request(Method.GET, genericUrl.toString())
.then()
.statusCode(200)
urlEncoding is set to false for urls with query params that are already encoded. For example:
{url}/invoice?q=internalid%20IS%2012
I hope it helps someone in the future!

How do you set a token as an HTTPHeader for a get request in java?

I'm trying to write a test to receive a JSON response from an API and I need to set a security token in the header for the API call. I've already verified that I am receiving a valid token from the get/token API. When I try to execute the HttpGet I am receiving a 401 status code.
Update: Does anyone have a complete list of authorization token types?
public void listAllDoctors() throws IOException {
String listAllDoctors = "/api/doctors/search";
HttpGet getDEV = new HttpGet(DEVBASE_ENDPOINT + listAllDoctors);
getDEV.setHeader(HttpHeaders.AUTHORIZATION, "token " + TOKEN);
getDEV.setHeader(HttpHeaders.CONTENT_TYPE, "application/json");
response = client.execute(getDEV);
int actualStatus = response.getStatusLine().getStatusCode();
assertEquals(actualStatus, 200);
}
I figured out that the API uses a custom header token authentication. So the line of code goes like this:
getDev.setHeader("token", "Token value goes here");

Apidaze REST API HTTP POST Call in Android/Java

I am trying to send SMS messages when a button is clicked in an Android app. I have the SMS sending code in Python using a REST API. The template looks like so:
import requests
url = "https://api.apidaze.io/{{api_key}}/sms/send"
querystring = {"api_secret":"{{api_secret}}"}
payload = "from=15558675309&to=15551234567&body=Have%20a%20great%20day."
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
response = requests.request("POST", url, data=payload, headers=headers,
params=querystring)
print(response.text)
Because I am making an Android app, I need this to be in Java, but I am having trouble making the same POST request with the same parameters, headers, and body in JAVA.
Does anyone know how to make convert this template into something I can use for an Android app in Java?
There is a port of Apache Http Client for Android:
http://hc.apache.org/httpcomponents-client-4.3.x/android-port.html
Check the documentation, a simple POST request is very easy using this library:
HttpPost httpPost = new HttpPost("https://api.apidaze.io/" + api_key + "/sms/send");
String json = "{"api_secret":" + api_secret + "}";
StringEntity entity = new StringEntity(json);
httpPost.setEntity(entity);
httpPost.setHeader("Content-type", "application/x-www-form-urlencoded");
CloseableHttpResponse response = client.execute(httpPost);

Can't use Dynamics CRM token (401 Unauthorized)

I'm writing a simple android app in Java and recently implemented retrieving a token for a user from Microsoft Dynamics CRM (I have created a connected app in Azure, got application id, secret etc).
I want other users of this application to be able to connect to their CRMs and organizations.
Now I'm trying to use the token with the REST API and getting 401 error.
Read all the related answers here, nothing helped. The code I'm using:
//retrieved the authorization code by this url:
mAuthorizationUrl = Configuration.AUTHORIZE_ENDPOINT + "?response_type=code&client_id="
+ Configuration.CLIENT_ID + "&redirect_uri=" + Configuration.REDIRECT_URI;
...
//Retrieving access_token:
String body_content = "grant_type=authorization_code&client_id=" +
Configuration.CLIENT_ID + "&redirect_uri=" + Configuration.REDIRECT_URI
+ "&code=" + code + "&resource=" + Configuration.CLIENT_ID;
//I don't have app URI (resource) in Azure, so I used app id (client id).
//This worked (see above).
RequestBody body = RequestBody.create(
MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"),
body_content);
Request request = new Request.Builder()
.url(Configuration.TOKEN_RETRIEVAL_ENDPOINT)
.post(body)
.build();
Response response = new OkHttpClient().newCall(request).execute();
String responseString = response.body().string();
JSONObject json = new JSONObject(responseString);
String token = json.getString("access_token");
//NOT WORKING CODE:
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.protocols(Collections.singletonList(Protocol.HTTP_1_1))
.build();
Map<String, String> headers = new ArrayMap<>();
headers.put("Authorization", "Bearer " + token));
headers.put("Accept", "application/json");
request = new Request.Builder()
.url(Configuration.REST_ENDPOINT)
.headers(Headers.of(headers))
.build();
try {
response = okHttpClient
.newCall(request)
.execute();
statusCode = response.code();
}
...
//401 UNAUTHORIZED
Endpoints I used:
AUTHORIZE_ENDPOINT = https://login.microsoftonline.com/common/oauth2/authorize
TOKEN_RETRIEVAL_ENDPOINT = https://login.microsoftonline.com/common/oauth2/token
REST_ENDPOINT = url_to_crm/api/data/v9.0/
Here are two sample Java projects that connect and authenticate with the Dynamics Web API via Azure:
Link 1
Link 2
Hope this helps.

Categories

Resources