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

Posted

技术标签:

【中文标题】javax.mail.AuthenticationFailedException:连接失败,没有指定密码?【英文标题】:javax.mail.AuthenticationFailedException: failed to connect, no password specified? 【发布时间】:2011-09-30 10:25:25 【问题描述】:

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

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

即使在输入密码后,我也得到了异常。为什么不认证?

【问题讨论】:

【参考方案1】:

尝试创建一个 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));

【讨论】:

我无法理解。您能否将其包含在您的答案中 如果您需要帮助,请告诉我,我会尽力帮助您 @Suhail Gupta,我已经在你之前的question 中提到过。 @RMT this is my edited code after your answer这是你要求的吗? 我遇到了同样的错误,这解决了它,但为什么呢?为什么身份验证仅在使用身份验证器获取 Session 实例时才有效,而不是在尝试与 Transport 连接时有效,因为用户/密码显然是好的。【参考方案2】:

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

【讨论】:

【参考方案3】:

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

    Transport.send 应该被静态访问 因此,transport.connect 没有为我做任何事情,我只需要在初始 Properties 对象中设置连接信息。

这是我的示例 send() 方法。 config 对象只是一个愚蠢的数据容器。

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】:

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

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?

【讨论】:

【参考方案5】:

您的电子邮件会话应提供如下验证器实例

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/

【讨论】:

【参考方案6】:
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");
              


【讨论】:

【参考方案7】:

我刚遇到这个问题,解决办法是属性“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");

【讨论】:

【参考方案8】:

即使在使用 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】:

我也有这个问题,不用担心。由于外部身份验证问题,它来自邮件服务器端。打开您的邮件,您会从邮件服务器收到一封邮件,告诉您启用可访问性。完成后,重试您的程序。

【讨论】:

链接 (productforums.google.com/forum/#!topic/gmail/x_gAqixiJio) 告诉您启用可访问性。你可以通过 (google.com/settings/security/lesssecureapps) 做到这一点。这解决了问题。否则,您必须进行两步验证。【参考方案10】:

我已经在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! :)
  

【讨论】:

【参考方案11】:

在 gmail 帐户的安全设置中打开“访问安全性较低的应用程序”。(来自邮件),请参阅以下链接以获取参考

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

【讨论】:

【参考方案12】:

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

举例

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

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

您可能会收到该错误。因为Transportclass' 方法可能无法处理特殊字符。如果您使用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);

【讨论】:

【参考方案13】:

看你代码的第9行,可能是错误;应该是:

mail.smtp.user 

不是

mail.stmp.user;

【讨论】:

【参考方案14】:

首先,在您的 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"));
    

希望!它有助于。谢谢!

【讨论】:

经过大量搜索,您的代码是唯一对我有用的代码。谢谢!!!

以上是关于javax.mail.AuthenticationFailedException:连接失败,没有指定密码?的主要内容,如果未能解决你的问题,请参考以下文章