Я пытаюсь отправить электронное письмо с использованием API запросов Amazon SES Https. , но подпись, которую я рассчитываю и отправляю в aws, не принимается.Ошибка проверки подлинности API запроса API-запроса Amazon SES HTTPS
Получаю это сообщение об ошибке.
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
<Error>
<Type>Sender</Type>
<Code>SignatureDoesNotMatch</Code>
<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.</Message>
</Error>
<RequestId>c97bd130-24c9-11e6-924a-b59d7ac9182b</RequestId>
</ErrorResponse>
вот мой код Java
public class SendSESMail {
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, IOException, SignatureException {
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
String dateString = format.format(new Date());
final String ENDPOINT = "https://email.us-east-1.amazonaws.com";
final String AWS_ACCESS = "ACCESS_KEY";
final String AWS_SECRET = "SECRET_KEY";
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(ENDPOINT);
String authString = generateAuthHeader(AWS_ACCESS, AWS_SECRET, dateString);
List<NameValuePair> formVals = new ArrayList<>();
formVals.add(new BasicNameValuePair("Action", "SendRawEmail"));
formVals.add(new BasicNameValuePair("Destination.ToAddresses.member.1", "[email protected]"));
formVals.add(new BasicNameValuePair("Message.Body.Text.Data", "I hope you see the body."));
formVals.add(new BasicNameValuePair("Message.Subject.Data", "This is a Unique Subject"));
formVals.add(new BasicNameValuePair("Source", "[email protected]"));
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(formVals);
post.setHeader("Content-Type", ContentType.APPLICATION_FORM_URLENCODED.toString());
post.setHeader("Date", dateString);
post.setHeader("X-Amzn-Authorization", authString);
post.setEntity(formEntity);
HttpResponse response = httpClient.execute(post);
response.getEntity().writeTo(System.out);
}
public static String generateAuthHeader(String accessKey, String secret, String dateString) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException {
String authHeaderVal = "AWS3-HTTPS AWSAccessKeyId=" + accessKey + ",Algorithm=HmacSHA256,Signature=";
authHeaderVal += generateSignature(dateString, secret);
return authHeaderVal;
}
public static String generateSignature(String message, String secret) throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256_HMAC.init(secretKey);
return Base64.encodeBase64URLSafeString(sha256_HMAC.doFinal(message.getBytes()));
}
}
в первый раз я попробовал его, он дал мне эту ошибку
<ErrorResponse xmlns="http://ses.amazonaws.com/doc/2010-12-01/">
<Error>
<Type>Sender</Type>
<Code>ValidationError</Code>
<Message>1 validation error detected: Value null at 'rawMessage' failed to satisfy constraint: Member must not be null</Message>
</Error>
<RequestId>9a986157-24ca-11e6-9864-3fdeb433e3c8</RequestId>
</ErrorResponse>
это было потому, что подпись была «=» знак в конце, поэтому я использовал
encodeBase64URLSafeString();
метод для преобразования подписи в Base64 вместо
encodeBase64String();
Так что я здесь делаю неправильно, Пожалуйста, кто-то помочь мне здесь спасибо.
Я думаю, что строка, которую вы подписываете, неверна. Хотя это не тот же сервис, здесь приведен пример фрагмента кода Java для подписания aws-запроса HTTP с сигнатурой версии 2.http: //docs.aws.amazon.com/AWSECommerceService/latest/DG/AuthJavaSampleSig2.html – Shibashis
, но здесь http: //docs.aws.amazon.com/ses/latest/DeveloperGuide/query-interface-authentication.html он говорит «Чтобы создать строку для подписи, вычислить хеш-маркер HMAC, совместимый с RFC 2104, со значением заголовка Date, секретный ключ доступа в качестве ключа, а SHA256 или SHA1 в качестве алгоритма хеширования « –
- это именно то, что я сделал. за исключением того, что при преобразовании в Base64 я использовал версию URLSafe, а не обычный. потому что обычный имеет знак «=», который вызывает другую ошибку. –