javax.mail.AuthenticationFailedException:连接失败,没有指定密码?

时间:2011-07-07 12:27:07

标签: java smtp gmail javax.mail

此程序尝试发送电子邮件但会引发运行时异常:

javax.mail.AuthenticationFailedException: failed to connect, no password specified?

为我提供正确的用户名和密码进行身份验证时,为什么会出现此异常?

发件人和收件人都有g-mail帐户。发件人和收件人都有g-mail帐号。发件人已禁用两步验证流程。

这是代码:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

class tester {
    public static void main(String args[]) {
        Properties props = new Properties();
        props.put("mail.smtp.host" , "smtp.gmail.com");
        props.put("mail.stmp.user" , "username");

        //To use TLS
        props.put("mail.smtp.auth", "true"); 
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.password", "password");
        //To use SSL
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", 
            "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "465");


        Session session  = Session.getDefaultInstance( props , null);
        String to = "me@gmail.com";
        String from = "from@gmail.com";
        String subject = "Testing...";
        Message msg = new MimeMessage(session);
        try {
            msg.setFrom(new InternetAddress(from));
            msg.setRecipient(Message.RecipientType.TO, 
                new InternetAddress(to));
            msg.setSubject(subject);
            msg.setText("Working fine..!");
            Transport transport = session.getTransport("smtp");
            transport.connect("smtp.gmail.com" , 465 , "username", "password");
            transport.send(msg);
            System.out.println("fine!!");
        }
        catch(Exception exc) {
            System.out.println(exc);
        }
    }
}

即使在给出密码后我也得到了例外。为什么不进行身份验证?

14 个答案:

答案 0 :(得分:10)

您需要将对象身份验证作为参数添加到会话中。比如

Session session = Session.getDefaultInstance(props, 
    new javax.mail.Authenticator(){
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(
                "XXXX@gmail.com", "XXXXX");// Specify the Username and the PassWord
        }
});

现在你不会得到这种例外......

javax.mail.AuthenticationFailedException: failed to connect, no password specified?

答案 1 :(得分:9)

尝试创建一个javax.mail.Authenticator对象,并将其与属性对象一起发送到Session对象。

Authenticator 编辑:

您可以修改此选项以接受用户名和密码,您可以将其存储在那里或任何您想要的位置。

public class SmtpAuthenticator extends Authenticator {
public SmtpAuthenticator() {

    super();
}

@Override
public PasswordAuthentication getPasswordAuthentication() {
 String username = "user";
 String password = "password";
    if ((username != null) && (username.length() > 0) && (password != null) 
      && (password.length   () > 0)) {

        return new PasswordAuthentication(username, password);
    }

    return null;
}

在您发送电子邮件的班级中:

SmtpAuthenticator authentication = new SmtpAuthenticator();
javax.mail.Message msg = new MimeMessage(Session
                    .getDefaultInstance(emailProperties, authenticator));

答案 2 :(得分:3)

您的电子邮件会话应提供验证者实例,如下所示

Session session = Session.getDefaultInstance(props,
    new Authenticator() {
        protected PasswordAuthentication  getPasswordAuthentication() {
        return new PasswordAuthentication(
                    "myemail@gmail.com", "password");
                }
    });

这里有一个完整的例子http://bharatonjava.wordpress.com/2012/08/27/sending-email-using-java-mail-api/

答案 3 :(得分:2)

除了RMT的回答。我也不得不修改一下代码。

  1. 应以静态方式访问Transport.send
  2. 因此,transport.connect没有为我做任何事情,我只需要在初始的Properties对象中设置连接信息。
  3. 这是我的示例send()方法。配置对象只是一个愚蠢的数据容器。

    public boolean send(String to, String from, String subject, String text) {
        return send(new String[] {to}, from, subject, text);
    }
    
