Grailsアプリケーションからメールを送信しようとして何日も試みましたが、失敗しました。私が使用しているもの:
具体的には、TomcatサーバーにデプロイされたアプリケーションからExchangeを使用してメールを送信しようとしています。ポート25は、認証もSSLも使用していません。
アプリがデプロイされているVMWare仮想マシンからtelnetでメッセージを送信しようとしましたが、トラフになりました。
これはメールを送信するための私のクラスです:
public boolean sendMessage(String to, String msgSubject, String msgText)
{
String Host = "mail.mydomain.com";
String username = "[email protected]"; // your authsmtp username
String password = "mypassword" // your authsmtp password
String from = "[email protected]";
Properties props = System.getProperties();
props.put("mail.smtp.Host", Host);
props.put("mail.smtp.user", username);
props.put("mail.smtp.password", password);
props.put("mail.smtp.port", "25"); // thish is the port recommended by authsmtp
props.put("mail.smtp.auth", "false");
Session session = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress to_address = new InternetAddress(to);
message.addRecipient(Message.RecipientType.TO, to_address);
message.setSubject(msgSubject);
message.setText(msgText);
Transport transport = session.getTransport("smtp");
transport.connect(Host, username, password);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
return true;
}
これはエラースタックトレースです:
javax.mail.AuthenticationFailedException: No authentication mechansims supported by both server and client
at com.Sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.Java:590)
at javax.mail.Service.connect(Service.Java:291)
at javax.mail.Service.connect(Service.Java:172)
at javax.mail.Service$connect.call(Unknown Source)
at org.helpdesk.MymailService.sendMessage(MymailService.groovy:37)
at org.helpdesk.MymailService$sendMessage.call(Unknown Source)
at org.helpdesk.RequestController$_closure13.doCall(RequestController.groovy:247)
at org.helpdesk.RequestController$_closure13.doCall(RequestController.groovy)
at Java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at Java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at Java.lang.Thread.run(Unknown Source)
私はこのような問題を考慮して数十の投稿を読みましたが、まだ問題を解決することができていません。どんな助けでも大歓迎です。
* EDIT: *認証がない場合、ExchangeサーバーSMTPでjavaMailを使用してメールを送信する際に問題が発生する可能性はありますか?
メールサーバーに接続しようとしている場合なし認証、しないユーザー名とパスワードを取得するconnectメソッドを呼び出します。ユーザー名とパスワードを渡すと、本当に認証したいと考え、サーバーがサポートする認証メカニズムが見つからないため、失敗します。
私の場合、プロパティを設定する必要がありました
"mail.smtp.ehlo"
to "false"
(プロパティ"mail.smtp.auth"
を"false"
に設定することに加えて、これは このリンク によるとデフォルトのようです)
"mail.smtp.ehlo"
を"false"
に設定する前に、次のデバッグ出力が表示されました(プロパティ"mail.debug"
を"true"
に設定すると有効になります)。
DEBUG SMTP: Attempt to authenticate using mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM
DEBUG SMTP: mechanism LOGIN not supported by server
DEBUG SMTP: mechanism PLAIN not supported by server
DEBUG SMTP: mechanism DIGEST-MD5 not supported by server
DEBUG SMTP: mechanism NTLM not supported by server
次に、同じjavax.mail.AuthenticationFailedException
を取得します。
(この場合、SMTPサーバーはMicrosoftサーバーでした)
さて、問題はほとんどなかったようです。最初は、Exchangeが正しくセットアップされていませんでした。そして、私はすべての可能な構成を試したようですが、正しいものです。これは機能します:
class MymailService
{
boolean transactional = false
public sendMessage(String to, String cc, String msgSubject, String msgText)
{
String Host = "mail.mailserver.com";
String username = "[email protected]";
String password = "xxx";
String from = "[email protected]";
String port = "25";
Properties props = System.getProperties();
props.put("mail.smtp.Host", Host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "false");
Transport transport = null;
try{
Session session = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress to_address = new InternetAddress(to);
message.addRecipient(Message.RecipientType.TO, to_address);
InternetAddress cc_address = new InternetAddress(cc);
message.addRecipient(Message.RecipientType.CC, cc_address);
message.setSubject(msgSubject);
message.setText(msgText);
transport = session.getTransport("smtp");
transport.connect();
transport.sendMessage(message, message.getAllRecipients());
} finally {
if (transport != null) try { transport.close(); } catch (MessagingException logOrIgnore){}
}
}
}
最後の手がかりはビル・シャノンの投稿でした。ありがとうビル!
ヒットしているサーバーが認証を義務付けているかどうかを確認します。これについては、コードで詳しく説明します。
プロパティにmail.debugを入れて、コードとメールサーバーの間で何が起こっているかを正確に把握してください。これについては、コードで詳しく説明します。
これは、私の会社のメールサーバーでうまく機能する簡単なコードです。
package com.datereminder.service;
import Java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class ReminderDaemonService2 {
/**
* @param args
*/
public static void main(String[] args) {
Properties props = new Properties();
props.put("mail.smtp.Host", "mail.mycompany123.com");
// this mandates authentication at the mailserver
props.put("mail.smtp.auth", "true");
// this is for printing debugs
props.put("mail.debug", "true");
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("[email protected]","xxxxxxxxxxx");
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse("[email protected]"));
message.setSubject("Testing Subject");
message.setText("Dear Friend," +
"\n\n This is a Test mail!");
Transport.send(message);
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
これが私の解決策です、多分それは最善の方法ではありませんが、それは私にとってはうまくいきます...
mail-config.xml内:
<bean id="mailSender" class="com.xxx.service.MailSender">
<property name="Host" value="${mail.Host}" />
<property name="port" value="${mail.port}" />
<property name="protocol" value="${mail.protocol}" />
<property name="defaultEncoding" value="UTF-8" />
<property name="authRequired" value="${mail.auth}" />
<property name="username" value="${mail.username}" />
<property name="password" value="${mail.password}" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtps.auth">${mail.auth}</prop>
</props>
</property>
</bean>
設定は次のとおりです。
mail.from=XXX Team <[email protected]>
mail.Host=exchange.xxx.com
mail.port=25
mail.protocol=smtp
mail.auth=false
mail.username=
mail.password=
そして最後に、コード:
package com.xxx.service;
import org.springframework.mail.javamail.JavaMailSenderImpl;
public class MailSender extends JavaMailSenderImpl {
private boolean authRequired;
@Override
public String getUsername() {
if (!authRequired) {
return null;
}
return super.getUsername();
}
@Override
public String getPassword() {
if (!authRequired) {
return null;
}
return super.getPassword();
}
public boolean isAuthRequired() {
return authRequired;
}
public void setAuthRequired(boolean authRequired) {
this.authRequired = authRequired;
}
}
SMTPサーバーにログインするアプリケーションが必要な場合(認証の詳細を提供しているため)。変更するだけ
props.put("mail.smtp.auth", false);
に
props.put("mail.smtp.auth", true);