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
611 stars 733 forks source link

[BUG] C# IO.Swagger.Api.ReportsApi getReport 'InvalidSignature' #2039

Closed wisdomleo closed 2 years ago

wisdomleo commented 2 years ago

{ "errors": [ { "message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

The Canonical String for this request should have been 'GET /reports/2021-06-30/reports/5189...

accept:application/json host:sellingpartnerapi-na.amazon.com x-amz-access-token:Atza|IwEBIH1z4kzFZFDtAm... ... ...SkxamYSj5zkiETz1jsgi x-amz-date:20211117T065625Z x-amz-security-token:FwoGZXIvYXdzEPj//////////wE... ... ...bbYgcBe7RohkuX7C3azLVsj8JhFvCk+LdMeg8IpmCV1qo=

accept;host;x-amz-access-token;x-amz-date;x-amz-security-token e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'

The String-to-Sign should have been 'AWS4-HMAC-SHA256 20211117T065625Z 20211117/us-east-1/execute-api/aws4_request ee7c603bda80885d4a8ab9a7bc33414e43366d361d137619f169d4b7df0446c1' ", "code": "InvalidSignature" } ] }

access and signed normally on 'createReport' call, but met 'invalid signature' error...

anybody knows why? /going crazy//going crazy//going crazy/

C# code as below:

region Generating the x-amz-security-token Header

                Amazon.SecurityToken.AmazonSecurityTokenServiceClient STS_client = new Amazon.SecurityToken.AmazonSecurityTokenServiceClient
                (
                    sp_dev.AWSAccessKeyID,
                    sp_dev.AWSSecretKey,
                    Amazon.RegionEndpoint.USEast1
                );

                Amazon.SecurityToken.Model.AssumeRoleRequest assumeRoleRequest = new Amazon.SecurityToken.Model.AssumeRoleRequest()
                {
                    RoleArn = sp_dev.AWSRoleARN,
                    RoleSessionName = Guid.NewGuid().ToString()
                };

                Amazon.SecurityToken.Model.AssumeRoleResponse assumeRoleResponse = STS_client.AssumeRole(assumeRoleRequest);

                #endregion

                IO.Swagger.Client.Configuration config = new Configuration()
                {
                    BasePath = MainForm.GetValue("Amazon_SPConfig_BaseURL"),
                    AuthenticationCredentials = new AWSAuthenticationCredentials()
                    {
                        // If the IAM ARN added to the application is IAM Role, you need to use AWS STS to request temporary credentials 
                        // and a session token which is to be added to your request along with the LWA Access Token.
                        AccessKeyId = assumeRoleResponse.Credentials.AccessKeyId,
                        SecretKey = assumeRoleResponse.Credentials.SecretAccessKey,
                        Region = sp_dev.Region
                    },

                    AuthorizationCredentials = new LWAAuthorizationCredentials()
                    {
                        ClientId = sp_dev.LWAClientID,
                        ClientSecret = sp_dev.LWAClientSecret,
                        Endpoint = new Uri(sp_dev.LWAEndpoint),
                        RefreshToken = act.OAuthRefreshToken
                    }
                };
                config.AddDefaultHeader("x-amz-security-token", assumeRoleResponse.Credentials.SessionToken);

                IO.Swagger.Client.ApiClient client = new ApiClient(config);
                IO.Swagger.Api.ReportsApi sp_reports_api = new IO.Swagger.Api.ReportsApi(config);

                // CreateReportResponse

                act.sp_resource.CR_Request = new IO.Swagger.Model.CreateReportSpecification
                (
                    new IO.Swagger.Model.ReportOptions(),
                    sp_ReportType, 
                    null, 
                    null, 
                    new List<string>() { MarketplaceID_US }
                );

                act.sp_resource.CR_Response = sp_reports_api.CreateReport(act.sp_resource.CR_Request);

                // GetReportResponse

                #region re-signature

                Amazon.SecurityToken.AmazonSecurityTokenServiceClient STS_client_2 = new Amazon.SecurityToken.AmazonSecurityTokenServiceClient
                (
                    sp_dev.AWSAccessKeyID,
                    sp_dev.AWSSecretKey,
                    Amazon.RegionEndpoint.USEast1
                );

                Amazon.SecurityToken.Model.AssumeRoleRequest assumeRoleRequest_2 = new Amazon.SecurityToken.Model.AssumeRoleRequest()
                {
                    RoleArn = sp_dev.AWSRoleARN,
                    RoleSessionName = Guid.NewGuid().ToString()
                };

                Amazon.SecurityToken.Model.AssumeRoleResponse assumeRoleResponse_2 = STS_client_2.AssumeRole(assumeRoleRequest_2);

                IO.Swagger.Client.Configuration config_2 = new Configuration()
                {
                    BasePath = MainForm.GetValue("Amazon_SPConfig_BaseURL"),
                    AuthenticationCredentials = new AWSAuthenticationCredentials()
                    {
                        // If the IAM ARN added to the application is IAM Role, you need to use AWS STS to request temporary credentials 
                        // and a session token which is to be added to your request along with the LWA Access Token.
                        AccessKeyId = assumeRoleResponse_2.Credentials.AccessKeyId,
                        SecretKey = assumeRoleResponse_2.Credentials.SecretAccessKey,
                        Region = sp_dev.Region
                    },

                    AuthorizationCredentials = new LWAAuthorizationCredentials()
                    {
                        ClientId = sp_dev.LWAClientID,
                        ClientSecret = sp_dev.LWAClientSecret,
                        Endpoint = new Uri(sp_dev.LWAEndpoint),
                        RefreshToken = act.OAuthRefreshToken
                    }
                };
                config_2.AddDefaultHeader("x-amz-security-token", assumeRoleResponse_2.Credentials.SessionToken);

                IO.Swagger.Client.ApiClient client_2 = new ApiClient(config_2);
                IO.Swagger.Api.ReportsApi sp_reports_api_2 = new IO.Swagger.Api.ReportsApi(config_2);
                #endregion

                act.sp_resource.GR_Request = act.sp_resource.CR_Response.ReportId;
                act.sp_resource.GR_Response = sp_reports_api_2.GetReport(act.sp_resource.GR_Request);
wisdomleo commented 2 years ago

**Relate to amzn/selling-partner-api-models#703

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

Thanks michaellavoie !!!

michaellavoie commented on 1 May While we wait for an official fix, I was able to resolve the bug by running this find-replace on the generated swagger output: Find: var localVarPath = " Replace: var localVarPath = $"

coder771 commented 2 years ago

@wisdomleo - have you created separate sdk clients for each API endpoint? like for feeds,orders,reports and referencing them? I'm trying to figure out if I can create one sdk client for all the APIs that are needed