Use spring-cloud-aws-message without credentials to confirm a SNS subscription - amazon-web-services

I'm using spring-cloud-aws-messaging to be able to easily confirm SNS topic subscription and receive notification through an HTTPS endpoint in my service.
#NotificationSubscriptionMapping
public void confirmSubscription(final NotificationStatus status) {}
For that specific process, aws credentials shouldn't be necessary, the flow is validated through a certificate validation between SNS request to my service and a call to the provided URL matching the certificate's signature, but still when SNS tries to confirm the subscription I get:
com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY))
Is there a way to go around it?
Here we can find an example of someone that could do it using the .NET aws-sdk directly:
Use AWS SDK without credentials to confirm a SNS subscription --> No RegionEndpoint or ServiceURL configured
So it's probably possible to do it in java with the SDK directly but I still wonder if with spring-cloud-aws it's possible.
I appreciate a lot any help,
Cheers!

Related

How to Send Emails With reactjs Using Amazon SES

i want to connect my simple REACTJS contact form to my AWS SES email to receive emails
I did some researches about this but did not find a useful tutorial or article to follow it
is there anyone who can help!?
THANKS
There is a tutorial to do just what you asked for: https://www.youtube.com/watch?v=HiHflLTqiwU
In short: You set up an AWS IAM user with limited permissions to AWS SES. The user has only programmatic access to the AWS console. You will use the secret key and key ID in your React app later on, so make sure to save it. Also, make sure you are familiar with the SES pricing
Then, go ahead and configure AWS SES to your needs.
Your React App will need to run with an ExpressJS backend. Add the JavaScript AWS SDK to your project. It is needed to connect to AWS and interact with SES. Here the link to the AWS SES SDK documentation
The tutorial is great. However, there are some things to look out for:
Make sure you don't check in your access key and secret to a VCS.
The AWS access key will never be renewed. This can be ok but should be avoided
Regularly rotating your IAM credentials helps prevent a compromised set of IAM access keys from accessing components in your AWS account. Rotating IAM credentials is also an important part of security best practices in IAM. (Source)
You send e-mails through a public, unauthenticated POST request to your express backend. Anybody with their browser's devtools open can see the POST request. including the headers, the request body, and repsonse. With Postman, or a similar tool, anybody can spam your contact endpoint. To avoid that you can setup rate limits, put an API Gateway, with quotas in the middle instead of calling SES directly, etc.

Sending email using AWS API without Secret Key and Access Key Id

I know close to nothing about AWS. But I want to use AWS SDK in my Springboot project to send email via SES. I am to send the emails as a delegate user, and all I have is the Identity user's ARN. I tried the code available on the AWS website and set X-SES-SOURCE-ARN header as the identity user's ARN, and I am getting Unable to load AWS credentials from any provider in the chain error. Do I need to add any sort of ACCESS-KEY-ID and SECRET-KEY?
You might be confusing IAM identity with email/domain identities.
IAM handles authorization for the API call (AWS sigv4).
SES identities are internal to the service and just represent an authorized sending email address or domain (one that has performed verification steps).
To make a successful call you need to have both of those:
An IAM principal with authorization for ses:SendEmail in the account.
A verified email or domain identity in the account that is passed as the source ARN in your API call.
If you are using sending authorization policies then things require a little more setup but is essentially the same.
You can add the accessKey and secretKey on a file named AwsCredentials.properties. Next, when you configure the AWS SES Client, you load that file, as in the following example with Cognito.
public AWSCognitoIdentityProvider getAmazonCognitoIdentityClient() {
ClasspathPropertiesFileCredentialsProvider propertiesFileCredentialsProvider = new ClasspathPropertiesFileCredentialsProvider();
return AWSCognitoIdentityProviderClientBuilder.standard().withCredentials(propertiesFileCredentialsProvider)
.withRegion(props.getRegion()).build();
}

Getting error while invoking API using AWS Lambda. (AWS Lambda + AWS API Gateway+ Postman)

