-->

send mail via SMTP Gmail Oauth2 issue

2019-02-11 06:22发布

问题:

I can authenticated to SMTP by following the google example.

But the problem now is I can't send out the mail. I am getting the following error whenever I try to send out mail.

com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 f5sm19578172pav.22

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2114)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1618)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1119)
    at javax.mail.Transport.send0(Transport.java:195)
    at javax.mail.Transport.send(Transport.java:124)

First I am getting can't connect to local host , thus I added a few lines of code to propery of session like below to OAuth2Authenticator class , still authenicated successfully. But can't send out the mail.

props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");

I am using the same session object and SMTP transport object which will be returned from OAuth2Authenticator class when I first authenticated successfully.

            Message message = new MimeMessage(session);


        message.setFrom(new InternetAddress(msg.getFrom()));
        message.setRecipients(Message.RecipientType.TO,
            InternetAddress.parse(msg.getTo()));
        message.setSubject(msg.getSubject());
        message.setText(msg.getBody());

        transport.send(message);

Full Debug Log

DEBUG: setDebug: JavaMail version 1.4.5
DEBUG SMTP: enable SASL
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 mx.google.com ESMTP gj1sm1027169pbc.11 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587

EHLO E6410-PC
250-mx.google.com at your service, [202.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO E6410-PC
250-mx.google.com at your service, [202.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Authenticate with SASL
DEBUG SMTP: SASL mechanisms allowed: XOAUTH2
DEBUG SMTP: SASL AUTH command trace suppressed
DEBUG SMTP SASL: Mechanisms: XOAUTH2
DEBUG SMTP SASL: SASL client XOAUTH2
DEBUG SMTP SASL: callback length: 1
DEBUG SMTP SASL: callback 0: javax.security.auth.callback.NameCallback@100ab23
DEBUG SMTP SASL: no response
Successfully authenticated to SMTP.
NOOP
250 2.0.0 OK gj1sm1027169pbc.11 - gsmtp
Is SMTP still connected: true
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: enable SASL
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 mx.google.com ESMTP az8sm1466819pab.3 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587

EHLO E6410-PC
250-mx.google.com at your service, [202.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO E6410-PC
250-mx.google.com at your service, [202.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<user@gmail.com>
530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 az8sm1466819pab.3 - gsmtp
DEBUG SMTP: got response code 530, with response: 530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 az8sm1466819pab.3 - gsmtp

RSET
250 2.1.5 Flushed az8sm1466819pab.3 - gsmtp
DEBUG SMTP: MessagingException while sending
com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 az8sm1466819pab.3 - gsmtp

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2114)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1618)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1119)
    at javax.mail.Transport.send0(Transport.java:195)

Edited: I now called AUTH command explicitly like that .

 byte[] response = String.format("user=%s\1auth=Bearer %s\1\1",
                    emailAddress, accessToken.getToken()).getBytes();
            response = BASE64EncoderStream.encode(response);
            System.out.println("token check : " + new String(response));

            transport.issueCommand("AUTH XOAUTH2 " + new String(response), 235);

but the response still the same.

DEBUG: setDebug: JavaMail version 1.4.5
DEBUG SMTP: enable SASL
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 mx.google.com ESMTP kl3sm6965596pbc.15 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587

EHLO E6410-PC
250-mx.google.com at your service, [xxx.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO E6410-PC
250-mx.google.com at your service, [xxx.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
Successfully authenticated to SMTP.
token check : abcdefgFuYUBnbWFpbC5jb20BYXV0aD1CZWabcdefgSEVTNlpUVlFTUXZfblZfZ01FaDF6WWtSQ2kzb1d5RElFQ19mb2NmWG5Sam93RUlBYVJRTldfNwEB
AUTH XOAUTH2 abcdefgFuYUBnbWFpbC5jb20BYXV0aD1CZWabcdefgSEVTNlpUVlFTUXZfblZfZ01FaDF6WWtSQ2kzb1d5RElFQ19mb2NmWG5Sam93RUlBYVJRTldfNwEB
235 2.7.0 Accepted
NOOP
250 2.0.0 OK kl3sm6965596pbc.15 - gsmtp
Is SMTP still connected: true
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: enable SASL
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 mx.google.com ESMTP vo6sm6969236pbc.8 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587

EHLO E6410-PC
250-mx.google.com at your service, [xxx.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO E6410-PC
250-mx.google.com at your service, [xxx.xxx.xxx.xxx]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
250 ENHANCEDSTATUSCODES
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: use8bit false
MAIL FROM:<user@gmail.com>
530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 vo6sm6969236pbc.8 - gsmtp
DEBUG SMTP: got response code 530, with response: 530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 vo6sm6969236pbc.8 - gsmtp

RSET
250 2.1.5 Flushed vo6sm6969236pbc.8 - gsmtp
DEBUG SMTP: MessagingException while sending
com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 vo6sm6969236pbc.8 - gsmtp

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2114)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1618)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1119)
    at javax.mail.Transport.send0(Transport.java:195)
    at javax.mail.Transport.send(Transport.java:124)

QUIT
221 2.0.0 closing connection vo6sm6969236pbc.8 - gsmtp
com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. Learn more at
530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 vo6sm6969236pbc.8 - gsmtp

    at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2114)
    at com.sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.java:1618)
    at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1119)
    at javax.mail.Transport.send0(Transport.java:195)
    at javax.mail.Transport.send(Transport.java:124)

