smtpgoogle-appsoauth-2.0smtp-authemailrelay

SMTP Google Apps Oauth2 - issue in relay


I am trying to send mail by connecting to Google SMTP server using oAuth2 mechanism.

public static Transport connectToSmtp(String smtpServer, int port, String email, String authToken, boolean isDebug, MimeMessage mimeMsg)
     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.imaps.sasl.mechanisms.oauth2.oauthToken", authToken);
    Session session = Session.getInstance(props);
    session.setDebug(isDebug);
    final String emptyPassword = "";
    Transport transport = session.getTransport("smtp");
    transport.connect(smtpServer, port, email, emptyPassword);
    try
    {
        transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients());
    }
    catch (Exception e)
    {
        logger.log(Level.WARNING, "Exception Occured : ", e);
    }
    return transport;
}

Client ID and Secret of my App:

ID - 345101*-i6ki*4tk1sms.apps.googleusercontent.com

Secret - e6NHB*-eZ-rk

The above code threw the following error:

javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at 535 5.7.8 https://support.google.com/mail/answer/14257 o135sm276925ith.4 - gsmtp

Smtp Server : aspmx.l.google.com, Port : 25

Edited:

I have changed the below for the Google App account I am trying to connect and the above exception was cleared:

  1. No 2 step authentication

  2. Allow Less Secure Apps "Security" -> "Basic Settings" -> "Go to settings for less secure apps" -> "Allow Users to Manager Their Access to Less Secure Apps"

But after clearing the above exception. I got another exception.

com.sun.mail.smtp.SMTPSendFailedException: 550-5.7.1 Invalid credentials for relay [121...2]. The IP address you've registered in Google Apps SMTP Relay service doesn't match domain of the account this email is being sent from. If you are trying to relay mail from a domain that isn't registered under your Googles Apps account or has empty envelope-from, you must configure your mail server either to use SMTP AUTH to identify the sending domain or to present one of your domain names in the HELO or EHLO command. For more information, please visit https://support.google.com/a/answer/6140680#invalidcred f65sm341248ith.1 - gsmtp ;

So I changed the following setting:

Apps > Google Apps > Gmail > Settings for Gmail > Advanced settings

SMTP relay service

Even after attempting the above change the same exception is thrown. Please help.


Solution

  • Plain authentication and OAuth2 must be differentiated in Transport object which sends actual mail data to the SMTP server. This is done in JavaMail with the password parameter in Transport.connect().

    If the password is given as null in the above code, then the Java MailClient treats the authentication as OAuth instead of plain auth.

    So the code should be

    final String emptyPassword = null;
    

    As reply to the comment,
    If authentication is given as IP Address, then the given username and password are not validated. Instead, the IP address from which the connection comes from serves as authentication.
    This is the reason the same code worked, when you added the sender IP address to the GApps Relay Mail Settings and select authentication type as IP address.