我尝试使用 JavaMail 通过 IMAP 连接到 gmail
这是我所做的事情的代码片段
public class OAuth2Authenticator {
private static final Logger logger = Logger
.getLogger(OAuth2Authenticator.class.getName());
private static Session mSession;
public static final class OAuth2Provider extends Provider {
private static final long serialVersionUID = 1L;
public OAuth2Provider() {
super("Google OAuth2 Provider", 1.0,
"Provides the XOAUTH2 SASL Mechanism");
put("SaslClientFactory.XOAUTH2",
"org.scribe.examples.OAuth2SaslClientFactory");
}
}
public static void initialize() {
Security.addProvider(new OAuth2Provider());
}
public static IMAPStore connectToImap(String host, int port,
String userEmail, String oauthToken, boolean debug)
throws Exception {
Properties props = new Properties();
props.put("mail.imaps.sasl.enable", "true");
props.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken);
Session session = Session.getInstance(props);
session.setDebug(debug);
final URLName unusedUrlName = null;
IMAPSSLStore store = new IMAPSSLStore(session, unusedUrlName);
final String emptyPassword = "";
store.connect(host, port, userEmail, emptyPassword);
return store;
}
public static synchronized void testImap(String user, String oauthToken) {
try {
initialize();
IMAPStore imapStore = connectToImap("imap.gmail.com", 993, user,
oauthToken, true);
} catch (Exception e) {
System.out.println("Failed");
e.printStackTrace();
}
}
public static void main (String[] args){
String username="username@gmail.com";
String oauthToken=GoogleExample.getOAuthCode();// explained below
testImap(username, oauthToken);
}
}
为了获得OauthToken,我使用这样的抄写员
private static final String NETWORK_NAME = "Google";
private static final String AUTHORIZE_URL = "https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=";
private static final String PROTECTED_RESOURCE_URL = "https://mail.google.com/mail/feed/atom";
private static final String SCOPE = "https://mail.google.com/mail";
public static String getOAuthCode(){
OAuthService service = new ServiceBuilder()
.provider(GoogleApi.class)
.apiKey("anonymous")
.apiSecret("anonymous")
.scope(SCOPE)
.build();
Scanner in =new Scanner(System.in);
System.out.println("=== " + NETWORK_NAME + "'s OAuth Workflow ===");
System.out.println();
//Obtain Request token
System.out.println("Fetching request token");
Token requestToken = service.getRequestToken();
System.out.println("The request token"+requestToken);
System.out.println("Authorizing Scribe");
System.out.println();
System.out.println(AUTHORIZE_URL + requestToken.getToken());
System.out.println("And paste the verifier here");
System.out.print(">>");
Verifier verifier = new Verifier(in.nextLine());
System.out.println();
System.out.println("Trading the Request Token for an Access Token...");
Token accessToken = service.getAccessToken(requestToken, verifier);
System.out.println("Got the Access Token!");
System.out.println("(if your curious it looks like this: " + accessToken + " )");
System.out.println();
return accessToken.getToken();
}
这是我运行程序时得到的调试日志
Fetching request token
The request tokenToken[4/WIZGED1ommjoIwt8NQdF76IgbPio , hfXe_IPPFX1A-DPWXKOb9GKJ]
Authorizing Scribe
https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=4/WIZGED1ommjoIwt8NQdF76IgbPio
And paste the verifier here
>>VX2hIT2rRi_7822BT_WLa-81
Trading the Request Token for an Access Token...
Got the Access Token!
(if your curious it looks like this: Token[1/hKn9r0lSf1QWp0ESgn7J18PDnpE80buxvjcaGRLm9wM , -SGAHMqlD6kaxneB3evD5SMX] )
DEBUG: setDebug: JavaMail version 1.5.0
DEBUG IMAPS: mail.imap.fetchsize: 16384
DEBUG IMAPS: mail.imap.ignorebodystructuresize: false
DEBUG IMAPS: mail.imap.statuscachetimeout: 1000
DEBUG IMAPS: mail.imap.appendbuffersize: -1
DEBUG IMAPS: mail.imap.minidletime: 10
DEBUG IMAPS: enable SASL
DEBUG IMAPS: SASL mechanisms allowed: XOAUTH2
DEBUG IMAPS: trying to connect to host "imap.gmail.com", port 993, isSSL true
* OK Gimap ready for requests from 174.26.139.84 iu5if8027627pbc.224
A0 CAPABILITY
* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIENTTOKEN
A0 OK Thats all she wrote! iu5if8027627pbc.224
DEBUG IMAPS: AUTH: XOAUTH
DEBUG IMAPS: AUTH: XOAUTH2
DEBUG IMAPS: AUTH: PLAIN
DEBUG IMAPS: AUTH: PLAIN-CLIENTTOKEN
DEBUG IMAPS: protocolConnect login, host=imap.gmail.com, user=username@gmail.com, password=<non-null>
DEBUG IMAPS: SASL authentication command trace suppressed
DEBUG IMAPS: SASL Mechanisms:
DEBUG IMAPS: XOAUTH2
DEBUG IMAPS:
DEBUG IMAPS: SASL client XOAUTH2
DEBUG IMAPS: SASL challenge: :
DEBUG IMAPS: SASL callback length: 1
DEBUG IMAPS: SASL callback 0: javax.security.auth.callback.NameCallback@17b14695
DEBUG IMAPS: SASL response: user=username@gmail.comauth=Bearer 1/hKn9r0lSf1QWp0ESgn7J18PDnpE80buxvjcaGRLm9wM :
DEBUG IMAPS: SASL no response
Failed
javax.mail.AuthenticationFailedException: [ALERT] Invalid credentials (Failure)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:663)
at javax.mail.Service.connect(Service.java:345)
at org.scribe.examples.OAuth2Authenticator.connectToImap(OAuth2Authenticator.java:187)
at org.scribe.examples.OAuth2Authenticator.testImap(OAuth2Authenticator.java:219)
at org.scribe.examples.OAuth2Authenticator.main(OAuth2Authenticator.java:273)
很抱歉这篇文章很长,但任何关于我哪里出错的见解将不胜感激。谢谢!
猜测一下,你的令牌是坏的。
1/hKn9r0lSf1QWp0ESgn7J18PDnpE80buxvjcaGRLm9wM , -SGAHMqlD6kaxneB3evD5SMX
这不是访问令牌通常的外观。它看起来更像是访问令牌和用逗号分隔的刷新令牌。