amzn / selling-partner-api-models

This repository contains OpenAPI models for developers to use when developing software to call Selling Partner APIs.
Apache License 2.0
580 stars 730 forks source link

Access to requested resource is denied #1194

Closed diegocvazquez closed 3 years ago

diegocvazquez commented 3 years ago

Hello, I am having a problem integrating the sp-api, I have an applicacion that is using MSW, I followed the Selling Partner API Developer guide to set up up the user, policy and role. I started by trying a Grantless endpotint https://sellingpartnerapi-eu.amazon.com/authorization/v1/authorizationCode, I am using Postman and Signing the call with the AccessKey and secretKey The result is "errors": [ { "message": "Access to requested resource is denied.", "code": "Unauthorized", "details": "Access token is missing in the request header." } ]

Then generated a c# client with the swager-codegenator, to test the same enpoint, and I have the same results, same error. I have also tried to list some oders, using a sefl authorization token and I get the same issue. So I guess my problem is somehow the Iam configuration, I followed the guide and did all the steps the ARN that I used is the role one as mentioned in the guide.

I am able to generate a token using the refersh token that got from the self authorization, that is woking ok

Any help will be much appreciated! Thanks

sparkweb commented 3 years ago

The error seems to indicate that you aren't setting the token in the request header properly. Can you post a redacted screenshot of your header request?

diegocvazquez commented 3 years ago

The error seems to indicate that you aren't setting the token in the request header properly. Can you post a redacted screenshot of your header request?

Thanks four you response, just bring some context, I am using postman to test a grantless call

This is the Header image

This is the signature image

This is the call, I am testing getAuthorizationCode wich is grantless, and requires no authentication image

The result is; { "errors": [ { "message": "Access to requested resource is denied.", "code": "Unauthorized", "details": "Access token is missing in the request header." } ] }

If I test the same using C#, or for any call of any kind I get the same error but without the details, this is why I think this is more related with the configuration of User IAM

