How to resolve "Access to requested resource is denied"? - amazon-web-services

I am getting the following when sending a marketplaceParticipations request to sellers/v1/marketplaceParticipations via Postman after following instructions and examples provided at https://developer-docs.amazon.com/sp-api/docs/connecting-to-the-selling-partner-api
{
"errors": [
{
"message": "Access to requested resource is denied.",
"code": "Unauthorized",
"details": ""
}
]
}
We have registered a self-authorized app client in Draft status which has a user ARN IAM attached as described at https://developer-docs.amazon.com/sp-api/docs/registering-your-application.Ï
I've checked the inline and role policies for the ARN IAM. They are exactly as described at https://developer-docs.amazon.com/sp-api/docs/creating-and-configuring-iam-policies-and-entities#step-4-create-an-iam-role.
We are able to successfully request an LWA access token following the docs at https://developer-docs.amazon.com/sp-api/docs/connecting-to-the-selling-partner-api#step-1-request-a-login-with-amazon-access-token.

Please check that the roles of the user you are using allow to make request to that endpoint in your dev profile at https://sellercentral.amazon.com/
As far as I know, the getMarketplaceParticipations doesn't need a Restricted Data Token (RDT). So you must be able to solve it by giving the user the correct roles.
I was able to get them using Postman. It is a good way to check that the request is correctly built and not a programming issue.

Related

Overcoming 401 on /compute/v1/projects/{project}/zones?

Reverse-engineering the gcloud tool—with the suggested --log-http mostly—I was able to get auth tokens generated, and even selected the same scope (double checking at https://www.googleapis.com/oauth2/v1/tokeninfo):
http://[redacted]/callback?state=[redacted]&code=[redacted]&scope=email+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&authuser=0&prompt=consent
https://oauth2.googleapis.com:443/token?grant_type=authorization_code&code=[redacted]&redirect_uri=[redacted]/callback&client_id=[redacted]apps.googleusercontent.com&client_secret=[redacted]
Headers I try to hit the /zones/list endpoint with:
Content-Type: application/json
charset: utf-8
Authorization: Bearer [redacted]
X-Goog-User-Project: [redacted]
I've also tried putting access_token=[redacted] in my query string. But not matter what I do, I always get:
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Login Required.",
"domain": "global",
"reason": "required",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED"
}
}
Other endpoints like like /projects/list seem to work with this access token (in header). What am I doing wrong?
As I see from the error message, you got 401 http status code. It means that the access token you used does not give you access (is not authorised) to list zones. And here you need to know that you cannot compare zone.list and projects.list. In fact:
zone.list is part of compute engine API, whereas projects.list is part of resource-manager API
zone.list requires compute.zones.list permission that is part of Compute Engine roles, like Compute Viewer whereas projects.list requires resourcemanager.projects.list which you'll find with many roles even the Browser role which is the smallest role (I think) in terms of number of permission.
To summarise, typically you used an access token of an identity which has access to projects.list but not to zone.list. Example this identity has only Browser role.
Then, there this sentence that caught my attention on how you are getting the access token:
Reverse-engineering the gcloud tool
You need to know that getting an access token is quite easy.
Run gcloud auth login which obtains access credentials for your user account via a web-based authorization flow.
Run gcloud auth print-access-token which prints an access token for your user account, so his permissions.
So if your user account has a role with compute.zones.list and resourcemanager.projects.list permissions (for example Compute Viewer role has both), you will be able to call both endpoints successfully.
Finally, here is a curl example, listing zones, using the generated access token:
curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json" https://compute.googleapis.com/compute/v1/projects/<PROJECT_ID>/zones
Turns out my original solution was 100% correct. For some odd reason the string being saved in the access token field of my struct was different to the one gathered from the remote auth flow.

Google recommendations AI deleting catalog items error 403