    public boolean send(String[] to, String from, String subject, String text) {
    
        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", config.host);
        props.put("mail.smtp.user", config.username);
        props.put("mail.smtp.port", config.port);
        props.put("mail.smtp.password", config.password);
    
        Session session = Session.getInstance(props, new SmtpAuthenticator(config));
    
        try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            InternetAddress[] addressTo = new InternetAddress[to.length];
            for (int i = 0; i < to.length; i++) {
                addressTo[i] = new InternetAddress(to[i]);
            }
            message.setRecipients(Message.RecipientType.TO, addressTo);
            message.setSubject(subject);
            message.setText(text);
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    

答案 4 :(得分:2)

我已在Transport.send电话中解决了此问题添加用户和密码

Transport.send(msg, "user", "password");

根据javax.mail中send function的签名(来自version 1.5 ):

public static void send(Message msg, String user, String password)

此外,如果您使用此签名,则无需设置任何Authenticator,并在Properties中设置用户和密码(仅需要主机)。所以你的代码可能是:

private void sendMail(){
  try{
      Properties prop = System.getProperties();
      prop.put("mail.smtp.host", "yourHost");
      Session session = Session.getInstance(prop);
      Message msg = #createYourMsg(session, from, to, subject, mailer, yatta yatta...)#;
      Transport.send(msg, "user", "password");
  }catch(Exception exc) {
      // Deal with it! :)
  }
}

答案 5 :(得分:1)

可能值得验证gmail帐户由于多次登录尝试失败而未被锁定,您可能需要重置密码。我和你有同样的问题,结果证明这是解决方案。

答案 6 :(得分:1)

我也有这个问题所以不用担心。由于外部身份验证问题,它来自邮件服务器端。打开邮件,您将收到来自邮件服务器的邮件,告知您启用辅助功能。完成后,重试您的程序。

答案 7 :(得分:0)

import java.util.Properties;

import javax.mail.Authenticator;
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;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

@SuppressWarnings("serial")
public class RegisterAction {


    public String execute() {


         RegisterAction mailBean = new RegisterAction();

           String subject="Your username & password ";

           String message="Hi," + username;
          message+="\n \n Your username is " + email;
          message+="\n \n Your password is " + password;
          message+="\n \n Please login to the web site with your username and password.";
          message+="\n \n Thanks";
          message+="\n \n \n Regards";

           //Getting  FROM_MAIL

           String[] recipients = new String[1];
            recipients[0] = new String();
            recipients[0] = customer.getEmail();

           try{
          mailBean.sendMail(recipients,subject,message);

          return "success";
          }catch(Exception e){
           System.out.println("Error in sending mail:"+e);
          }

        return "failure";
    }

    public void sendMail( String recipients[ ], String subject, String message)
             throws MessagingException
              {
                boolean debug = false;

                 //Set the host smtp address

                 Properties props = new Properties();
                 props.put("mail.smtp.host", "smtp.gmail.com");
                 props.put("mail.smtp.starttls.enable", true);
                 props.put("mail.smtp.auth", true);

                // create some properties and get the default Session

                Session session = Session.getDefaultInstance(props, new Authenticator() {

                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(
                                "username@gmail.com", "5373273437543");// Specify the Username and the PassWord
                    }

                });
                session.setDebug(debug);


                // create a message
                Message msg = new MimeMessage(session);


                InternetAddress[] addressTo = new InternetAddress[recipients.length];
                for (int i = 0; i < recipients.length; i++)
                {
                  addressTo[i] = new InternetAddress(recipients[i]);
                }

                msg.setRecipients(Message.RecipientType.TO, addressTo);

                // Optional : You can also set your custom headers  in the Email if you Want
                //msg.addHeader("MyHeaderName", "myHeaderValue");

                // Setting the Subject and Content Type
                msg.setSubject(subject);
                msg.setContent(message, "text/plain");

                //send message
                Transport.send(msg);

                System.out.println("Message Sent Successfully");
              }

}

答案 8 :(得分:0)

即使使用Authenticator,我也必须将mail.smtp.auth属性设置为true。这是一个有效的例子:

final Properties props = new Properties();
props.put("mail.smtp.host", config.getSmtpHost());
props.setProperty("mail.smtp.auth", "true");

Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator()
{
  protected PasswordAuthentication getPasswordAuthentication()
  {
    return new PasswordAuthentication(config.getSmtpUser(), config.getSmtpPassword());
  }
});

