title: Javamail gmail and OAuth2
body: <p>I'm trying to use the latest javamail 1.6.0 api in a web app (java 1.8/tomcat8) to send email on behalf of client users of the app. Some clients use gmail.
  I don't want to ask them to enable access to insecure apps in their google accounts as suggested by the <a href="https://javaee.github.io/javamail/FAQ#gmail" rel="noreferrer">javamail FAQ</a>, and I'm willing to implement oauth2 if that's what it takes.</p>
  
  <p>To do that, I did the following on <a href="https://console.developers.google.com" rel="noreferrer">google developer console</a>:</p>
  
  <ul>
  <li>created an app </li>
  <li>created oauth2 credentials for the app (clientid,
  clientsecret) </li>
  <li>granted the app access to gmail api</li>
  </ul>
  
  <p>Then, I implemented the oauth2 flow in my app using the <a href="https://developers.google.com/api-client-library/java/apis/oauth2/v1" rel="noreferrer">google oauth client</a></p>
  
  <p>The authorization redirect is constructed:</p>
  
  <pre><code>String url = 
          new GoogleAuthorizationCodeRequestUrl(clientId, 
              redirectUrl, 
              Collections.singleton(GmailScopes.GMAIL_SEND)
              ).setAccessType("offline").build();
  </code></pre>
  
  <p>That successfully redirects to the google site where I can authenticate and authorize my app to send mail on my behalf.  It successfully redirects back to my app after I authorize, and the app processes the authorization code:</p>
  
  <pre><code>GoogleTokenResponse response =
                  new GoogleAuthorizationCodeTokenRequest(
                          new NetHttpTransport(), 
                          new JacksonFactory(),
                        clientId, 
                        clientSecret,
                        code, 
                        redirectUrl)
                  .execute();
  </code></pre>
  
  <p>(where code is the returned authorization code)
  This seems to work, and returns an access token and refresh token.
  (I can also go back to my google account settings and see that I have authorized the app to send email.</p>
  
  <p>So now I want to try to use the access token to send mail through the javamail api using my gmail username (the one I logged in as to authorize the app), the access token, and the following settings:</p>
  
  <pre><code>host = "smtp.gmail.com";
  port = 587;
  props.put("mail.smtp.auth", "true");
  props.put("mail.smtp.starttls.enable", "true");
  props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
  </code></pre>
  
  <p>The javamail code works fine for other smtp servers.
  I also turned on debug to trace the smtp flow</p>
  
  <pre><code>DEBUG: JavaMail version 1.6.0
  DEBUG: successfully loaded resource: /META-INF/javamail.default.providers
  DEBUG: Tables of loaded providers
  DEBUG: Providers Listed By Class Name: {com.sun.mail.smtp.SMTPSSLTransport=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], com.sun.mail.smtp.SMTPTransport=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle], com.sun.mail.imap.IMAPSSLStore=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], com.sun.mail.pop3.POP3SSLStore=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], com.sun.mail.imap.IMAPStore=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], com.sun.mail.pop3.POP3Store=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle]}
  DEBUG: Providers Listed By Protocol: {imaps=javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle], imap=javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle], smtps=javax.mail.Provider[TRANSPORT,smtps,com.sun.mail.smtp.SMTPSSLTransport,Oracle], pop3=javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Oracle], pop3s=javax.mail.Provider[STORE,pop3s,com.sun.mail.pop3.POP3SSLStore,Oracle], smtp=javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]}
  DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
  DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
  DEBUG SMTP: useEhlo true, useAuth true
  DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
  220 smtp.gmail.com ESMTP c7sm3632131pfg.29 - gsmtp
  DEBUG SMTP: connected to host "smtp.gmail.com", port: 587
  
  EHLO 10.0.0.5
  250-smtp.gmail.com at your service, [216.165.225.194]
  250-SIZE 35882577
  250-8BITMIME
  250-STARTTLS
  250-ENHANCEDSTATUSCODES
  250-PIPELINING
  250-CHUNKING
  250 SMTPUTF8
  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 ""
  DEBUG SMTP: Found extension "PIPELINING", arg ""
  DEBUG SMTP: Found extension "CHUNKING", arg ""
  DEBUG SMTP: Found extension "SMTPUTF8", arg ""
  STARTTLS
  220 2.0.0 Ready to start TLS
  EHLO 10.0.0.5
  250-smtp.gmail.com at your service, [216.165.225.194]
  250-SIZE 35882577
  250-8BITMIME
  250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
  250-ENHANCEDSTATUSCODES
  250-PIPELINING
  250-CHUNKING
  250 SMTPUTF8
  DEBUG SMTP: Found extension "SIZE", arg "35882577"
  DEBUG SMTP: Found extension "8BITMIME", arg ""
  DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH"
  DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
  DEBUG SMTP: Found extension "PIPELINING", arg ""
  DEBUG SMTP: Found extension "CHUNKING", arg ""
  DEBUG SMTP: Found extension "SMTPUTF8", arg ""
  DEBUG SMTP: protocolConnect login, host=smtp.gmail.com, user=&lt;myemail@gmail.com&gt;, password=&lt;non-null&gt;
  DEBUG SMTP: Attempt to authenticate using mechanisms: XOAUTH2
  DEBUG SMTP: Using mechanism XOAUTH2
  DEBUG SMTP: AUTH XOAUTH2 command trace suppressed
  DEBUG SMTP: AUTH XOAUTH2 failed, THROW: 
  
  
   javax.mail.AuthenticationFailedException: OAUTH2 asked for more
  ...
  DEBUG SMTP: AUTH XOAUTH2 failed
  ERROR 2017-08-06 18:39:57,443  - send: 334 eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==
  </code></pre>
  
  <p>decoding that last line I see that the error is a 400 status, that I interpret to mean that the token is not valid.</p>
  
  <p>I also verified that the token is good using the google rest api:</p>
  
  <pre><code>https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=&lt;token&gt;
  </code></pre>
  
  <p>I also tried using port 465 with ssl enabled, but got the same error.</p>
  
  <p>what am I doing wrong here?</p>