{ "errors": [ { "message": "Access to requested resource is denied.", "code": "Unauthorized", "details": "" } ]

Any ideas?

sparkweb commented 3 years ago

This is the call, I am testing getAuthorizationCode wich is grantless, and requires no authentication

Actually, I don't think that's quite true. Step 2 here says:

While the getAuthorizationCode operation gets you authorization to make calls to Selling Partner API on behalf of a seller, calling the operation itself does not require authorization from any seller. In this respect, the getAuthorizationCode operation is a "grantless" operation and has a different authorization model from other Selling Partner API operations.

Before you can make a grantless call, you need to request a token with the migration scope. Then you have to use that token when you make the authorization call just as you would with a regular call.

diegocvazquez commented 3 years ago

This is the call, I am testing getAuthorizationCode wich is grantless, and requires no authentication

Actually, I don't think that's quite true. Step 2 here says:

While the getAuthorizationCode operation gets you authorization to make calls to Selling Partner API on behalf of a seller, calling the operation itself does not require authorization from any seller. In this respect, the getAuthorizationCode operation is a "grantless" operation and has a different authorization model from other Selling Partner API operations.

Before you can make a grantless call, you need to request a token with the migration scope. Then you have to use that token when you make the authorization call just as you would with a regular call.

I see your point, I have check the documentation in https://github.com/amzn/selling-partner-api-docs/blob/main/guides/en-US/developer-guide/SellingPartnerApiDeveloperGuide.md Example for calling a grantless operation:

POST /auth/o2/token HTTP/l.l Host: api.amazon.com Content-Type: application/x-www-form-urlencoded;charset=UTF-8 grant_type=client_credentials &scope=sellingpartnerapi::notifications &client_id=foodev &client_secret=Y76SDl2F

so, basically doing this I am able to get a session token, but I dont see how to use this in the authorizationCode call, I am really lost with this

sparkweb commented 3 years ago

Right. So once you get the grantless token, use it just like you would use a regular access token: with the header x-amz-access-token. You also have to use all the other required headers as well as signing the request. So if you haven't completed that part of it, I'd recommend doing that with an endpoint like /sellers/v1/marketplaceParticipations before messing with the migrations.

diegocvazquez commented 3 years ago

Right. So once you get the grantless token, use it just like you would use a regular access token: with the header x-amz-access-token. You also have to use all the other required headers as well as signing the request. So if you haven't completed that part of it, I'd recommend doing that with an endpoint like /sellers/v1/marketplaceParticipations before messing with the migrations.

Hi, this is the call image The errror is still the same

Also tested the endpoint you suggeted image

Any ideas? , thanks for your support

diegocvazquez commented 3 years ago

I also tried from c# sellers/v1/marketplaceParticipations, in this case I am using a refresh token from a self authorized app, the error ist consitant, it must be som problem with my credentials, because when I require the token (with out signing ) it works.

I need help with this we are in the process of migrating a big application and I still cannot connect after 2 days

{ "errors": [ { "message": "Access to requested resource is denied.", "code": "Unauthorized", "details": "" } ] } Thanks for your help

diegocvazquez commented 3 years ago

UPDATE I red some post suggesting to create a second application and use the USER ARN, i did that and didnt work, but I also red someone recomending to asing the policy directly to the user, now the second application is working, I can make request.

The issue is that our appliction is a Hybrid and I need to make it work in order to start then migration. So basically my quiestion is: I hava a hybrid application with the status PUBLISHED, and it uses the Role ARN what do I need to do in the IAM user to make it work, I followed the guide over again and I am sure i did all the steps.

Woudl it be posible to change the ARN to the user in the published application?

AmericanY commented 3 years ago

@diegocvazquez am having a similar issue as you to call the Reports API. do i need to set another role/policy ? as my currently set is for STS ! https://github.com/amzn/selling-partner-api-models/issues/1195

diegocvazquez commented 3 years ago

@diegocvazquez am having a similar issue as you to call the Reports API. do i need to set another role/policy ? as my currently set is for STS ! amzn/selling-partner-api-models#1195

What I did is creating a new applaction and I used the USER ARN as suggested in some posts then I added the policy directly to the the user as a managed policy. It works but I need to use my Published application that is a Hybrid one, And I am lost

sparkweb commented 3 years ago

What I discovered is that if you are using the role ARN, you have to use STS to generate a temporary token to sign the request. And not only that, but you have to set the x-amz-security-token header which is not mentioned anywhere in the docs. It's quite frustrating because they direct you to use the role ARN in the docs but then give different directions that don't include anything about STS or the extra required header. You have to glean all this info from the issues tab by seeing what worked for other people.

I'm now stuck where you are. I have a legacy application which I don't want to touch until we are ready to transition and a new hybrid role-based ARN app. And I can't migrate any of the keys on my new app to test with real-world data since it isn't published. I'm unsure of how to proceed. I've started up amzn/selling-partner-api-models#1198 to query about this.

diegocvazquez commented 3 years ago

What I discovered is that if you are using the role ARN, you have to use STS to generate a temporary token to sign the request. And not only that, but you have to set the x-amz-security-token header which is not mentioned anywhere in the docs. It's quite frustrating because they direct you to use the role ARN in the docs but then give different directions that don't include anything about STS or the extra required header. You have to glean all this info from the issues tab by seeing what worked for other people.

I'm now stuck where you are. I have a legacy application which I don't want to touch until we are ready to transition and a new hybrid role-based ARN app. And I can't migrate any of the keys on my new app to test with real-world data since it isn't published. I'm unsure of how to proceed. I've started up amzn/selling-partner-api-models#1198 to query about this.

Yes, what I am testing now is how to assume the role, make the call with the remporary credentials, there is a post about it, I have implemented it but it is now working I guess there is still something wrong with my credentials in IAM

https://github.com/amzn/selling-partner-api-models/issues/713 Do you have any ideas?

sparkweb commented 3 years ago

I'm using the AWS PHP SDK with Guzzle and it worked like this:

private function getTemporaryCredentials(): Credentials
{
    $sts_client = new StsClient(self::MY_CREDENTIAL_ARRAY);

    $temporary_tokens = $sts_client->assumeRole([
        'RoleArn'         => self::ROLE_ARN_IAM,
        'RoleSessionName' => 'SellingPartnersApiSession',
    ]);

    $this->request_headers['x-amz-security-token'] = $temporary_tokens['Credentials']['SessionToken'];

    return new Credentials(
        $temporary_tokens['Credentials']['AccessKeyId'],
        $temporary_tokens['Credentials']['SecretAccessKey'],
    );
}
diegocvazquez commented 3 years ago

I am doing in c# but it does not work

diegocvazquez commented 3 years ago

I was able to solve this issue, this is realted with adding the ROLE ARN to the application registration you need to AssumeRole before making any calls, thanks for the help

hamduc7 commented 3 years ago

@diegocvazquez you meant you are still using ROLE ARN and it works? If yes could you please share the settings in AWS: role, policy, user?.

I am using ROLE ARN and it does not work. It only works when I use User ARN

diegocvazquez commented 3 years ago

@hamduc7 What I did is basically using the code ifrom his code avobe https://github.com/amzn/selling-partner-api-models/issues/1194. You need to use AmazonSecurityTokenServiceClient assumeRole ans obtain the AWS credentials from the role ARN, and then use this temporaly created credentials to sing your request

hamduc7 commented 3 years ago

@hamduc7 What I did is basically using the code ifrom his code avobe #574 (comment). You need to use AmazonSecurityTokenServiceClient assumeRole ans obtain the AWS credentials from the role ARN, and then use this temporaly created credentials to sing your request

I am testing in Postman. is there a way to make it works in Postman?

diegocvazquez commented 3 years ago

@hamduc7

Sorry I dont know that, I hava to code a small client c# for that purpouse not sure how to do the AssumeRoleAsync via Postman. Good luck!

diegocvazquez commented 3 years ago

@hamduc7 Have a look at this thread https://github.com/amzn/selling-partner-api-models/issues/699

hamduc7 commented 3 years ago

@diegocvazquez thank you