IMAP using OAuth2 in App Engine

I am trying to implement a service in App Engine that interacts with a Gmail account using OAuth2, Java 7 and the App Engine SDK 1.8.2. The problem is using the sample code provided by https://code.google.com/p/google-mail-oauth2-tools/wiki/JavaSampleCode the security provider does not seem to be found on the node, although it works locally. The code provided by the link earlier was modified to be run by the servlet with a sample code:

import java.io.IOException; import java.security.Provider; import java.security.Security; import java.util.Properties; import javax.mail.Session; import javax.mail.URLName; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.code.samples.oauth2.OAuth2SaslClientFactory; import com.sun.mail.imap.IMAPSSLStore; import com.sun.mail.imap.IMAPStore; import com.sun.mail.smtp.SMTPTransport; public class RunnerServlet extends HttpServlet { public void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String email = request.getParameter( "email"); String oauthToken = request.getParameter( "oauthToken"); initialize(); try { IMAPStore imapStore = connectToImap("imap.gmail.com", 993, email, oauthToken, true); System.out.println("Successfully authenticated to IMAP.\n"); SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com", 587, email, oauthToken, true); System.out.println("Successfully authenticated to SMTP."); } catch( Exception e ) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. throw new RuntimeException( e ); } } 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", "com.google.code.samples.oauth2.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); session.getProperties().put("mail.imaps.sasl.enable", "true"); session.getProperties().put("mail.imaps.sasl.mechanisms", "XOAUTH2"); session.getProperties().put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken); final URLName unusedUrlName = null; IMAPSSLStore store = new IMAPSSLStore(session, unusedUrlName); final String emptyPassword = ""; store.connect(host, port, userEmail, emptyPassword); return store; } public static SMTPTransport connectToSmtp(String host, int port, String userEmail, String oauthToken, boolean debug) throws Exception { Properties props = new Properties(); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.starttls.required", "true"); props.put("mail.smtp.sasl.enable", "true"); props.put("mail.smtp.sasl.mechanisms", "XOAUTH2"); props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oauthToken); Session session = Session.getInstance(props); session.setDebug(debug); final URLName unusedUrlName = null; SMTPTransport transport = new SMTPTransport(session, unusedUrlName); // If the password is non-null, SMTP tries to do AUTH LOGIN. final String emptyPassword = null; transport.connect(host, port, userEmail, emptyPassword); return transport; } } 

Trace IMAP debugging:

 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 xxx.xxx.xxx.xxx ZZZZZZZZZ A0 CAPABILITY * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY A0 OK Thats all she wrote! ZZZZZZZZZ DEBUG IMAPS: AUTH: XOAUTH DEBUG IMAPS: AUTH: XOAUTH2 DEBUG IMAPS: protocolConnect login, host=imap.gmail.com, user=som...@gmail.com , password=<non-null> DEBUG IMAPS: SASL authentication command trace suppressed DEBUG IMAPS: SASL Mechanisms: DEBUG IMAPS: XOAUTH2 DEBUG IMAPS: DEBUG IMAPS: No SASL support DEBUG IMAPS: SASL authentication failed DEBUG IMAPS: LOGIN command trace suppressed DEBUG IMAPS: LOGIN command result: A1 NO Empty username or password. ZZZZZZZZZ DEBUG IMAPS: trying to connect to host "imap.gmail.com", port 993, isSSL true * OK Gimap ready for requests from xxx.xxx.xxx.xxx YYYYYYYYYY A0 CAPABILITY * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH AUTH=XOAUTH2 A0 OK Thats all she wrote! YYY DEBUG IMAPS: AUTH: XOAUTH DEBUG IMAPS: AUTH: XOAUTH2 DEBUG IMAPS: protocolConnect login, host=imap.gmail.com, user=som...@gmail.com , password=<non-null> DEBUG IMAPS: SASL authentication command trace suppressed DEBUG IMAPS: SASL Mechanisms: DEBUG IMAPS: XOAUTH2 DEBUG IMAPS: DEBUG IMAPS: No SASL support DEBUG IMAPS: SASL authentication failed DEBUG IMAPS: LOGIN command trace suppressed DEBUG IMAPS: LOGIN command result: A1 NO Empty username or password. YYYYYYYYYY java.lang.RuntimeException: javax.mail.AuthenticationFailedException: Empty username or password. YYYYYYYYYY 

This problem only occurs when node is deployed. Ensure that the provider has been correctly installed and installed and uses the latest versions of the App Engine SDK, which facilitate IMAP and SMTP sockets. An attempt was made to run using an example servlet and a task in the task queue.

Thank you for your help in advance.

+4
source share
2 answers

I have the same problem as yours ... I am doing research, and I think the session is not created correctly. I have attached an image that shows the difference.

At the top of the image, the contents of the "props" variable are displayed, which are the same values ​​for the AppEngine project (left image) as the Normal project (right image). The lower images show the contents of the Session variable, and inside that the contents of the Properties variables. As you can see in the left case, it is null. But in the right case there are values.

Here is the image: http://ricorrico.comoj.com/misc/img2.jpg

This is really a mistake, is there a workaround?

Thank you in advance.

Hello!

+1
source

Not sure if you are still facing this problem, but @ user2606850 was very close to the solution. Initializing a session using a set of properties does not properly initialize a session.

BUT adding the correct properties AFTER creating a WORK session!

 Properties props = new Properties(); Session session = Session.getInstance(props); props = session.getProperties(); props.put("mail.imaps.sasl.enable", "true"); props.put("mail.imaps.sasl.mechanisms", "XOAUTH2"); IMAPSSLStore store = new IMAPSSLStore(session, unusedUrlName); ... 

Tested tested to work with AppEngine.

+1
source

Source: https://habr.com/ru/post/1494011/


All Articles