I need help implementing OAuth2 authentication for Gmail SMTP since Google is removing support for basic authentication methods. I have created a service account and downloaded the JSON credentials file but my authentication attempt is failing.
Here is my current implementation:
import com.google.auth.oauth2.ServiceAccountCredentials;
import com.sun.mail.smtp.SMTPTransport;
import jakarta.mail.Session;
import java.io.InputStream;
import java.util.Base64;
import java.util.Collections;
import java.util.Properties;
public class EmailAuthenticator {
void authenticate() throws Exception {
InputStream credentialsFile = this.getClass().getClassLoader().getResourceAsStream("service-account.json");
String accountEmail = "[email protected]";
GoogleCredentials creds = ServiceAccountCredentials.fromStream(credentialsFile)
.createScoped(Collections.singletonList("https://mail.google.com/"));
creds.refreshIfExpired();
String accessToken = creds
.getAccessToken()
.getTokenValue();
Properties mailProps = new Properties();
mailProps.put("mail.smtp", "true");
mailProps.put("mail.transport.protocol", "smtp");
mailProps.put("mail.smtp.auth.mechanisms", "XOAUTH2");
mailProps.put("mail.smtp.starttls.enable", "true");
Session mailSession = Session.getInstance(mailProps);
mailSession.setDebug(true);
SMTPTransport smtpTransport = (SMTPTransport) mailSession.getTransport("smtp");
smtpTransport.connect("smtp.gmail.com", 587, accountEmail, null);
String oauthString = "user=" + accountEmail + "\001auth=Bearer " + accessToken + "\001\001";
String encodedAuth = Base64.getEncoder().encodeToString(oauthString.getBytes());
smtpTransport.issueCommand("AUTH XOAUTH2 " + encodedAuth, 235);
}
}
The connection fails with a 555-5.5.2 syntax error during the authentication step. The server responds with “Syntax error, goodbye” before I even try to send any email. What could be causing this authentication failure?