I get an error while invoking the AWS SageMaker endpoint API from a Lambda function. When I call this using Postman, I am getting an error like:
{
"errorMessage": "module initialization error"
}
Just to make it clear, you can't call SageMaker endpoints directly using PostMan (even if it is, it would not be straightforward).
You may need to use AWS SDK (i.e. boto) for that.
Ref : https://aws.amazon.com/blogs/machine-learning/call-an-amazon-sagemaker-model-endpoint-using-amazon-api-gateway-and-aws-lambda/
What I would suggest is to create a small HTTP server with Flask and use the AWS SDK (Boto) to call the endpoint. Then you can call your Flask endpoint using PostMan.
We recommend using AWS SDK to invoke your endpoint. AWS SDK clients handle the serialization for you as well as request signing, etc. It would be really hard to get it right manually with postman.
We have the SDK client available in many languages, including Java, Python, JS, etc.
https://docs.aws.amazon.com/sagemaker/latest/dg/API_runtime_InvokeEndpoint.html#API_runtime_InvokeEndpoint_SeeAlso
Next time please include more details in your question. eg. POST request data, Headers etc.
Anyways, to help you out in calling Sagemaker endpoint using Postman -
In 'Authorization' tab, select type as 'AWS Signature'.
Enter your Access and Secret key of the IAM user which has permission to Sagemaker resources.
Enter the AWS region. eg.us-east-1
Enter 'Service Name' as 'sagemaker'
Select the right content type. Some ML algorithms only accept 'text/csv'.
Select request type as 'POST'
Enter the Sagemaker Invocation url. eg:'https://runtime.sagemaker.us-east-1.amazonaws.com/endpoints/xgboost-xxxx-xx-xx-xx-xx-xx-xxx/invocations'
Try it out and let me know if you have any issues.
Here is how your Postman should look -

Cross account, cross region SNS message processing

We are working on SNS to HTTPS API integration between 2 teams. So, another team has SNS topic configured in us-east-1 region and our HTTPS API is running in us-west-2 region.
Just wanted to check if we can process SNS messages generated from us-east-1 and a different AWS account in us-west-2 region.
I read somewhere (can't remember the blog post link now), that if SNS messages are generated in us-east-1, they have to be processed in us-east-1 only. If we try to process in us-east-2, message signature verification will fail and throws an invalid TopicArn exception.
Please guide if this is correct.
So, another team has SNS topic configured in us-east-1 region and our HTTPS API is running in us-west-2 region.
When SNS is publishing to an HTTPS endpoint, the endpoint can be anywhere on the Internet. It doesn't even need to be in AWS at all. As long as your HTTPS endpoint is accessible from the Internet and has a valid SSL certificate (matches the hostname, not expired, signed by an accredited certificate authority, not self-signed), that is all SNS will require.
The destination region and destination AWS account lose all meaningfulness in such a setup. There is no constraint, here.
If the topic is in us-east-1 then all requests sent to SNS must be sent to the us-east-1 endpoint (e.g. Subscribe or Publish) but even then, they can be sent from anywhere on the Internet.
SNS can be configured across regions via HTTPS endpoint of lambda by attaching the API Gateway to that lambda and copying the HTTPS URL of same.
After getting the HTTPS URL of the lambda may be whichever region. It may be that you just add in SNS service subscription part in SNS service by creating the subscription in the service.
After that, just publish a message. You will see entries in your Cloudwatch logs if you print an event in lambda. You will see something like "Subscribe URL". Copy that URL and paste it in the SNS service where you will be able to see "Pending on Subscription". This will work with latest amazon SNS service.
I tried and tested it to verify that this works.

AWS ElasticSearch Client SDK

Is there any AWS ElasticSearch Client SDK for Java, which signs the requests with AWS credentials? I saw this, but I guess its for managing AWS Elasticsearch Service.
You can create AWS client for Elasticsearch in the following way:
AwsClientBuilder.withCredentials(AWSCredentialsProvider) for example: AWSElasticsearchClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).build();
How I do this is by first creating AWSBasicSessionCredential instance by providing awsAccessKey, awsSecretKey, and sessionToken information and then passing this instance in the above code to build the client instance. However, I do this for test programming the clients. Its not advised to create a client this way though. For example, one secure way would be using federated identification to generate a temporary security token and then use that to assume a role through AWS' AssumeRoleRequest, receive its response in the form of AssumeRoleResult and then retrieve credential information from the assumeRoleResult response received above. Use this credential information in generating AWSCredential.
Source of generating AWS Elasticsearch client.