0 Replies Latest reply on May 3, 2016 2:06 PM by traviswithoutlookstruggles

    Outlook SMTP via OAuth ~ Java. Struggling!!!

    traviswithoutlookstruggles

      Working in Java, trying to connect to SMTP to see inbox using OAUTH tokens. I have obtained the access_token, refresh_token, and email. From what I understand I should be able to connect.

       

      I have obtained the email, refresh_token, and access_token using the following code:

           

            String USER_OAUTH2_AUTHORIZE_URL = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize";

       

       

            public String getOAuthDialog(Http.Request request) {

          return USER_OAUTH2_AUTHORIZE_URL

              + "?client_id=" + config.getClientId()

              + "&redirect_uri=" + getOutlookLoginRedirect(request)

              + "&response_type=code"

              + "&scope=https%3A%2F%2Foutlook.office.com%2Fmail.send%20" +

                       "https%3A%2F%2Foutlook.office.com%2Fmail.readwrite%20" +

                       "https%3A%2F%2Foutlook.office.com%2Fmail.read%20" +

                       "offline_access%20openid%20email%20profile"

              + "&state=" + stateGenerator.generate();

        }

       

       

      So the scopes I am using are mail.send, mail.readwrite, mail.read, offline_access, openid, email, and profile (although I am fairly confident I do not need all of these -> goal is to read inbox and send emails, while also getting email and name if they exist).

       

       

      I am then connecting to SMTP server with the following code:

       

       

            private SMTPTransport getSMTPConnection(User user) {

          OAuth2Authenticator.initialize();

          try {

            String accessToken = user.getAccesstoken();

            for (int tries = 1; true; tries++) {

              try {

                return OAuth2Authenticator.connectToSmtp("smtp-mail.outlook.com",

                    587,

                    user.getOutlookUid(),

                    accessToken,

                    true);

              } catch (AuthenticationFailedException e) {

                // Try refreshing once, and then fail if we get this exception again

                if (tries > 1) {

                  log.info("{}", e);

                  throw new RuntimeException("Failed to connect to Outlook SMTP for " + user.getOutlookUid() + ". " + e.getMessage(), e);

                }

       

       

                // Token expired; we need a new one

                log.info("Exception connecting to Outlook SMTP for " + user.getOutlookUid() + ": " + e);

       

       

                accessToken = updateAccessToken(user);

              }

            }

          } catch (Exception e) {

            log.error("Email send failure through Outlook SMTP. " + e.getMessage());

            throw Throwables.propagate(e);

          }

          }

       

       

      Well essentially I call that function, then call

       

       

          smtpTransport.sendMessage(message, message.getAllRecipients());

      on a message I have created.

       

       

      The code that actually connects to the server is here:

       

       

           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("mail.smtp.sasl.mechanisms.oauth2.oauthToken", oauthToken);

          Session session = Session.getInstance(props);

          session.setDebug(debug);

       

       

       

       

          URLName unusedUrlName = null;

          SMTPTransport transport = new SMTPTransport(session, unusedUrlName);

          // If the password is non-null, SMTP tries to do AUTH LOGIN.

          String password = "";

          transport.connect(host, port, userEmail, password);

       

       

          return transport;

        }

       

       

      Okay, now I can get to the most frustrating part... I have used the "connectToSMTP" method to connect to Gmail and it worked perfectly.

       

       

          OAuth2Authenticator.connectToSmtp("smtp.gmail.com",

                    587,

                    user.getGoogleUid(),

                    accessToken,

                    true);

       

       

      So ultimately my question is "what am I doing wrong?" or "what can I update to be able to send emails through Outlook"? I have seen that Outlook has a REST API, but that is plan B. Is there something different about Outlook vs Gmail?

       

       

       

       

      Some things I have considered:

        

       

       

      1. Scope did not request enough access (so I probably am asking for too much now)

      2. access_token was stored incorrectly or encoded in some way (tried decoding it from base_64 which provided nothing). I am able to use my refresh_token to update the access_token so that tells me I am probably storing them correctly.

      3. I tried passing null for the password. Also passed in the actual password and that WORKED, but I have the access_token and refresh_token so I shouldn't need to ask for their explicit password. Also this would be dangerous and sketchy to ask of users.

      4. I tried manually connecting to the smtp server using "openssl s_client -crlf -starttls smtp -connect smtp-mail.outlook.com:587", but it seemed to think my access_token was wrong "535 5.0.0 OAuth failed: OAuth authentication failed due to Invalid token.  Code -2147184118"  That number when taken two's complement and converted to hex is 0x8004920a. Helped in searches but was to no avail.

      5. I have done a lot of searching for this and will continue now to post this everywhere. A lot of resources for it working with Gmail, but as previously stated I already have it working for Gmail. Something seems different for Outlook. Also I have encountered lots of posts regarding email forwarding on an email client... I am semi-creating an email client so going through outlook.com settings doesn't help me.

       

       

      Another concern that a buddy of mine had was that my access token was really long, contributing to what the manual smtp server claimed. It is 1188 characters long. It's something like 'EwB4Aul3BAAUo4xeBIbHjhBxWOFekj4Xy2...x9stHxi2K/VFggE=' (obviously I hid most of the characters).

       

       

      Preemptive THANK YOU for anyone who offers advice or finds my issue. Especially why I can pass in the email password and that fails, but using the oauth access_token fails.