Вот ошибка я получаю ....Сообщение об ошибке при вызове Api Шлюз с подписью
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
/devcam/securehello
host:*.execute-api.us-west-2.amazonaws.com
x-amz-date:20161223T170922Z
host;x-amz-date
e3b0c44098098s098df098s...8f0s98df098sd09f8s0d98f095'
The String-to-Sign should have been
'AWS4-HMAC-SHA256
20161223T170922Z
20161223/us-west-2/execute-api/aws4_request
828177fca39making23409...9840928304980238402983282d'
Странная вещь я сравнить это с моей каноническом строки и строки, чтобы подписать и они идентичны .. Что еще мне нужно проверить?
Я пытаюсь назвать это временными удостоверениями лямбда aws. Я не совсем уверен, как я должен использовать токен сеанса, но сейчас он добавляется как заголовок (я пытался включить его в подписанные заголовки и не включая его - ни работа) «X-Amz -Маркер безопасности".
Edit:
Вот JSON Serialized объект HttpMessageRequest из .NET ядра, который я использую, чтобы отправить запрос.
{
"Version": {
"Major": 1,
"Minor": 1,
"Build": -1,
"Revision": -1,
"MajorRevision": -1,
"MinorRevision": -1
},
"Content": null,
"Method": {
"Method": "GET"
},
"RequestUri": "https:\/\/somerandomapigatewaystring.execute-api.us-west-2.amazonaws.com\/devcam\/securehello",
"Headers": [
{
"Key": "x-amz-security-token",
"Value": [
"FQoDYXdzEKr\/\/\/\/\/\/\/\/\/\/wEaDPuFLZoHsomefmorefakevaluesin5here0+36yIwO1kh8sdkeuf98eek3kj4934898erjthisisafakevaluehahahahahahahahaz8FE7jKvENO1IdshzqjDFWhpnfLESAS4B404dBW\/VAkH1jJDvpiFylP5qiZk6q+S\/eJHDdLUoVAXDqkh0w2wkFdXNpsMsfr8eLdzXP8jT\/ZDA+OxG2qzxd1UaotDl\/\/NSzWjNyOYGX3pEoNk9LtefKBGKbgTvH5lrguydfN8JFb4mGjtP8wRY7tjHHq8jtLQhJMRiub3eGnR\/vxwNQk8EJ5usJxB1UF2Kl0p5LqSohViivqfXCBQ=="
]
},
{
"Key": "host",
"Value": [
"somerandomapigatewaystring.execute-api.us-west-2.amazonaws.com"
]
},
{
"Key": "x-amz-date",
"Value": [
"20161223T200041Z"
]
},
{
"Key": "Authorization",
"Value": [
"AWS4-HMAC-SHA256 Credential=********************\/20161223\/us-west-2\/execute-api\/aws4_request, SignedHeaders=host;x-amz-date, Signature=3e0d3***********************************************************"
]
}
],
"Properties": {
}
}
Вот мой код - Извиняюсь за беспорядок.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Amazon.CloudFormation;
using Amazon.IdentityManagement;
using Amazon.IdentityManagement.Model;
using Amazon.Lambda.Core;
using Amazon.Runtime.Internal;
using Amazon.Runtime.Internal.Auth;
using Amazon.SecurityToken;
using Amazon.SecurityToken.Model;
using bifrost;
using Newtonsoft.Json;
namespace Bifrost
{
public class Handler
{
private static HttpClient httpClient = new HttpClient(); //yes we want this to be static https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
private static string Service = "execute-api";
// private static string Service = "apigateway";
private static string Algorithm = "AWS4-HMAC-SHA256";
public const string Iso8601DateTimeFormat = "yyyyMMddTHHmmssZ";
public const string Iso8601DateFormat = "yyyyMMdd";
public Response Hello(Request request, ILambdaContext context)
{
try
{
var now = DateTime.Now;
var signedHeaders = new string[]
{
// "content-type",
"host", //http://docs.aws.amazon.com/general/latest/gr/rande.html#apigateway_region
"x-amz-date",
// "x-amz-security-token",
// "Authorization",
// "Credential"
};
//X-Amz-Security-Token
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, "https://somerandomapigatewaystring.execute-api.us-west-2.amazonaws.com/devcam/securehello");
httpRequest.Headers.Add("x-amz-security-token", EnvironmentVariables.SessionToken);
// httpRequest.Headers.Add("host", "apigateway.us-west-2.amazonaws.com");
httpRequest.Headers.Add("host", "somerandomapigatewaystring.execute-api.us-west-2.amazonaws.com");
httpRequest.Headers.Add("x-amz-date", now.ToString(Iso8601DateTimeFormat));
// httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
// httpRequest.Headers.Add("X-Amz-Security-Token", EnvironmentVariables.SessionToken);
string credentialScope = String.Format("{0}/{1}/{2}/aws4_request", now.ToString(Iso8601DateFormat),
EnvironmentVariables.Region, Service);
string credentialString = EnvironmentVariables.AccessKeyId + "/" + credentialScope;
string signedHeadersString = string.Join(";",
signedHeaders.Select(x => x.Trim().ToLowerInvariant()).OrderBy(x => x));
// AwsV4SignatureCalculator signatureCalculator = new AwsV4SignatureCalculator(EnvironmentVariables.SecretKey, Service, "us-west-2");
// string signature = signatureCalculator.CalculateSignature(httpRequest, signedHeaders, now);
string signature = getSignature(EnvironmentVariables.AccessKeyId, Service, "us-west-2", httpRequest, signedHeaders, now);
// task 4: add signing info to request
string authorization = CreateAuthorizationGET(signature, signedHeadersString, credentialScope);
Console.WriteLine("authorization:");
Console.WriteLine(authorization);
// The format of value 'AWS4-HMAC-SHA256 Credential=/20161222/us-west-2/execute-api/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=.
// httpRequest.Headers.Add("Authorization", authorization);
httpRequest.Headers.TryAddWithoutValidation("Authorization", authorization);
// httpRequest.Headers.TryAddWithoutValidation("Authorization", authorization + ", X-Amz-Security-Token=" + EnvironmentVariables.SessionToken);
// httpRequest.Version = Version./
var response = httpClient.SendAsync(httpRequest);
return new Response
{
Body =
"Go Serverless v1.0! Your function executed successfully!\r\n" +
JsonConvert.SerializeObject(request)
+ "\r\n\r\n" + JsonConvert.SerializeObject(context) + "\r\n\r\n" +
JsonConvert.SerializeObject(Environment.GetEnvironmentVariables()) + "\r\n\r\n" +
JsonConvert.SerializeObject(httpRequest) + "\r\n\r\n" +
JsonConvert.SerializeObject(response.Result) + "\r\n\r\n" +
// "",
response.Result.Content.ReadAsStringAsync().Result,
StatusCode = 200,
Headers = new Dictionary<string, string>()
};
}
catch (Exception e)
{
return new Response
{
StatusCode = 200,
Body = e.Message + "\r\n\r\n" + e.StackTrace +
"\r\n\r\n" + e.InnerException.StackTrace,
Headers = new Dictionary<string, string>()
};
}
}
private string getSignature(string accessKey, string service, string region, HttpRequestMessage httpRequest, string[] signedHeaders, DateTime now)
{
// httpRequest.Content = new StringContent("", Encoding.UTF8,
// "application/json");
var signedHeadersDict = createSignedHeadersDictionary(signedHeaders, httpRequest);
string hashedPayload = AWSAuthenticationHelper.HashAndHexEncodeString("");
string canonicalHeaders = string.Join("\n", signedHeadersDict.Select(x => x.Key.ToLowerInvariant() + ":" + x.Value.Trim())) + "\n";
string signedHeadersString = string.Join(";", signedHeaders);
// httpRequest.Headers.Add("X-Amz-SignedHeaders", signedHeadersString);
string canonicalRequest = AWSAuthenticationHelper.CreateCanconicalRequestGET(hashedPayload, signedHeadersString, canonicalHeaders,
httpRequest.RequestUri.AbsolutePath,
httpRequest.RequestUri.Query);
Console.WriteLine("Canonical String:");
Console.WriteLine(canonicalRequest);
string hashedCanonicalRequest = AWSAuthenticationHelper.HashAndHexEncodeString(canonicalRequest);
string dateStamp = now.ToString(Iso8601DateFormat);
string dateTimeStamp = now.ToString(Iso8601DateTimeFormat);
// httpRequest.Headers.Add("X-Amz-Date", now.ToString(Iso8601DateTimeFormat));
string credentialScope = String.Format("{0}/{1}/{2}/aws4_request", dateStamp, region, service);
// httpRequest.Headers.Add("X-Amz-Credential", credentialScope);
string stringToSign = CreateStringToSign(hashedCanonicalRequest, dateTimeStamp, credentialScope);
Console.WriteLine("stringToSign:");
Console.WriteLine(stringToSign);
// task 3: calculate signature
string signature = AWSAuthenticationHelper.CreateSignature(stringToSign, dateStamp, region, service, accessKey);
return signature;
}
private string CreateAuthorizationGET(string signature, string signedHeaders, string credentialScope)
{
return String.Format("{0} Credential={1}/{2}, SignedHeaders={3}, Signature={4}", Algorithm, EnvironmentVariables.AccessKeyId, credentialScope, signedHeaders, signature);
}
private string CreateStringToSign(string hashedRequest, string requestDate, string credentialScope)
{
string stringToSign = string.Format("{0}\n{1}\n{2}\n{3}", Algorithm, requestDate, credentialScope, hashedRequest);
return stringToSign;
}
private SortedDictionary<string, string> createSignedHeadersDictionary(string[] signedHeaders, HttpRequestMessage httpRequest)
{
SortedDictionary<string, string> ret = new SortedDictionary<string, string>();
List<string> signedHeadersList = signedHeaders.Select(x => x.ToLowerInvariant().Trim()).OrderBy(x => x).ToList();
foreach (KeyValuePair<string, IEnumerable<string>> header in httpRequest.Headers)
{
if (signedHeadersList.Contains(header.Key.ToLowerInvariant().Trim()))
{
ret.Add(header.Key, String.Join(",", header.Value)); // TODO: is tostring safe here?
}
}
if (httpRequest.Content != null && httpRequest.Content.Headers != null)
{
foreach (var contentHeader in httpRequest.Content.Headers)
{
if (signedHeaders.Contains(contentHeader.Key.ToLowerInvariant().Trim()))
{
ret.Add(contentHeader.Key, string.Join(",", contentHeader.Value));
}
}
}
// else if (signedHeadersList.Contains("content-type"))
// {
// throw new Exception("content-type header set but no Content found");
// }
return ret;
}
public Response SecureHello(Request request, ILambdaContext context)
{
return new Response
{
Body = "securely called!\r\n" + JsonConvert.SerializeObject(request)
+ "\r\n\r\n" + JsonConvert.SerializeObject(context) + "\r\n\r\n" +
JsonConvert.SerializeObject(Environment.GetEnvironmentVariables()),
StatusCode = 200,
Headers = new Dictionary<string, string>()
};
}
}
public class Response : BaseResponse
{
}
public class Request : BaseRequest
{
}
}
И еще код ...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace bifrost
{
public class AWSAuthenticationHelper
{
public static string HashAndHexEncodeString(string str)
{
return HexEncode(GenerateHash(ToBytes(str)));
}
public static string CreateSignature(string stringToSign, string dateStamp, string region, string serviceName, string awsKey)
{
byte[] key = GenerateKey(dateStamp, region, serviceName, awsKey);
return HexEncode(HmacSha256(stringToSign, key));
}
public static string CreateCanconicalRequestPOST(string hashedPayload, string signedHeaders, string canonicalHeaders, string canonicalURI)
{
string canonicalRequest = "POST" + "\n" + canonicalURI + "\n" + "" + "\n" + canonicalHeaders + "\n" +
signedHeaders + "\n" + hashedPayload;
return canonicalRequest;
}
public static string CreateCanconicalRequestGET(string hashedPayload, string signedHeaders, string canonicalHeaders, string canonicalURI, string canonicalQueryString)
{
string canonicalRequest = "GET" + "\n" +
canonicalURI + "\n" +
canonicalQueryString + "\n" +
canonicalHeaders + "\n" +
signedHeaders + "\n"
+ hashedPayload;
return canonicalRequest;
}
private static byte[] GenerateKey(string dateStamp, string region, string serviceName, string awsSecretKey)
{
byte[] kDate = HmacSha256(dateStamp, ToBytes("AWS4" + awsSecretKey));
byte[] kRegion = HmacSha256(region, kDate);
byte[] kService = HmacSha256(serviceName, kRegion);
return HmacSha256("aws4_request", kService);
}
private static string HexEncode(byte[] bytes)
{
return BitConverter.ToString(bytes).Replace("-", string.Empty).ToLowerInvariant();
}
private static byte[] ToBytes(string str)
{
return Encoding.UTF8.GetBytes(str.ToCharArray());
}
private static byte[] GenerateHash(byte[] bytes)
{
return SHA256.Create().ComputeHash(bytes);
}
private static byte[] HmacSha256(String data, byte[] key)
{
return new HMACSHA256(key).ComputeHash(ToBytes(data));
}
}
}
Обновлено Canonical Запрос Строка:
GET
/devcam/securehello
host:somerandomapigatewaystring.execute-api.us-west-2.amazonaws.com
x-amz-date:20161223T200041Z
host;x-amz-date
e3b0ooooyeaaac149afbf4c89somemorefake8888fvaluesa495991oooyea855
Обновлено Строка Вход
AWS4-HMAC-SHA256
20161223T200041Z
20161223/us-west-2/execute-api/aws4_request
01b7ad17a58c442ed893ece5acb63a650b9781e32d23cb4d4114777d224deaf7
Изменено Authorization Заголовок:
AWS4-HMAC-SHA256 Credential=ASPECIALSECRETEKEYKK/20161223/us-west-2/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=3e0immodifyingthesevaluesjusttobesafeoiuoiuoiuoiukjh8a30540609fe
вы спасли меня много времени. Спасибо u so much – Viji
@CamHart +1 Приятный и чистый пример вместе со ссылками. –