AWS SES在Spring Boot Java中的实现,无需使用凭证。

huangapple go评论74阅读模式
英文:

AWS SES implement In spring boot java without using credential

问题

我是一名后端开发者(使用Spring Boot),DevOps团队要求我实现AWS的SES和SNS服务,但不能使用凭证,因为它们与AWS中的IAM角色使用相同的凭证存储,所以他们希望我在代码中仅传递主机,将凭证部分留空,然后它将向特定收件人发送电子邮件。(根据他们的要求)

正如他们所说,我尝试在Java中使用空凭证,但是这并没有起作用,它显示无效的身份验证。

我不知道他们是如何实现这个相同的功能的,他们使用了PHP的SDK,将凭证部分留空,并且在IAM角色凭证下正常工作。

以下是我留空凭证部分的代码:

private boolean sendAwsMail() {
    String result = null;
    boolean flag = true;
    try {
        Properties props = System.getProperties();
        props.put("mail.transport.protocol", varMap.get("protocol"));
        props.put("mail.smtp.port", Integer.parseInt(varMap.get("port")));
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");
        Session session = Session.getDefaultInstance(props);
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("no-reply@lottoweaver.com", "lottoweaver.com"));
        msg.setRecipient(Message.RecipientType.TO, new InternetAddress(varMap.get("destinationMailId")));
        msg.setSubject(varMap.get("subject"));
        msg.setContent(varMap.get("content"), "text/html");
        Transport transport = session.getTransport();
        transport.connect("email-smtp.us-west-2.amazonaws.com", "", "");
        transport.sendMessage(msg, msg.getAllRecipients());
        AppLogger.writeLog("INFO", "MAIL_SEND", "send_mail", this.getClass().getName(),
                Thread.currentThread().getStackTrace()[1].getMethodName(),
                "toMailId:" + varMap.get("destinationMailId"), "subject:" + varMap.get("subject"), "", "", null,
                null, "");
        result = varMap.get("content");
        transport.close();
    } catch (Exception ex) {
        AppLogger.writeLog("WARNING", "Issue_In_Connection", "send_mail", this.getClass().getName(),
                Thread.currentThread().getStackTrace()[1].getMethodName(),
                "toMailId:" + varMap.get("destinationMailId"), "subject:" + varMap.get("subject"), "", "", null, ex,
                "");
        flag = false;
        result = ex.toString();
    } finally {
        this.flag = flag;
        dumpList.add(new MessageDataDump(varMap.get("destinationMailId"), result, varMap, "AWS-EMAIL"));
        return flag;
    }
}

我用以下内容替换了 msg.setFrom(new InternetAddress(varMap.get("fromEmail"), varMap.get("fromName")));

msg.setFrom(new InternetAddress("no-reply@lottoweaver.com", "lottoweaver.com"));

并且在凭证部分也进行了同样的替换,即 transport.connect(varMap.get("HOST"), varMap.get("SMTP_USERNAME"), varMap.get("SMTP_PASSWORD")); 替换为 transport.connect("email-smtp.us-west-2.amazonaws.com", "", "");

请指导我正确实现这一点。提前感谢您的帮助。

英文:

I am a Backend Developer (Spring boot) and the DevOps team wants me to implement the SES and SNS service of AWS but without using credentials as they are stored the same credentials with IAM Role in aws so they want to me pass the only host in code and left credential part empty and it will send email to particular recipient.(as per their concern)

So as they said I did try with empty credentials in java but that didn't work it says Invalid authentication

I don't know how but they did implement this same thing with PHP SDKs they left the credentials part empty and it works fine with IAM role credentials

Here is my code Where I left the credential part empty

private boolean sendAwsMail() {
String result = null;
boolean flag = true;
try {
Properties props = System.getProperties();
props.put("mail.transport.protocol", varMap.get("protocol"));
props.put("mail.smtp.port", Integer.parseInt(varMap.get("port")));
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("no-reply@lottoweaver.com", "lottoweaver.com"));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(varMap.get("destinationMailId")));
msg.setSubject(varMap.get("subject"));
msg.setContent(varMap.get("content"), "text/html");
Transport transport = session.getTransport();
transport.connect("email-smtp.us-west-2.amazonaws.com", "", "");
transport.sendMessage(msg, msg.getAllRecipients());
AppLogger.writeLog("INFO", "MAIL_SEND", "send_mail", this.getClass().getName(),
Thread.currentThread().getStackTrace()[1].getMethodName(),
"toMailId:" + varMap.get("destinationMailId"), "subject:" + varMap.get("subject"), "", "", null,
null, "");
result = varMap.get("content");
transport.close();
} catch (Exception ex) {
AppLogger.writeLog("WARNING", "Issue_In_Connection", "send_mail", this.getClass().getName(),
Thread.currentThread().getStackTrace()[1].getMethodName(),
"toMailId:" + varMap.get("destinationMailId"), "subject:" + varMap.get("subject"), "", "", null, ex,
"");
flag = false;
result = ex.toString();
} finally {
this.flag = flag;
dumpList.add(new MessageDataDump(varMap.get("destinationMailId"), result, varMap, "AWS-EMAIL"));
return flag;
}
}

I replaced msg.setFrom(new InternetAddress(varMap.get("fromEmail"), varMap.get("fromName")));
with msg.setFrom(new InternetAddress("no-reply@lottoweaver.com", "lottoweaver.com"));

and also replaced same at credentail part that is transport.connect(varMap.get("HOST"), varMap.get("SMTP_USERNAME"), varMap.get("SMTP_PASSWORD")); with transport.connect("email-smtp.us-west-2.amazonaws.com", "", "");

please point me a correct way to achieve this.

Thanks in advance

答案1

得分: 2

执行代码时,AWS SDK 将使用凭证链来查找您的凭证:https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html

SDK 将沿着这条链路工作,尝试查找凭证。对于在本地机器上工作的开发人员,通常会通过以下方式获取您的凭证:a)aws 凭证文件;b)将 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 设置为环境变量。

当您在服务器上运行代码时,情况会稍微有些不同。在这种情况下,凭证将应用于实例角色。基本上,不需要传递任何凭证,因为代码在 AWS 服务器上运行,AWS 知道它具有什么权限,这是通过 IAM 实例角色进行设置的。

简而言之,当您在本地时,您需要传递凭证,但不用担心,如果您的同事已正确设置服务器,您在服务器上运行代码时将不需要传递凭证。

编辑:您需要使用 Java SDK 来访问凭证链:https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-java.html

英文:

When you execute your code, the AWS SDK will use a credential chain to find your credentials:
https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html

The SDK will work down this chain, trying to find credentials. For a developer working on a local machine you credentials are normally picked up either by a) the aws credentials file or b) setting AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as environment variables.

Things work slightly differently when you are running your code on the server. In this case, the credentials are applied to an instance role. Basically, no credentials need to be passed, as the code is on an AWS server, AWS knows what permissions it has, as set through an IAM instance role.

In short, you need to pass credentials when you're on local, but don't worry, if your colleagues have setup the server correctly, you won't need to pass credentials when you're on the server.

EDIT: You will need to use the Java SDK to access the credential chain
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-java.html

huangapple
  • 本文由 发表于 2020年9月9日 13:08:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/63805087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定