带有MS Exchange的JavaMail:服务器和客户端都不支持身份验证机制

时间:2011-12-23 11:49:34

标签: java authentication grails javamail exchange-server

我几天来一直试图从Grails应用程序发送邮件但没有成功。我正在使用:

  • grails 1.3.7
  • mail 1.0插件
  • spring-security-core 1.2.6插件
  • tomcat 7.0.23

Specifficaly我正在尝试使用部署在Tomcat服务器端口25上的应用程序发送邮件,而没有身份验证,没有SSL。

我尝试从部署了应用程序的VMWare虚拟机发送带有telnet的消息,但它已经过了。

这是我发送邮件的课程:

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)

我已经阅读了几十篇文章,考虑过这样的问题,但我仍然无法解决问题。任何帮助表示赞赏。

* 编辑: *如果没有身份验证,是否可能在使用带有Exchange服务器SMTP的javaMail发送邮件时出现问题?

5 个答案:

答案 0 :(得分:19)

如果您尝试连接到没有身份验证的邮件服务器,请调用获取用户名和密码的connect方法。如果您传递了用户名和密码,它认为您确实想要进行身份验证,并且由于找不到服务器支持的身份验证机制,它就会失败。

答案 1 :(得分:17)

就我而言,我必须设置属性

"mail.smtp.ehlo"

"false"

(除了添加将属性"mail.smtp.auth"设置为"false",然而根据this link,这似乎是默认属性

在将"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服务器)

答案 2 :(得分:1)

  1. 检查您要服务的服务器是否要求进行身份验证或 不。更多关于代码的内容。

  2. 请将mail.debug放入 属性,以了解您的代码和代码之间究竟发生了什么 邮件服务器。更多关于代码的内容。

  3. 这是一个简单的代码,适用于我公司的邮件服务器:

     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);
            }
        }
     }
    

答案 3 :(得分:0)

这是我的解决方案,也许这不是最好的方式,但它对我有用......

在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;
    }

}

答案 4 :(得分:0)

如果您希望您的应用程序登录SMTP服务器(因为您提供身份验证详细信息)。只需改变

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

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