答案 9 :(得分:0)

开启&#34;访问不太安全的应用&#34;在gmail帐户的安全设置中(来自邮件),请参阅以下链接以获取参考资料

http://www.ghacks.net/2014/07/21/gmail-starts-block-less-secure-apps-enable-access/

答案 10 :(得分:0)

此错误可能与密码字符有关。如果您的密码包含特殊字符,并且您还将密码添加到Transport类方法中;

例如

Transport transport = session.getTransport("smtp");
transport.connect("user","passw@rd");

Transport.send(msg, "user", "passw%rd");

您可能会收到该错误。因为Transport类'方法可能无法处理特殊字符。如果您使用javax.mail.PasswordAuthentication课程将您的用户名和密码添加到邮件中,我希望您能够避免该错误;

例如

...
Session session = Session.getInstance(props, new javax.mail.Authenticator()
{
  protected PasswordAuthentication getPasswordAuthentication()
  {
    return new PasswordAuthentication("user", "pas$w@r|d");
  }
});

Message message = new MimeMessage(session);
...
Transport.send(message);

答案 11 :(得分:0)

请参见代码的9行,可能是错误;应该是:

mail.smtp.user 

不是

mail.stmp.user;

答案 12 :(得分:0)

首先,在您的Gmail帐户中启用安全性较低的应用程序,您可以使用以下链接从中发送电子邮件:-https://myaccount.google.com/lesssecureapps?pli=1

然后,您只需在会话创建中添加以下代码。它将正常工作。

Session mailSession = Session.getInstance(props, new javax.mail.Authenticator(){
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                    "your_email", "your_password");// Specify the Username and the PassWord
            }
        });

如果您想要更详细的说明,请使用以下命令:-

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class MailSender {

    public Properties mailProperties() {
        Properties props = new Properties();

        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.host", "smtp.gmail.com");
        props.setProperty("mail.smtp.port", "587");
        props.setProperty("mail.smtp.user", "your_email");
        props.setProperty("mail.smtp.password", "your_password");
        props.setProperty("mail.smtp.starttls.enable", "true");
        props.setProperty("mail.smtp.auth", "true");

        return props;
    }

    public String sendMail(String from, String to, String subject, String msgBody) {
        Properties props = mailProperties();
        Session mailSession = Session.getInstance(props, new javax.mail.Authenticator(){
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(
                    "your_email", "your_password");// Specify the Username and the PassWord
            }
        });

        mailSession.setDebug(false);

        try {
            Transport transport = mailSession.getTransport();

            MimeMessage message = new MimeMessage(mailSession);
            message.setSubject(subject);
            message.setFrom(new InternetAddress(from));
            message.addRecipients(Message.RecipientType.TO, to);

            MimeMultipart multipart = new MimeMultipart();

            MimeBodyPart messageBodyPart = new MimeBodyPart();

            messageBodyPart.setContent(msgBody, "text/html");

            multipart.addBodyPart(messageBodyPart);
            message.setContent(multipart);

            transport.connect();
            transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
            transport.close();
            return "SUCCESS";
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
            return "INVALID_EMAIL";
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return "ERROR";
    }

    public static void main(String args[]) {
        System.out.println(new MailSender().sendMail("your_email/from_email", "to_email", "Subject", "Message"));
    }
}

希望!它有助于。谢谢!

答案 13 :(得分:-1)

我刚遇到这个问题,解决方法是“mail.smtp.user”属性应该是您的电子邮件(不是用户名)。

gmail用户的示例:

properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.user", from);
properties.put("mail.smtp.password", pass);
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.auth", "true");