回答1:

Sorry people, answer is here: Javamail api in android using XOauth I tested, it works.

"SMS style login" failure - Secure accounts with 2 step login (via phone SMS) reject sending email via SMTP (both RAW password & OAuth style, fail with a Authentication error). They will let you create the OAuth token but will not send email.



回答2:

You just need to authenticate. Follow this example, it also uses gmail: http://www.mkyong.com/java/javamail-api-sending-email-via-gmail-smtp-example/



回答3:

This is an old thread but it took me a very long time to figure this out after going through numerous forums (and none of them had the right answer) so I'll post it if it helps someone. Many of the answers above suggest using password which is incorrect

If you are using the latest google apis with OAuth2 and also using the sample code @ http://code.google.com/p/google-mail-oauth2-tools/downloads/detail?name=oauth2-java-sample-20120904.zip&can=2&q=

and are getting the exception com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. Learn more at 530 5.5.1 http://support.google.com/mail/bin/answer.py?answer=14257 vo6sm6969236pbc.8 - gsmtp

Here are the steps to fix the problem

Run python oauth2.py exactly as the instruction suggest in the zip download. The OAuth2 Argument is the oauthtoken you must use in the code.

After running the OAuth2Authenticator.connectToSmtp("smtp.googlemail.com", 587, email, oauthToken, true) method to get the SMTPTransport. To send the message:

  //create the message
  //Note that you do need to get the same session object that gets created within the connectToSmtp method.
  MimeMessage message = new MimeMessage(session);
  message.setFrom(new InternetAddress("from@gmail.com"));
  message.addRecipient(Message.RecipientType.TO, new InternetAddress("to@gmail.com"));
  message.setSubject("This is the Subject Line!");
  message.setText("This is actual message");

  //this was the magic line that is needed - for authentication
  transport.issueCommand("AUTH XOAUTH2 " + oauthToken, 235);

  //send the message
  transport.sendMessage(message, message.getAllRecipients());


回答4:

I think so it is asking for authentication of your username.

session=Session.getInstance(props,
         new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(fromUsername, password);
            }
          });

And then use above session in your code.

I haven't use the code specified in the google link u mentioned but i use java mail api to send email from my gmail account.Use above code for authentication



回答5:

try adding these to your props config..

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


回答6:

Hi Friend finally i am able to send Message using OAUTH , Posting my OAuth2Authenticator source,

/* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.example;

import com.sun.mail.imap.IMAPStore;
import com.sun.mail.imap.IMAPSSLStore;
import com.sun.mail.smtp.SMTPTransport;

import java.security.Provider;
import java.security.Security;
import java.util.Properties;
import java.util.UUID;
import java.util.logging.Logger;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;


/**
* Performs OAuth2 authentication.
*
* <p>Before using this class, you must call {@code initialize} to install the
* OAuth2 SASL provider.
*/
public class OAuth2Authenticator {
 private static final Logger logger =
     Logger.getLogger(OAuth2Authenticator.class.getName());

 public static final class OAuth2Provider extends Provider {
   private static final long serialVersionUID = 1L;

   public OAuth2Provider() {
     super("Google OAuth2 Provider", 1.0,
           "Provides the XOAUTH2 SASL Mechanism");
     put("SaslClientFactory.XOAUTH2",
         "com.google.code.samples.oauth2.OAuth2SaslClientFactory");
   }
 }

 /**
  * Installs the OAuth2 SASL provider. This must be called exactly once before
  * calling other methods on this class.
  */
 public static void initialize() {
   Security.addProvider(new OAuth2Provider());
 }

