javaemailoauth-2.0smtpgmail

Google service account OAUTH2 SMTP "555-5.5.2 Syntax error"


I have a simple Java sample to test the connectivity to a Gmail service account. Issue is when i try to connect it says "555-5.5.2 Syntax error, goodbye. For more information, go to 555-5.5.2 https://support.google.com/a/answer/3221692 and review RFC 5321" And i do not know what is wrong.

I correctly get the token generate from the .json file and it seems like the properties are set up correctly?

It's funny because i dont have any issues sending emails over a normal user Gmail account...but Service account is throwing errors.

My code is this:

    public static void main(String[] args) throws IOException, MessagingException {
        // Properties
        Properties props = System.getProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.debug", "true");
        props.put("mail.debug.auth", "true");
        
        
        // Get token
        GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("D:/path-to-my-json.json"))
                .createScoped(Collections.singleton("https://mail.google.com/"));

        credentials.refreshIfExpired();
        String accessToken = credentials.getAccessToken().getTokenValue();
        System.out.println("Token "+accessToken);
        

        // Session
        Session session = Session.getDefaultInstance(props);
        session.setDebug(true);

        // Message
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("add@ress.com"));
        msg.setRecipient(Message.RecipientType.TO, new InternetAddress("rec@ipient.com"));
        msg.setSubject("Test");
        msg.setContent("this is a test email", "text/html");

        // Connect
        SMTPTransport transport = new SMTPTransport(session, null);
        transport.connect("smtp.gmail.com", "add@ress.com", null);
        transport.issueCommand("AUTH XOAUTH2 " + new String(BASE64EncoderStream.encode(String.format("user=%s\1auth=Bearer %s\1\1", "add@ress.com", accessToken).getBytes())), 235);
        transport.sendMessage(msg, msg.getAllRecipients());
    }

I have tried several ways and i always end up with the same "555-5.5.2 " error. If i plug my token in: https://www.googleapis.com/oauth2/v3/tokeninfo?accessToken=y It gets decoded as: { "azp": "117395330125029916455", "aud": "117395330125029916455", "scope": "https://mail.google.com/", "exp": "1720432913", "expires_in": "3589", "access_type": "online" }


Solution

  • For anyone that maybe will have the same issue: I was doing it the wrong way.

    I should have used:

    import com.google.api.services.gmail.Gmail;
    import com.google.api.services.gmail.GmailScopes;
    

    and then construct the authentication this way:

    GoogleCredentials credentials = GoogleCredentials.fromStream(new ByteArrayInputStream(SERVICE_ACCOUNT_KEY_JSON.getBytes(StandardCharsets.UTF_8)))
      .createScoped(Collections.singleton(GmailScopes.GMAIL_SEND))
      .createDelegated(USER_EMAIL);
    
    Gmail gmailService = new Gmail.Builder(new NetHttpTransport(), JSON_FACTORY, new HttpCredentialsAdapter(credentials))
      .setApplicationName(APPLICATION_NAME)
      .build();