Javamail gmail和OAuth2 [英] Javamail gmail and OAuth2

查看:85
本文介绍了Javamail gmail和OAuth2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在网络应用程序(java 1.8/tomcat8)中使用最新的javamail 1.6.0 api代表应用程序的客户端用户发送电子邮件.一些客户端使用gmail.我不想让他们按照 javamail的建议在他们的Google帐户中启用对不安全应用程序的访问FAQ ,如果愿意的话,我愿意实现oauth2.

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 javamail FAQ, and I'm willing to implement oauth2 if that's what it takes.

为此,我在 Google开发人员控制台上进行了以下操作:

To do that, I did the following on google developer console:

  • 创建了一个应用
  • 为应用创建了oauth2凭据(客户端ID,clientsecret)
  • 授予应用访问gmail api的权限

然后,我使用在我的应用中实现了oauth2流google oauth客户端

授权重定向的构造方式:

The authorization redirect is constructed:

String url = 
        new GoogleAuthorizationCodeRequestUrl(clientId, 
            redirectUrl, 
            Collections.singleton(GmailScopes.GMAIL_SEND)
            ).setAccessType("offline").build();

该操作成功重定向到Google网站,我可以在该网站上进行身份验证并授权我的应用程序代表我发送邮件.授权后,它将成功重定向回我的应用程序,并且该应用程序处理授权代码:

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:

GoogleTokenResponse response =
                new GoogleAuthorizationCodeTokenRequest(
                        new NetHttpTransport(), 
                        new JacksonFactory(),
                      clientId, 
                      clientSecret,
                      code, 
                      redirectUrl)
                .execute();

(其中代码是返回的授权代码)这似乎可行,并返回访问令牌和刷新令牌.(我还可以返回到我的Google帐户设置,查看我是否已授权该应用发送电子邮件.

(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.

因此,现在我想尝试使用访问令牌通过使用我的gmail用户名(我登录以授权应用程序的用户名),访问令牌和以下设置通过javamail api发送邮件:

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:

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");

javamail代码可用于其他smtp服务器.我还打开了调试以跟踪smtp流

The javamail code works fine for other smtp servers. I also turned on debug to trace the smtp flow

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=<myemail@gmail.com>, password=<non-null>
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==

对最后一行进行解码,我看到错误是400状态,我认为这是令牌无效.

decoding that last line I see that the error is a 400 status, that I interpret to mean that the token is not valid.

我还使用google rest api验证了令牌是好的:

I also verified that the token is good using the google rest api:

https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<token>

我也尝试在启用ssl的情况下使用端口465,但出现相同的错误.

I also tried using port 465 with ssl enabled, but got the same error.

我在做什么错了?

推荐答案

这是对user2000974的补充.Google的有关使用OAuth对IMAP或SMTP服务器进行身份验证的文档 Gmail> IMAP> OAuth2.0机制明确指出以下内容

This is an addition to the answer of user2000974. The documentation of Google about using OAuth to authenticate to an IMAP or SMTP server Gmail > IMAP > OAuth 2.0 Mechanism clearly states the following

本文档定义了与IMAP AUTHENTICATE和SMTP AUTH命令一起使用的SASL XOAUTH2机制.该机制允许使用OAuth 2.0访问令牌来验证用户的Gmail帐户.

This document defines the SASL XOAUTH2 mechanism for use with the IMAP AUTHENTICATE and SMTP AUTH commands. This mechanism allows the use of OAuth 2.0 Access Tokens to authenticate to a user's Gmail account.

IMAP和SMTP访问的范围为 https://mail.google.com/.

The scope for IMAP and SMTP access is https://mail.google.com/.

我希望这能将以后遇到此问题的人们引向正确的文档页面.

I hope this will direct people that stumble upon this question in the future to the right documentation page.

这篇关于Javamail gmail和OAuth2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