0 votes
by (120 points)

We are attempting to pass an OAuth2 token into the Pop3 Rebex client utilizing the pattern indicated below.
We are able to retrieve the token using Microsoft Identity Client, connect with the Pop3 client and Login
using the token and the Pop3Auntenication.OAuth20 override. But, when attempting to utilize the GetMessageList() method
an exception is thrown indicating "A-ERR Authentication failure: unknown user name or bad password...".

string pattern = string.Format("user={0}{1}auth=Bearer {2}{1}{1}", config.UserName, '\x1', AccessToken);
string token = Convert.ToBase64String(Encoding.ASCII.GetBytes(pattern));

Applies to: Rebex Secure Mail

1 Answer

0 votes
by (148k points)
edited by

Make sure that config.UserName is correct - it's best to retrieve this via OAuth2 as well. Check out ImapOAuthWpfApp_IdentityClient sample source code - this shows how to authenticate with OAuth2 via Microsoft Identity Client to Office365, and retrieve mail messages using Rebex Imap class. The process for Pop3 is essentially the same (just use Pop3 instead of Imap and configure the application to ask for https://outlook.office365.com/POP.AccessAsUser.All instead of https://outlook.office365.com/IMAP.AccessAsUser.All).

Update: We published a blog post that describes how to login with OAuth 2.0 to Office365 with Rebex Secure Mail, and another one that describes how to register application for with appropriate permissions in Azure.

by (120 points)
Okay, so, what I run into is that all of this seems to be fine for applications using delegated authentication with a signed-in user present. But what we need to do is make it work for background service applications with no signed in user present. The blog references that this process is a bit different but outside the scope of the blog. So I am trying to find a description of how to do this.
by (148k points)
We hope to publish a separate blogpost on that soon as well. In the meantime, try following Microsoft's instructions for "app-only" authentication for EWS at https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth - the same process would for Rebex EWS, and I assume it applies to POP3 as well, although the section on application manifests and requiredResourceAccess  is somewhat cryptic and might have to be adjusted for POP3.
by
edited by anonymous
hi together,
we are facing the same problem.
We are trying to connect via OAuth2 and Pop3 without user interaction. (ClientCredentials)

We did register an App in our Microsoft Tenant with all delegated permissions and APP Permissions correlating to Mail access. We use this registered app
with a client secret to get the token from "https://login.microsoftonline.com/MSTenantID/oauth2/v2.0/token", where MSTenantID is our Microsoft Tenant.

 var scope = "https://outlook.office.com/.default";

We are requesting the token correctly. Connection via EWS is possible. A connection via Pop3 always fails with the following error:
Rebex.Net.Pop3Exception: "Authentication failure: unknown user name or bad password."

Example Code:

static void Main(string[] args)
        {

            Pop3 pop3 = new Pop3();
            try
            {
                pop3.Connect(server,SslMode.Implicit);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            var tok = HelperClass.GetElibilityToken(tenant_id, client_ID, client_Secret, scope);
            //string pattern = string.Format("user={0}{1}auth=Bearer {2}{1}{1}", userMail, '\x1', tok.AccessToken);
            string pattern = string.Format("user={0}{1}auth=Bearer {2}{1}{1}", userMail, Convert.ToChar(0x01), tok.AccessToken);
            string token = Convert.ToBase64String(Encoding.ASCII.GetBytes(pattern));
            try
            {
                pop3.Login(token, Pop3Authentication.OAuth20);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            Console.ReadKey();
        }

        public static Token GetElibilityToken(string ptenantID,string pclient_id, string pclient_secret, string pScope)
        {
            // Using Microsoft.Identity.Client 4.22.0
            var cca = ConfidentialClientApplicationBuilder
                .Create(pclient_id)
                .WithClientSecret(pclient_secret)
                .WithTenantId(ptenantID)
                .Build();

            // The permission scope required for EWS access
            var ewsScopes = new string[] { pScope };

            //Make the token request
            var authResult = cca.AcquireTokenForClient(ewsScopes).ExecuteAsync().Result;
            Token tok = new Token();
            tok.AccessToken = authResult.AccessToken;
            tok.TokenType = authResult.TokenType;
            return tok;
        }

Is there any solution without EWS? Is there something missing in the implementation?


Thanks for the help.
by (148k points)
edited by
Hello 'anonymous'. If you are trying to connect without user interaction, then you have to use "app-only" (unattended) authentication where only "app-only" Azure AD permissions are relevant. This is in contrast to "delegated" authentication (interactive, with a user present), which has a separate set of "delegated" permissions in Azure AD that don't apply in "app-only" mode. Which application permissions have you assigned?

For instructions on how to get app-only authentication work with POP3 or IMAP, see the following article:
    https://blog.rebex.net/office365-imap-pop3-oauth-unattended
...