1

I am trying to send emails from a google compute instance through GMAIL API using a service account. I have followed all the steps according to this documentation but still getting an error message saying 'com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized'.

Below is the code snippet for the same.

public static void main( String[] args ) throws GeneralSecurityException, IOException, MessagingException
{
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    GoogleCredential credentialFromJson = GoogleCredential
            .fromStream(new FileInputStream(
                    "/Users/souravc/Documents/MySpaceSRV6100/Java_Samples/EmailTest/mail-auth.json"))
            .createScoped(Collections.singletonList(GmailScopes.GMAIL_SEND));

    GoogleCredential credential = new GoogleCredential.Builder()
            .setTransport(HTTP_TRANSPORT)
            .setJsonFactory(JSON_FACTORY)
            .setServiceAccountId(credentialFromJson.getServiceAccountId())
            .setServiceAccountPrivateKey(credentialFromJson.getServiceAccountPrivateKey())
            .setServiceAccountScopes(SCOPES)
            .setServiceAccountUser("exampleemail").build();         

    //credential.refreshToken();

    Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();

    String user = "me";
    Message123 obj = new Message123();
    obj.sendMessage(service, "me", obj.createEmail("exampleemail", "exampleemail",
            "Test", "Hi,\n\nTest Email\n\nThanks,\nSourav"));
}

In a class named 'Message123', I have written the sendMessage(). Below is the code for the same.

public Message sendMessage(Gmail service, String userId, MimeMessage emailContent) throws MessagingException, IOException 
{
    Message message = createMessageWithEmail(emailContent);
    message = service.users().messages().send(userId, message).execute();
    System.out.println("Message id: " + message.getId());
    System.out.println(message.toPrettyString());
    return message;
}

Note: Delegating domain-wide authority has not been granted to the service account

Could you please help with this? and here I would like to ask one more concern do we need to assign Delegating domain-wide authority to the service account even if I'm just sending email not reading/fetching any other user data?

Thanks for your help in advance

1 Answers1

3

The problem come from this

Note: Delegating domain-wide authority has not been granted to the service account

In your use case, you want that the service account send an email on behalf of you. It's close to the description provided in the documentation

For example, an application that uses the Google Calendar API to add events to the calendars of all users in a G Suite domain would use a service account to access the Google Calendar API on behalf of users

The 401 error means that the service-account has been authenticated (either you will have a 403) but it's not authorize to perform the operation, to send an email on behalf of you

guillaume blaquiere
  • 66,369
  • 2
  • 47
  • 76
  • thanks for the input. So I have to grant Delegating domain-wide authority to the same service account? – Sourav Chatterjee Dec 12 '19 at 13:38
  • Yes, if you want. If this service account is only use for this, you can. If it's shared for several thing, prefer the least privilege mode, and create another only for this task. – guillaume blaquiere Dec 12 '19 at 14:13
  • Yes, because to be able to impersonate any user you need a service account with [domain-wide authority](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority). – Andres Duarte Dec 12 '19 at 14:28
  • Seems like all you'd want is the permission to send email on behalf of a specific account or, at worst, a few specific accounts. Is there a way to do that? It's a fairly typical use case to send out emails "as" an application, e.g. noreply@myapp.example.com. How do you do that? – Charlie Reitzel Dec 12 '19 at 23:32
  • Thanks for all the inputs. I will try again after delegating domain-wide authority and will keep you posted – Sourav Chatterjee Dec 13 '19 at 03:46