使用IAM临时凭证调用AWS API:C#代码认证失败但Postman成功
AWS SigV4A签名认证失败排查(C#代码)
我通过AssumeRole获取临时凭证,再用该凭证通过SigV4A签名调用AWS服务API,代码返回Authentication Error,但将相同临时凭证放到Postman中请求完全正常。
相关代码
获取临时凭证代码
private static async Task<Aws.Crt.Auth.Credentials> GetTemporaryCredentialsAsync() { using (var stsClient = new AmazonSecurityTokenServiceClient(aws_access_key_id, aws_secret_access_key)) { var response = await stsClient.AssumeRoleAsync(new AssumeRoleRequest { RoleArn = "arn:aws:iam::77790******:role/AmazonLendingAPIRole", RoleSessionName = "Assume123", DurationSeconds = 3600 }); Credentials credentials = response.Credentials; var sessionCredentials = new Aws.Crt.Auth.Credentials(credentials.AccessKeyId, credentials.SecretAccessKey, credentials.SessionToken); return sessionCredentials; } }
SigV4A签名方法
public IEnumerable<HttpHeader> SignRequest(string method, string region, string endpoint, string service, Credentials credentials) { var endpointUri = new Uri(endpoint); var request = new HttpRequest { Method = method, Uri = endpointUri.PathAndQuery, Headers = new[] { new HttpHeader("host", endpointUri.Host) } }; var config = new AwsSigningConfig { Service = service, Region = region, Algorithm = AwsSigningAlgorithm.SIGV4A, SignatureType = AwsSignatureType.HTTP_REQUEST_VIA_HEADERS, SignedBodyHeader = AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA256, Credentials = credentials, }; var result = AwsSigner.SignHttpRequest(request, config); AwsSigner.CrtSigningResult signingResult = result.Get(); HttpRequest signedRequest = signingResult.SignedRequest; return signedRequest.Headers; }
发起请求代码
var signingService = new SigV4ASign(); var assumeRoleUserCredentials = await GetTemporaryCredentialsAsync(); ; var endpoint = endpoint_get_offer; var awsCredentials = new Aws.Crt.Auth.Credentials(assumeRoleUserCredentials.AccessKeyId, assumeRoleUserCredentials.SecretAccessKey, assumeRoleUserCredentials.SessionToken); var method = HttpMethod.Get; var headers = signingService.SignRequest(method.Method, "eu-west-1", endpoint, "execute-api", awsCredentials); using var client = new HttpClient(); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Clear(); foreach (var header in headers) { client.DefaultRequestHeaders.TryAddWithoutValidation(header.Name, header.Value); } client.DefaultRequestHeaders.TryAddWithoutValidation("x-api-key", "WEuqF5RDOi5R1pza2601***************"); var response = await client.GetAsync(endpoint);
IAM用户配置截图

排查方向
- 签名Region一致性:确认Postman使用的Region与代码中
eu-west-1完全匹配,SigV4A签名对Region敏感,即使是多Region服务也需保证签名Region与请求目标Region一致。 - Host头校验:代码签名时已添加
host头,但HttpClient可能自动覆盖该头,需检查最终请求的Host是否与签名时的endpointUri.Host完全一致(含端口)。 - 请求参数一致性:对比Postman与代码的完整请求路径(含Query String),确保签名时的
endpointUri.PathAndQuery与实际请求的路径参数、编码、顺序完全相同。 - 签名Headers完整性:检查签名生成的所有Headers(如
Authorization、x-amz-date、x-amz-security-token)是否全部被HttpClient正确携带,未被默认设置覆盖。 - Body哈希配置:代码中设置
SignedBodyHeader = AwsSignedBodyHeaderType.X_AMZ_CONTENT_SHA256,需确认Postman使用相同的Body哈希方式;GET请求Body为空时,x-amz-content-sha256应对应空哈希或UNSIGNED-PAYLOAD。 - 临时凭证传递:验证AssumeRole获取的临时凭证(AccessKeyId、SecretAccessKey、SessionToken)是否完整、无错误地传递到签名方法中。
内容的提问来源于stack exchange,提问作者Fazla Elahi Md Jubayer
相关产品推荐
相关产品推荐

