带有MS Exchange的JavaMail:服务器和客户端都不支持身份验证机制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带有MS Exchange的JavaMail:服务器和客户端都不支持身份验证机制相关的知识,希望对你有一定的参考价值。
我几天来一直试图从Grails应用程序发送邮件但没有成功。我正在使用:
- grails 1.3.7
- 邮件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发送邮件时出现问题?
如果您尝试在未经身份验证的情况下连接到邮件服务器,请调用不带用户名和密码的connect方法。如果您传递用户名和密码,它认为您确实要进行身份验证,并且由于无法找到服务器支持的身份验证机制,因此无法进行身份验证。
在我的情况下,我不得不设置属性
"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的)
好吧,看起来我几乎没有问题。起初,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){}
}
}
}
最后的线索是Bill Shannon的帖子。谢谢比尔!
- 检查您遇到的服务器是否要求进行身份验证。在代码中更多关于此。
- 请在属性中放置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("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," +
"
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);
至
props.put("mail.smtp.auth", true);
以上是关于带有MS Exchange的JavaMail:服务器和客户端都不支持身份验证机制的主要内容,如果未能解决你的问题,请参考以下文章
使用 JavaMail 读取电子邮件时,MimeMultipart 计数为零
javamail 发送邮件时 No authentication mechansims supported by both server and client