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 #713

Closed FexusZ closed 3 years ago

FexusZ commented 3 years ago

Hello, I followed the documentation to use SP-API, but each time I got the error : { "errors": [ { "message": "Access to requested resource is denied.", "code": "Unauthorized", "details": "" } ] } i have access Token, signature.. I followed the advice in the other issues, but nothing works i use refresh token get by seller central, can you help me ? Edit : when i add new application client in sellercentral is status is : 'Current edit is saved as draft'

Sorrow91 commented 3 years ago

Same problem here

rogersv commented 3 years ago

I got the same problem before. I had missed that I needed to assume the role that I used when adding an application. This step is not described in the documentation. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html You will get an ID, secret and token. The Id and secret should be used instead of the id and secret for your user. The token should be added to the header as x-amz-security-token.

FexusZ commented 3 years ago

I tried, but I get the error: Could not find operation AssumeRole for version 2012-10-17 with : https://sts.amazonaws.com/ ?DurationSeconds=3600 &RoleArn=arn:aws:iam::... &PolicyArns.member.1.arn=arn:aws:iam::... &RoleSessionName=... &Action=AssumeRole &Version=2012-10-17

rogersv commented 3 years ago

In the example they use Version=2011-06-15 and &Policy={"Version":"2012-10-17" see https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html

FexusZ commented 3 years ago

Sorry I thought we had to use the version of the role created.... But now i have missing Authentication Token, but didn't see authenticate Token in parameters..

rogersv commented 3 years ago

I did not use the access token but I added the IAM user credentials in the call. You also need to sign the headers as described in https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html

From the document:

You must use credentials for an IAM user or an IAM role to call AssumeRole.

FexusZ commented 3 years ago

Do you now if its possible to get the full error message with 'The canonical string for this request should have been....' and 'The String-to-Sign should have been...' ?

2445809596 commented 3 years ago

I've used STS to get the token (Python) and the signature is correct

class Boto3STSService(object):
    def __init__(self, arn):
        sess = Session(aws_access_key_id=ARN_ACCESS_KEY,
                       aws_secret_access_key=ARN_SECRET_KEY)
        sts_connection = sess.client('sts')
        assume_role_object = sts_connection.assume_role(RoleArn=arn, RoleSessionName=ARN_ROLE_SESSION_NAME,DurationSeconds=3600)
        self.credentials = assume_role_object['Credentials']
        print(self.credentials)

        """
        {'AccessKeyId': 'xxxx', 
         'SecretAccessKey': 'xxxx', 
         'SessionToken': 'xxxx', 
         'Expiration': datetime.datetime(2020, 10, 23, 5, 44, 45, tzinfo=tzutc())}
        """

This is my headers

headers = {
        "Authorization": f"AWS4-HMAC-SHA256 Credential={access_key_id + '/' + credential_scope},SignedHeaders={signed_headers},Signature=",
        "Content-Type": "application/json;charset=UTF-8",
        "host": host,
        "user-agent": "python-requests/2.23.0 (Host=xxx)",
        "x-amz-access-token": access_token,
        "x-amz-date": amz_date,
        "x-amz-security-token": session_token,
    }

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

FexusZ commented 3 years ago

I've replace the credentials access by security access , and i get the same error

tenitre commented 3 years ago

I got the same problem before. I had missed that I needed to assume the role that I used when adding an application. This step is not described in the documentation. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html You will get an ID, secret and token. The Id and secret should be used instead of the id and secret for your user. The token should be added to the header as x-amz-security-token.

For all the developers have the same issue, this is your answer.. thank you @rogersv

aspence07 commented 3 years ago

here's a complete working .NET implementation minus actual credentials

I had to manually add the selling partner api project from here to my solution:

https://github.com/amzn/selling-partner-api-models

`using Amazon.Runtime; using Amazon.SecurityToken; using Amazon.SecurityToken.Model; using Amazon.SellingPartnerAPIAA; using RestSharp; using System; using System.Threading.Tasks;

namespace amazon_sp_api_test { class Program { static void Main(string[] args) { AssumeRoleResponse assumeRoleResponse = null;

        Task.Run(async () =>
        {
            assumeRoleResponse = await GetAssumeRoleTokenDetail();
        }).GetAwaiter().GetResult();

        var baseUrl = "https://sellingpartnerapi-na.amazon.com";

        string resource = "/reports/2020-09-04/reports";
        RestClient restClient = new RestClient(baseUrl);
        IRestRequest restRequest = new RestRequest(resource, Method.GET);

        restRequest.AddQueryParameter("reportTypes", "GET_FLAT_FILE_OPEN_LISTINGS_DATA");

        // LWA credentials for app in amazon seller central
        var clientId = "foo";
        var clientSecret = "foo";
        // generate refresh token with 'Authorize' action for app in amazon seller central
        var refreshToken = "foo";

        var lwaAuthCreds = new LWAAuthorizationCredentials
        {
            ClientId = clientId,
            ClientSecret = clientSecret,
            RefreshToken = refreshToken,
            Endpoint = new Uri("https://api.amazon.com/auth/o2/token")
        };

        restRequest = new LWAAuthorizationSigner(lwaAuthCreds).Sign(restRequest);

        var awsAuthCreds = new AWSAuthenticationCredentials
        {
            AccessKeyId = assumeRoleResponse.Credentials.AccessKeyId,
            SecretKey = assumeRoleResponse.Credentials.SecretAccessKey,
            Region = "us-east-1"
        };

        restRequest.AddHeader("X-Amz-Security-Token", assumeRoleResponse.Credentials.SessionToken);

        restRequest = new AWSSigV4Signer(awsAuthCreds)
            .Sign(restRequest, restClient.BaseUrl.Host);

        var response = restClient.Execute(restRequest);

        Console.WriteLine(response.StatusCode);
        Console.WriteLine(response.Content);
    }
    // END method def Main()

    private static async Task<AssumeRoleResponse> GetAssumeRoleTokenDetail()
    {
        // AWS IAM user data, NOT seller central dev data
        var accessKey = "foo";
        var secretKey = "foo";

        var credentials = new BasicAWSCredentials(accessKey, secretKey);

        var client = new AmazonSecurityTokenServiceClient(credentials);

        var assumeRoleRequest = new AssumeRoleRequest()
        {
            DurationSeconds = 3600,
            // role ARN you create here: 
            // https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#step-4-create-an-iam-role
            RoleArn = "foo",
            RoleSessionName = DateTime.Now.Ticks.ToString()
        };

        var assumeRoleResponse = await client.AssumeRoleAsync(assumeRoleRequest);

        Console.WriteLine(assumeRoleResponse.HttpStatusCode);

        return assumeRoleResponse;
    }
}

}`

mustafa-bayindir commented 3 years ago

I got the same problem before. I had missed that I needed to assume the role that I used when adding an application. This step is not described in the documentation. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html You will get an ID, secret and token. The Id and secret should be used instead of the id and secret for your user. The token should be added to the header as x-amz-security-token.

Hey I've been getting credentials from the assumerole call but i get an error that says that my securitytoken is invalid..

Anyone a idea?

massimobranca commented 3 years ago

i'm trying the code provided by aspence07, but at line var assumeRoleResponse = await client.AssumeRoleAsync(assumeRoleRequest); visual studio 2019 gives me error CS0815: cannot assign 'void' to an implicitly typed local variable.

mayurhshinde commented 3 years ago

Console.WriteLine(response.StatusCode); Console.WriteLine(response.Content);

I am also getting below Error : The security token included in the request is invalid code:InvalidInput

christopherroyshields commented 3 years ago

I got the same problem before. I had missed that I needed to assume the role that I used when adding an application. This step is not described in the documentation. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html You will get an ID, secret and token. The Id and secret should be used instead of the id and secret for your user. The token should be added to the header as x-amz-security-token.

Hey I've been getting credentials from the assumerole call but i get an error that says that my securitytoken is invalid..

Anyone a idea?

Make sure you are replacing the AWSAuthenticationCredentials with the credentials in the AssumeRole response.


var awsAuthCreds = new AWSAuthenticationCredentials
{
     AccessKeyId = assumeRoleResponse.Credentials.AccessKeyId,
     SecretKey = assumeRoleResponse.Credentials.SecretAccessKey,
     Region = "us-east-1"
};
diegocvazquez commented 3 years ago

Console.WriteLine(response.StatusCode); Console.WriteLine(response.Content);

I am also getting below Error : The security token included in the request is invalid code:InvalidInput

@mayurhshinde did you solve this issue I am facing the same problem, thanks

mayurhshinde commented 3 years ago

yes. you have to follow the step for AWS console configuration(Add User, Policy, and role).

kevinhq commented 3 years ago

here's a complete working .NET implementation minus actual credentials

I had to manually add the selling partner api project from here to my solution:

Does this work for anyone else? It doesn't work for me. But, I wonder if it's because of inactive Amazon Seller account?

We can access the MWS API just fine with inactive seller account, so I assume SP API has the same behavior. Or am I wrong?

Anyone is able to call SP API without an active seller account?

marcopaoletti commented 3 years ago

Same problem here, with an active seller account. Still trying to find a solution

kprajith commented 3 years ago

I am facing the same issue. Although I am able to successfully get response for the marketplaceParticipations API after updating code with Assume role as suggested previously. In the same code when I change the API URL from "sellers/v1/marketplaceParticipations"(Which is working) to "feeds/2021-06-30/feeds/", I am back to square one with same error. Gone through so many discussion and articles but still not able to resolve this error. Could someone please help?

xiaodong-zhu commented 3 years ago

Not the best practice, but i strongly recommend using IAM User, instead of IAM Role, when creating a SP Application in seller central, especially if you are new to this.

IAM User saves tons of time as temporary security credentials are not required.

If IAM User is indeed an option to you,

  1. Follow "Step 3. Create an IAM policy" and directly attach the policy created to your IAM User
  2. When you create the SP Application, use IAM User ARN, instead of IAM Role ARN, which you don't even need to create
  3. When you sign the request, use secretAccessKey and accessKeyId of your IAM User, and ignore sessionToken
xiaodong-zhu commented 3 years ago

I am facing the same issue. Although I am able to successfully get response for the marketplaceParticipations API after updating code with Assume role as suggested previously. In the same code when I change the API URL from "sellers/v1/marketplaceParticipations"(Which is working) to "feeds/2021-06-30/feeds/", I am back to square one with same error. Gone through so many discussion and articles but still not able to resolve this error. Could someone please help?

check "Authorization with the Restricted Data Token" in the reference. although sellers/v1/marketplaceParticipations is grantless, most feeds are restricted

SouravPal95 commented 3 years ago

Do we need to do the assumeRole even if we have lwa tokens?

Emizy commented 3 years ago

Am getting Access to requested resource is denied on create feed document ,any solution to that, very urgent ?

AlbertoVictoriaDeveloper commented 3 years ago

I have a similar problem I have two seller accounts in one the resource works correctly in my case I am testing the reports, but the strange thing is that in the old API MWS everything works correctly but in SP in one account I have problems someone can know why favor. Will it be a question of permission in the seller's amazon account?

abuzuhri commented 3 years ago

Same problem here keep getting same problem even after I try solution here https://stackoverflow.com/questions/64560163/a

abuzuhri commented 3 years ago

problem solved after change to role not user in amazon application

paulabirocchi commented 3 years ago

About the rogersv's answer, could someone help me to find the correct place to select the option "Assume the role"?

paulabirocchi commented 3 years ago

I got the same problem before. I had missed that I needed to assume the role that I used when adding an application. This step is not described in the documentation. https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html You will get an ID, secret and token. The Id and secret should be used instead of the id and secret for your user. The token should be added to the header as x-amz-security-token.

How can you get the ID, secret and token? I already added the role ARN when creating the app.

paulabirocchi commented 3 years ago

I am not sure how to "Assume Role". I included the role ARN when creating the app, but not sure if this is enough. I'm trying to access the API through Python.

kprajith commented 3 years ago

I have created Postman collection for SP apis(Which is working for me. based on that i have created my apis in Java). Please find the attachment at https://github.com/amzn/selling-partner-api-models/issues/1424. Also gave info on assuming role at the same link

paulabirocchi commented 3 years ago

Thank you. I'm looking for a solution in Python to make an automated process.

Em sex., 10 de set. de 2021 às 17:01, Prajith Komalachery < @.***> escreveu:

I have created Postman collection for SP apis(Which is working for me. based on that i have created my apis in Java). Please find the attachment at amzn/selling-partner-api-models#1424 https://github.com/amzn/selling-partner-api-models/issues/1424. Also gave info on assuming role at the same link

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/amzn/selling-partner-api-models/issues/713, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGCE3BV3BVMPE7FILPPRMKLUBJPX3ANCNFSM4SZPO7TA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

--

Paula Birocchi

Oceanographer MsC. in Sciences (Physical Oceanography) *PhD. *candidate Instituto Oceanográfico (IO)

University of São Paulo (USP), Brazil

paulabirocchi commented 2 years ago

Hi,

I was able to follow @rogersv steps, but I got: AuthorizationError: ('unauthorized_client', 'Not authorized for requested operation', 400) As I want to access the Orders (that is restricted), should I use the Restricted Data Token (RDT)?

I'm using the following Python command: res = orders_obj.get_orders( LastUpdatedAfter=(datetime.utcnow() - timedelta(days=7)).isoformat(), MarketplaceIds=','.join(marketplaces) , x_amz_security_token='XXXXX')

caseywalker commented 1 year ago

here's a complete working .NET implementation minus actual credentials

I had to manually add the selling partner api project from here to my solution:

https://github.com/amzn/selling-partner-api-models

`using Amazon.Runtime; using Amazon.SecurityToken; using Amazon.SecurityToken.Model; using Amazon.SellingPartnerAPIAA; using RestSharp; using System; using System.Threading.Tasks;

namespace amazon_sp_api_test { class Program { static void Main(string[] args) { AssumeRoleResponse assumeRoleResponse = null;

        Task.Run(async () =>
        {
            assumeRoleResponse = await GetAssumeRoleTokenDetail();
        }).GetAwaiter().GetResult();

        var baseUrl = "https://sellingpartnerapi-na.amazon.com";

        string resource = "/reports/2020-09-04/reports";
        RestClient restClient = new RestClient(baseUrl);
        IRestRequest restRequest = new RestRequest(resource, Method.GET);

        restRequest.AddQueryParameter("reportTypes", "GET_FLAT_FILE_OPEN_LISTINGS_DATA");

        // LWA credentials for app in amazon seller central
        var clientId = "foo";
        var clientSecret = "foo";
        // generate refresh token with 'Authorize' action for app in amazon seller central
        var refreshToken = "foo";

        var lwaAuthCreds = new LWAAuthorizationCredentials
        {
            ClientId = clientId,
            ClientSecret = clientSecret,
            RefreshToken = refreshToken,
            Endpoint = new Uri("https://api.amazon.com/auth/o2/token")
        };

        restRequest = new LWAAuthorizationSigner(lwaAuthCreds).Sign(restRequest);

        var awsAuthCreds = new AWSAuthenticationCredentials
        {
            AccessKeyId = assumeRoleResponse.Credentials.AccessKeyId,
            SecretKey = assumeRoleResponse.Credentials.SecretAccessKey,
            Region = "us-east-1"
        };

        restRequest.AddHeader("X-Amz-Security-Token", assumeRoleResponse.Credentials.SessionToken);

        restRequest = new AWSSigV4Signer(awsAuthCreds)
            .Sign(restRequest, restClient.BaseUrl.Host);

        var response = restClient.Execute(restRequest);

        Console.WriteLine(response.StatusCode);
        Console.WriteLine(response.Content);
    }
    // END method def Main()

    private static async Task<AssumeRoleResponse> GetAssumeRoleTokenDetail()
    {
        // AWS IAM user data, NOT seller central dev data
        var accessKey = "foo";
        var secretKey = "foo";

        var credentials = new BasicAWSCredentials(accessKey, secretKey);

        var client = new AmazonSecurityTokenServiceClient(credentials);

        var assumeRoleRequest = new AssumeRoleRequest()
        {
            DurationSeconds = 3600,
            // role ARN you create here: 
            // https://github.com/amzn/selling-partner-api-docs/blob/main/guides/developer-guide/SellingPartnerApiDeveloperGuide.md#step-4-create-an-iam-role
            RoleArn = "foo",
            RoleSessionName = DateTime.Now.Ticks.ToString()
        };

        var assumeRoleResponse = await client.AssumeRoleAsync(assumeRoleRequest);

        Console.WriteLine(assumeRoleResponse.HttpStatusCode);

        return assumeRoleResponse;
    }
}

}`

This fixed it for me. Thank you for providing your code sample.