JavaMail с MS Exchange: нет механизмов аутентификации, поддерживаемых сервером и клиентом

Я уже несколько дней пытаюсь отправить почту из приложения Grails и безуспешно. Я использую:

  • файл Grails 1.3.7
  • mail 1.0 плагин
  • spring-security-core 1.2.6 плагин
  • tomcat 7.0.23

Specifficaly я пытаюсь отправить почту с Exchange из приложения, развернутого на сервере Tomcat trought port 25 без аутентификации, без SSL.

Я попытался отправить сообщение с telnet из Виртуальная машина VMWare, на которой развернуто приложение, и она получила корыто.

Это мой класс для отправки писем:

public boolean sendMessage(String to, String msgSubject, String msgText) 
{
    String host = "mail.mydomain.com";
    String username = "myuser@mydomain.com"; // your authsmtp username
    String password = "mypassword" // your authsmtp password
    String from = "myuser@mydomain.com";

    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:*возможно ли, что есть некоторые проблемы с отправкой почты с помощью javaMail с Exchange server SMTP, когда нет проверка подлинности?

6 ответов


Если вы пытаетесь подключиться к почтовому серверу без аутентификация, вызовите метод connect, который не взять имя пользователя и пароль. Если вы передадите ему имя пользователя и пароль, он подумает, что вы действительно хотите аутентифицироваться, и поскольку он не может найти механизм аутентификации, который поддерживает сервер, он терпит неудачу.


в моем случае, я должен был установить свойство

"mail.smtp.ehlo"

to "false"

(в дополнение к добавлению к установлению имущества "mail.smtp.auth" to "false" который, однако, кажется по умолчанию в соответствии с этой ссылке)

перед "mail.smtp.ehlo" to "false" Я видел следующий вывод отладки (включен, установив свойство "mail.debug" to "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 = "myusername@mymailserver.com"; 
        String password = "xxx"; 
        String from = "myusername@mymailserver.com";
        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){}
    }
}
}

  1. проверьте, если сервер вы нажмете мандаты аутентификации или не. подробнее об этом в Кодексе.

  2. положите почту.отладка в свойства знать, что именно происходит между вашим кодом и почтовый сервер. подробнее об этом в Кодексе.

вот простой код, который хорошо работает для меня с почтовым сервером моей компании:

 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("sadique.khan@mycompany123.com","xxxxxxxxxxx");
                }
            });

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("sadique.khan@mycompany123.com"));
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse("my.bestfriend@mycompany123.com"));
            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 <xxx@tricascade.com>
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); 

to

props.put("mail.smtp.auth", true);