 /**
  * Connects and authenticates to an IMAP server with OAuth2. You must have
  * called {@code initialize}.
  *
  * @param host Hostname of the imap server, for example {@code
  *     imap.googlemail.com}.
  * @param port Port of the imap server, for example 993.
  * @param userEmail Email address of the user to authenticate, for example
  *     {@code oauth@gmail.com}.
  * @param oauthToken The user's OAuth token.
  * @param debug Whether to enable debug logging on the IMAP connection.
  *
  * @return An authenticated IMAPStore that can be used for IMAP operations.
  */
 public static IMAPStore connectToImap(String host,
                                       int port,
                                       String userEmail,
                                       String oauthToken,
                                       boolean debug) throws Exception {
   Properties props = new Properties();
   props.put("mail.imaps.sasl.enable", "true");
   props.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
   props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken);
   Session session = Session.getInstance(props);
   session.setDebug(debug);

   final URLName unusedUrlName = null;
   IMAPSSLStore store = new IMAPSSLStore(session, unusedUrlName);
   final String emptyPassword = "<your_gmail_password>";
   store.connect(host, port, userEmail, emptyPassword);
   return store;
 }

 /**
  * Connects and authenticates to an SMTP server with OAuth2. You must have
  * called {@code initialize}.
  *
  * @param host Hostname of the smtp server, for example {@code
  *     smtp.googlemail.com}.
  * @param port Port of the smtp server, for example 587.
  * @param userEmail Email address of the user to authenticate, for example
  *     {@code oauth@gmail.com}.
  * @param oauthToken The user's OAuth token.
  * @param debug Whether to enable debug logging on the connection.
  *
  * @return An authenticated SMTPTransport that can be used for SMTP
  *     operations.
  */
 public static SMTPTransport connectToSmtp(String host,
                                           int port,
                                           String userEmail,
                                           String oauthToken,
                                           boolean debug) throws Exception {
   Properties props = new Properties();
   props.put("mail.smtp.starttls.enable", "true");
   props.put("mail.smtp.starttls.required", "true");
   props.put("mail.smtp.sasl.enable", "true");
   props.put("mail.smtp.sasl.mechanisms", "XOAUTH2");
   props.put("mail.smtp.auth","true");
   props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken);



   Session session = Session.getInstance(props);
   /*,
           new javax.mail.Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("prateek.engineer@gmail.com", emptyPassword);
        }
      });*/
   session.setDebug(debug);

   final URLName unusedUrlName = null;
   SMTPTransport transport = new SMTPTransport(session, unusedUrlName);
   // If the password is non-null, SMTP tries to do AUTH LOGIN.
   final String emptyPassword = "<your_gmail_password>";
   transport.connect(host, port, userEmail, emptyPassword);

   Message message = new MimeMessage(session);
   message.setFrom(new InternetAddress("<your_gmail_id>"));
   message.setRecipients(Message.RecipientType.TO,InternetAddress.parse("<recepient_emailid>"));
   message.setSubject("Test Message");
   message.setText("First Message using OAuth Protocol");
   /*SMTPTransport.send(message);*/

   Address[] add=new InternetAddress[1];
   add[0]= new InternetAddress("<recepient_emailid>");
   transport.sendMessage(message, add);

   return transport;
 }

 /**
  * Authenticates to IMAP with parameters passed in on the commandline.
  */
 public static void main(String args[]) throws Exception {
   /*if (args.length != 2) {
     System.err.println(
         "Usage: OAuth2Authenticator <email> <oauthToken>");
     return;
   }*/
   String email = "<your_gmail_id>";

   String oauthToken = "";


   initialize();

   IMAPStore imapStore = connectToImap("imap.gmail.com",
                                       993,
                                       email,
                                       oauthToken,
                                       true);
   System.out.println("Successfully authenticated to IMAP.\n");
   SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com",
                                               587,
                                               email,
                                               oauthToken,
                                               true);

   System.out.println("Successfully authenticated to SMTP.");
 }
}

add your password and the line u missed because of which u r getting authentication required exception is :::

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

in your connectToSmtp(.... , ...); method

AND RESPONSE YOU GET IS ::

From: <your_email_id>
To: <recepient_eemail_id>
Subject: Test Message
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

First Message using OAuth Protocol //its message u have 
.
250 2.0.0 OK 1360312537 a1sm52630615pav.2 - gsmtp
Successfully authenticated to SMTP.