I am trying to integrate my catalog into google recommendations ai, and for debugging purposes I want to be able to delete items from the catalog once imported. The documentations suggests running the following code:
curl -X DELETE \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
"https://retail.googleapis.com/v2/projects/[PROJECT_NUMBER]/locations/global/catalogs/default_catalog/branches/0/products/[PRODUCT_ID]"
which returns the following error:
{
"error": {
"code": 403,
"message": "Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the retail.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.",
"status": "PERMISSION_DENIED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "SERVICE_DISABLED",
"domain": "googleapis.com",
"metadata": {
"service": "retail.googleapis.com",
"consumer": "[redacted for privacy]"
}
}
]
}
Running the suggested code with the --impersonate-service-account flag, results in the same error as above, but preceded with
WARNING: Impersonate service account '[name redacted for privacy]' is detected. This command cannot be used to print the access token for an impersonate account. The token below is still the application default credentials' access token.
If I attempt to log in for authorization instead of printing an access token, I get the following error:
{
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
The link provided is no longer working. I would like to know how to provide proper authorization/authentication for deleting an item from the recommendation ai catalog.
PS. The account I am using to do this is the owner of the project, and as such should have all the appropriate permissions.
To set up authentication for your application of local cURL request to Recommendations AI. You have to create a Service Account, download SA key, and set the environment variable 'GOOGLE_APPLICATION_CREDENTIALS' to the key so allow your local cURL request noted in the original description
If you are unable to download a SA key file, I kindly suggest to try to use a ! before the curl like this, !curl -X POST , also if you are familiar with Python, it's recommended to use the python library for Recommendations AI.

Template file failed to load with Dataflow bulk delete api

I'm using the REST API template provided from https://cloud.google.com/dataflow/docs/guides/templates/provided-utilities#api_2 to delete from datastore but I'm getting the following error
"error": {
"code": 403,
"message": "(55ae8f210de971e7): Template file failed to load: gs://dataflow-templates/dataflow-templates/latest/Datastore_to_Datastore_Delete. Permissions denied. Provided scope(s) are not authorized",
"status": "PERMISSION_DENIED"
}
It says the scope isn't authorized but the docs say you only need one of the following: https://www.googleapis.com/auth/compute.readonly, https://www.googleapis.com/auth/compute, https://www.googleapis.com/auth/cloud-platform or https://www.googleapis.com/auth/userinfo.email.
For my oauth2 request I tried adding the devstorage scope as well: https://www.googleapis.com/auth/compute.readonly https://www.googleapis.com/auth/devstorage.read_only
I'm calling POST https://dataflow.googleapis.com/v1b3/projects/{projectid}/templates:launch?gcsPath=gs://dataflow-templates/latest/Datastore_to_Datastore_Delete
With
{
jobName: 'PrunePrintLogs',
environment: { zone: 'europe-west2' },
parameters: {
datastoreReadGqlQuery: 'select * from `00000000test`',
datastoreReadProjectId: '{projectid}',
datastoreDeleteProjectId: '{projectid}'
}
}
My project id is redacted.
I added the Owner role to the account getting the oauth2 token just temporarily for testing so wouldn't all scopes be authorized?
Got it working. Firstly I needed to remove the 'environment' parameter. Secondly I set scope to 'https://www.googleapis.com/auth/cloud-platform'. It also seems the role needs to be Editor, I wasn't able to find a more restrictive role to get it working.
Curiously when I sent the request from postman is shows up in Dataflow jobs as sdk 2.27.0 but I'm sure I'm sending exactly the same from my node app using axios and it shows up as sdk 2.20.0 and warns that it will eventually be no longer supported.

What privileges are required to call the directory.user.update api?

Our organization uses SAML for SSO into Google Apps. In order to use SSO we must manage the change password functionality through APIs. Since the Provisioning API has been deprecated in favor of the Admin SDK Directory API, I am developing against this API.
The flow I am developing is that the end user will login using Google OAuth2 into my application. Then, using the users access token I am attempting to call the https://www.googleapis.com/admin/directory/v1/users/ API to put a new password, but I get an error 403 "Not Authorized to access this resource/api".
My question is, what privilege is required for the user to be able to update their own password? When calling this API with GET I am able to retrieve my user information successfully, but trying to put a new password (or any other field for that matter) fails.
Here is an example of my request and response:
Request:
PUT https://www.googleapis.com/admin/directory/v1/users/user%40domain.org?key={YOUR_API_KEY}
Content-Type: application/json
Authorization: Bearer ya29.AHES6ZT_7onp48edpClD72X-*************************
X-JavaScript-User-Agent: Google APIs Explorer
{
"password": "wlKsf.##2af"
}
Response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Not Authorized to access this resource/api"
}
],
"code": 403,
"message": "Not Authorized to access this resource/api"
}
}
Only super admins, delegated admins and resellers can access the Admin SDK Directory API.
I suggest creating a delegated admin that only has access to update users via the API and then having your web application utilize an OAuth token created for this delegated admin.

Calling Ads API reachestimate returns "Application does not have permission for this action"

Following the Ads API docs for reachestimate (http://developers.facebook.com/docs/reference/ads-api/reachestimate/), I received a "false" response when calling
https://graph.facebook.com/act_0000000000000000/reachestimate?currency=EUR&targeting_spec={'countries':['US']}&access_token=___
(Note: act_0000000000000000 is my user Id and _ is my access token - these tokens work correctly for other Ads API calls).
Using the Graph API Explorer tool, I receive the following response on this API call
{
"error": {
"message": "(#10) Application does not have permission for this action",
"type": "OAuthException",
"code": 10
}
}
However, when I call
https://graph.facebook.com/1111111111111111/reachestimate?currency=EUR&targeting_spec={'countries':['US']}&access_token=___
where 1111111111111111 is an adgroup, I get a valid data structure.
Has anyone come across this elsewhere? Is there a "magic" setting somewhere that enables this capability on the user account (enabled for ads_management, offline_access)?
Any thoughts very welcome.
Thank you.
Thanks #Igy - just confirmed that my issue was indeed the misuse of my UserID in account field - have since migrated these queries to use the designated account ID and works as expected.