7 Replies Latest reply: Jun 27, 2014 2:54 PM by Bill Shannon-Oracle RSS

    Using OAuth2 with Outlook.com

    02ddec58-9cfc-4db8-8409-66a82901ae51

      Hello,

       

      I'm trying to use JavaMail to authenticate against Outlook.com via OAuth2 and work with IMAP. Unfortunately, I've run into some challenges. I've seen two responses: 1) use apache commons or 2) the redirect mentioned here. The challenge is, the redirect doesn't have a Java solution. Instead, the solution is specific to Android. For that reason, I'm totally stuck. I've been trying all week to authenticate against Outlook.com via OAuth2 and pull down my emails from my inbox without any luck. I would sincerely appreciate any help I can get.

       

      Thank you for any ones help. I would really like to use JavaMail. However, I see a number of threads on the internet with this same issue, but no responses.

        • 1. Re: Using OAuth2 with Outlook.com
          Bill Shannon-Oracle

          The link in the JavaMail wiki appears to be dead.  I updated it to this.

           

          I haven't tried to use OAuth2 with outlook.com myself.  I looked at the Microsoft documentation, but I can't figure out where to get a Client ID to even get started.  If you've already figured that out, let me know.

           

          After that, I think everything you need is in this article.

           

          I didn't see anything that was specific to Android, which would be very unlikely for Microsoft.

          • 2. Re: Using OAuth2 with Outlook.com
            02ddec58-9cfc-4db8-8409-66a82901ae51

            Hello!

             

            Thank you for your speedy response. I'm in the process of trying to get this setup. From my understanding, you can setup a Client ID here.

            • 3. Re: Using OAuth2 with Outlook.com
              Bill Shannon-Oracle

              Thanks, that was just the pointer I needed to get started.  I was able to test this myself and it works.

               

              After you get your Client ID, browse to this page:

               

              https://login.live.com/oauth20_authorize.srf?client_id=CLIENT-ID&scope=wl.imap,wl.offline_access&response_type=code&redirect_uri=https://login.live.com/oauth20_desktop.srf

               

              After you go through the login and authorization procedure, it will send you to a URL of this form:

               

              https://login.live.com/oauth20_desktop.srf?code=XXXX&lc=ZZZZ

               

              You should see that URL in the browser's URL field.  You'll need the code value XXXX for the next step.

               

              Using (e.g.) the curl command line tool, make this request:

               

              curl \

                      -d client_id=CLIENT-ID \

                      -d redirect_uri=https://login.live.com/oauth20_desktop.srf \

                      -d client_secret=CLIENT-SECRET \

                      -d code=XXXX \

                      -d grant_type=authorization_code \

                      https://login.live.com/oauth20_token.srf

               

              That will give you a JSON formatted response that includes an Access Token and a Refresh Token (two very long strings).  You can use the Access Token as the password, following the instructions on the JavaMail wiki page.

               

              Let me know if that doesn't work for you.

              • 4. Re: Using OAuth2 with Outlook.com
                02ddec58-9cfc-4db8-8409-66a82901ae51

                Hello!

                 

                Thank you so much for your help. I was able to successfully get the Access Token and Refresh Token as you mentioned. However, its still not clear what kind of Store to use to actually connect to Outlook.com. Currently, I'm just trying with an IMAPStore as shown in the following code:

                 

                  IMAPStore store = new IMAPSSLStore(session, null);
                logger.info("Trying to connect to "imap-mail.outlook.com with emailAddress@outlook.com");
                store.connect("imap-mail.outlook.com", 993, "emailAddress@outlook.com", "");
                logger.info("Connected!"

                 

                I get an error that says:

                  javax.mail.MessagingException: failed to create new store connection;  nested exception is:  com.sun.mail.iap.ConnectionException: failed to create new store connection

                 

                I never get to the "Connected!" log entry. I sincerely appreciate your help with this.

                • 5. Re: Using OAuth2 with Outlook.com
                  Bill Shannon-Oracle

                  You should never create the Store object directly yourself.  You should always use the Session.getStore method.  Copy the code from here.

                   

                  Start by testing with the msgshow.java sample program.  Here's how I did it:

                   

                  token='XXXX'

                  java -Dmail.imap.sasl.enable=true \

                      -Dmail.imap.sasl.mechanisms=XOAUTH2 \

                      -Dmail.imap.auth.login.disable=true \

                      -Dmail.imap.auth.plain.disable=true \

                      -Dmail.imap.ssl.enable=true \

                      -Dmail.debug.auth=true \

                      msgshow -D -U USERNAME@outlook.com -P "$token" -T imap -H imap-mail.outlook.com -f INBOX 1

                   

                  If you still can't connect, try these debugging tips.

                  • 6. Re: Using OAuth2 with Outlook.com
                    02ddec58-9cfc-4db8-8409-66a82901ae51

                    Hello,

                     

                    Thank you so much for your help. However, there is still some odd behavior that doesn't make sense to me.

                     

                    I can successfully connect to the store using the java msgshow program you listed above. However, when I attempt to connect via my JUnit test, the authentication fails. I turned DEBUG on in the session in both the sample app and from my test. I found one subtle difference.

                     

                    In the sample app, I see the following lines:

                      DEBUG IMAP: SASL client XOAUTH2

                      DEBUG IMAP: SASL callback length: 2

                      DEBUG IMAP: SASL callback 0: javax.security.auth.callback.NameCallback@1fcef4f7

                      DEBUG IMAP: SASL callback 1: javax.security.auth.callback.PasswordCallback@4c349471

                     

                    However, from my test, I see the following:

                      DEBUG IMAP: SASL client XOAUTH2

                      DEBUG IMAP: SASL callback length: 1

                      DEBUG IMAP: SASL callback 0: javax.security.auth.callback.NameCallback@24e1e7e8

                     

                    Please notice how the sample app has 2 callbacks. However, my implementation only has one. Yet, I can't figure out the difference between my code and the sample app. My code looks like the following:

                            Properties properties = System.getProperties();

                            properties.put("mail.debug.auth", "true");

                            properties.put("mail.imap.sasl.enable", "true");

                            properties.put("mail.imap.sasl.mechanisms", "XOAUTH2");

                            properties.put("mail.imap.auth.login.disable", "true");

                            properties.put("mail.imap.auth.plain.disable", "true");

                            properties.put("mail.imap.ssl.enable", "true");

                     

                            // Create the session

                            Session session = Session.getInstance(properties, null);

                            session.setDebug(true);


                          // Connect to the store

                          Store _store = session.getStore("imap");

                            String accessToken = getHardcodedValue();                    // This value matches the value passed in for -P

                          _store.connect("imap-mail.outlook.com", -1, "username@outlook.com", accessToken);


                    When my code gets to the .connect call, the authentication fails. Once again, the main difference I see is the number of callbacks. Yet, I do not understand how this is setup.


                    Thank you for your continued assistance.

                    • 7. Re: Using OAuth2 with Outlook.com
                      Bill Shannon-Oracle

                      Are you sure the accessToken is being set properly in both cases?