Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Web Development
  3. Cloud Computing
  4. Office 365 + IMAP + OAuth2 [Solved]

Office 365 + IMAP + OAuth2 [Solved]

Scheduled Pinned Locked Moved Cloud Computing
csharpsharepointcomcloudsecurity
7 Posts 4 Posters 38 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Richard DeemingR Offline
    Richard DeemingR Offline
    Richard Deeming
    wrote on last edited by
    #1

    We currently have an intranet portal which uses IMAP to read email from a shared mailbox on Office365, using the excellent MailKit[^] library. I've just been made aware that Microsoft is going to disable basic authentication for IMAP clients. Originally, this was going to happen in October, but it's since been pushed back to the second half of 2021. Basic Auth and Exchange Online – February 2020 Update - Microsoft Tech Community - 1191282[^] After some panicked reading and experimentation (and much swearing), I've managed to get the MSAL[^] library to return an OAuth2 access token:

    const string ClientId = "...";
    const string Username = "...";
    SecureString password = ...;

    var scopes = new[] { "https://outlook.office365.com/.default" };
    var app = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs).Build();
    var tokenResult = await app.AcquireTokenByUsernamePassword(scopes, Username, password).ExecuteAsync(cancellationToken);

    After configuring the application as a "public client" in the Azure portal, giving it Mail.ReadWriteAll and Mail.SendAll permissions, and granting admin consent for my organisation, this code now returns a seemingly-valid access token. According to the author of the MailKit library[^], all I need to do now is use the token to authenticate:

    using var client = new ImapClient();
    await client.ConnectAsync("outlook.office365.com", 993, SecureSocketOptions.Auto, cancellationToken);
    await client.AuthenticateAsync(new SaslMechanismOAuth2(Username, tokenResult.AccessToken), cancellationToken);

    Unfortunately, that simply throws an "authentication failed"<

    "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

    Richard DeemingR K S 4 Replies Last reply
    0
    • Richard DeemingR Richard Deeming

      We currently have an intranet portal which uses IMAP to read email from a shared mailbox on Office365, using the excellent MailKit[^] library. I've just been made aware that Microsoft is going to disable basic authentication for IMAP clients. Originally, this was going to happen in October, but it's since been pushed back to the second half of 2021. Basic Auth and Exchange Online – February 2020 Update - Microsoft Tech Community - 1191282[^] After some panicked reading and experimentation (and much swearing), I've managed to get the MSAL[^] library to return an OAuth2 access token:

      const string ClientId = "...";
      const string Username = "...";
      SecureString password = ...;

      var scopes = new[] { "https://outlook.office365.com/.default" };
      var app = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs).Build();
      var tokenResult = await app.AcquireTokenByUsernamePassword(scopes, Username, password).ExecuteAsync(cancellationToken);

      After configuring the application as a "public client" in the Azure portal, giving it Mail.ReadWriteAll and Mail.SendAll permissions, and granting admin consent for my organisation, this code now returns a seemingly-valid access token. According to the author of the MailKit library[^], all I need to do now is use the token to authenticate:

      using var client = new ImapClient();
      await client.ConnectAsync("outlook.office365.com", 993, SecureSocketOptions.Auto, cancellationToken);
      await client.AuthenticateAsync(new SaslMechanismOAuth2(Username, tokenResult.AccessToken), cancellationToken);

      Unfortunately, that simply throws an "authentication failed"<

      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      Thanks to "paulflo150" on GitHub, I was able to authenticate with the token by changing the scopes to:

      var scopes = new[] { "https://outlook.office365.com/IMAP.AccessAsUser.All" };

      Now I need to find out how to connect to a shared mailbox. The usual trick of appending "\shared-mailbox-alias" to the username results in the same "authentication failed" error, and if I authenticate without it there are no "shared namespaces" available.


      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        We currently have an intranet portal which uses IMAP to read email from a shared mailbox on Office365, using the excellent MailKit[^] library. I've just been made aware that Microsoft is going to disable basic authentication for IMAP clients. Originally, this was going to happen in October, but it's since been pushed back to the second half of 2021. Basic Auth and Exchange Online – February 2020 Update - Microsoft Tech Community - 1191282[^] After some panicked reading and experimentation (and much swearing), I've managed to get the MSAL[^] library to return an OAuth2 access token:

        const string ClientId = "...";
        const string Username = "...";
        SecureString password = ...;

        var scopes = new[] { "https://outlook.office365.com/.default" };
        var app = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs).Build();
        var tokenResult = await app.AcquireTokenByUsernamePassword(scopes, Username, password).ExecuteAsync(cancellationToken);

        After configuring the application as a "public client" in the Azure portal, giving it Mail.ReadWriteAll and Mail.SendAll permissions, and granting admin consent for my organisation, this code now returns a seemingly-valid access token. According to the author of the MailKit library[^], all I need to do now is use the token to authenticate:

        using var client = new ImapClient();
        await client.ConnectAsync("outlook.office365.com", 993, SecureSocketOptions.Auto, cancellationToken);
        await client.AuthenticateAsync(new SaslMechanismOAuth2(Username, tokenResult.AccessToken), cancellationToken);

        Unfortunately, that simply throws an "authentication failed"<

        Richard DeemingR Offline
        Richard DeemingR Offline
        Richard Deeming
        wrote on last edited by
        #3

        Finally managed to get the code to access a shared mailbox, with help from Sivaprakash Saripalli at Microsoft. It's simply a case of passing the email address of the mailbox instead of the username to the SaslMechanismOAuth2 constructor.

        const string ClientId = "..."; // The "Application (client) ID" from the Azure apps portal
        const string UserName = "..."; // The Office365 account username - user@domain.tld
        SecureString Password = ...; // The Office365 account password
        const string Mailbox = "..."; // The shared mailbox name - mailbox@domain.tld

        // Get an OAuth token:
        var scopes = new[] { "https://outlook.office365.com/IMAP.AccessAsUser.All" };
        var app = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs).Build();
        var authenticationResult = await app.AcquireTokenByUsernamePassword(scopes, UserName, Password).ExecuteAsync(cancellationToken);

        // Authenticate the IMAP client:
        using var client = new ImapClient();
        await client.ConnectAsync("outlook.office365.com", 993, SecureSocketOptions.Auto, cancellationToken);
        await client.AuthenticateAsync(new SaslMechanismOAuth2(Mailbox, authenticationResult.AccessToken), cancellationToken);


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

        1 Reply Last reply
        0
        • Richard DeemingR Richard Deeming

          We currently have an intranet portal which uses IMAP to read email from a shared mailbox on Office365, using the excellent MailKit[^] library. I've just been made aware that Microsoft is going to disable basic authentication for IMAP clients. Originally, this was going to happen in October, but it's since been pushed back to the second half of 2021. Basic Auth and Exchange Online – February 2020 Update - Microsoft Tech Community - 1191282[^] After some panicked reading and experimentation (and much swearing), I've managed to get the MSAL[^] library to return an OAuth2 access token:

          const string ClientId = "...";
          const string Username = "...";
          SecureString password = ...;

          var scopes = new[] { "https://outlook.office365.com/.default" };
          var app = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs).Build();
          var tokenResult = await app.AcquireTokenByUsernamePassword(scopes, Username, password).ExecuteAsync(cancellationToken);

          After configuring the application as a "public client" in the Azure portal, giving it Mail.ReadWriteAll and Mail.SendAll permissions, and granting admin consent for my organisation, this code now returns a seemingly-valid access token. According to the author of the MailKit library[^], all I need to do now is use the token to authenticate:

          using var client = new ImapClient();
          await client.ConnectAsync("outlook.office365.com", 993, SecureSocketOptions.Auto, cancellationToken);
          await client.AuthenticateAsync(new SaslMechanismOAuth2(Username, tokenResult.AccessToken), cancellationToken);

          Unfortunately, that simply throws an "authentication failed"<

          K Offline
          K Offline
          kdbueno
          wrote on last edited by
          #4

          not all declared event handlers are proactive.

          1 Reply Last reply
          0
          • Richard DeemingR Richard Deeming

            We currently have an intranet portal which uses IMAP to read email from a shared mailbox on Office365, using the excellent MailKit[^] library. I've just been made aware that Microsoft is going to disable basic authentication for IMAP clients. Originally, this was going to happen in October, but it's since been pushed back to the second half of 2021. Basic Auth and Exchange Online – February 2020 Update - Microsoft Tech Community - 1191282[^] After some panicked reading and experimentation (and much swearing), I've managed to get the MSAL[^] library to return an OAuth2 access token:

            const string ClientId = "...";
            const string Username = "...";
            SecureString password = ...;

            var scopes = new[] { "https://outlook.office365.com/.default" };
            var app = PublicClientApplicationBuilder.Create(ClientId).WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs).Build();
            var tokenResult = await app.AcquireTokenByUsernamePassword(scopes, Username, password).ExecuteAsync(cancellationToken);

            After configuring the application as a "public client" in the Azure portal, giving it Mail.ReadWriteAll and Mail.SendAll permissions, and granting admin consent for my organisation, this code now returns a seemingly-valid access token. According to the author of the MailKit library[^], all I need to do now is use the token to authenticate:

            using var client = new ImapClient();
            await client.ConnectAsync("outlook.office365.com", 993, SecureSocketOptions.Auto, cancellationToken);
            await client.AuthenticateAsync(new SaslMechanismOAuth2(Username, tokenResult.AccessToken), cancellationToken);

            Unfortunately, that simply throws an "authentication failed"<

            S Offline
            S Offline
            Sernjijj Kabral
            wrote on last edited by
            #5

            Yes, most asynchronous development, are proposed to be antelope in the forms of rule, when AJAX overrule its dynamic system.

            OriginalGriffO 1 Reply Last reply
            0
            • S Sernjijj Kabral

              Yes, most asynchronous development, are proposed to be antelope in the forms of rule, when AJAX overrule its dynamic system.

              OriginalGriffO Offline
              OriginalGriffO Offline
              OriginalGriff
              wrote on last edited by
              #6

              I don't know if you have a problem with English or if you are trying to increase your reputation by randomly posting irrelevant crap; either way please stop or it will be treated as site abuse and the BanHammer will descend upon you. If it's a problem with English, write your message in your native language then use Google Translate to get an English version. If it's a reputation thing, then stop immediately.

              "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

              "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
              "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt

              Richard DeemingR 1 Reply Last reply
              0
              • OriginalGriffO OriginalGriff

                I don't know if you have a problem with English or if you are trying to increase your reputation by randomly posting irrelevant crap; either way please stop or it will be treated as site abuse and the BanHammer will descend upon you. If it's a problem with English, write your message in your native language then use Google Translate to get an English version. If it's a reputation thing, then stop immediately.

                "I have no idea what I did, but I'm taking full credit for it." - ThisOldTony "Common sense is so rare these days, it should be classified as a super power" - Random T-shirt AntiTwitter: @DalekDave is now a follower!

                Richard DeemingR Offline
                Richard DeemingR Offline
                Richard Deeming
                wrote on last edited by
                #7

                The BanHammer is already swinging[^]. :)


                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups