0

I am looking for a complete Step-by-step to accomplish the following objective. I have been looking around and trying many, many ways, but not one of them works.

Objective: using C# .net core code (in Azure Functions) connect to a shared mailbox of Office 365 to retrieve emails [with date filter] to do some processing, then move that email from Inbox into another folder (Processed). I want to use MailKit (or something similar that is free and has MIT license) to retrieve, load and parse the emails.

What I have done, but of course, I can be way off…

  • In Azure Active Directory, I have created an App Registration
  • In API Permissions, I have added and granted (I am an admin) a lot of permissions (everything I guess may be related to this, from Email, to IMAP, SMTP, POP, Application, User and a bunch of other permissions.
  • In Certificates & Secrets, I created a client secret and recorded the secret (Value)
  • From Overview, I recorded the Client ID, Tenant ID, etc.

Code (I tried several variation of this…)

string[] scopes = {"https://graph.microsoft.com/.default" }
/*
   for scopes, I have also tried:
      “https://graph.microsoft.com/IMAP.AccessAsUser.All”
      “https://outlook.office.com/IMAP.AccessAsUser.All” 
*/

var authority = authority + tenant;
/* 
   for authority, I have also tried:
      “https://login.microsoftonline.com/“
      “https://login.microsoftonline.com/common”
      “https://login.microsoftonline.com/oauth2”, etc… 
*/

var client = ConfidentialClientApplicationBuilder
    .Create(clientID)
    .WithClientSecret(secret)
    .WithAuthority(new Uri(authority)) 
    .Build();
 
/* Fails every time! */ 
CancellationToken cancellationToken = default;
var authResult = await app.AcquireTokenForClient(scopes)
    .ExecuteAsync(cancellationToken);

/* MailKit to retrieve emails… */
/* 
   any step-by-step code using MailKit to 
   accomplish the Objective would be much appreciated.
*/
user13971889
  • 9
  • 1
  • 2
  • Have you seen and tried following the guide at https://github.com/jstedfast/MailKit/blob/master/ExchangeOAuth2.md ? It *should* help you get it working. – jstedfast Dec 11 '20 at 20:38
  • Yes, and I keep getting this error: Only loopback redirect uri is supported, but https://login.microsoftonline.com/common/oauth2/nativeclient was found. Configure http://localhost or http://localhost:port both during app registration and when you create the PublicClientApplication object. See https://aka.ms/msal-net-os-browser for details – user13971889 Dec 11 '20 at 20:56
  • Make sure to copy the exact same scopes that appear in the HOWTO. Your scopes are not the same. Using the code from the HOWTO, it works for me. – jstedfast Dec 11 '20 at 21:11
  • Yep, I tried it exactly like that, but it still doesn’t work. – user13971889 Dec 12 '20 at 00:17
  • @user13971889 Hi did you have a chance to look into my answer? – Allen Wu Dec 15 '20 at 08:41

1 Answers1

1

Firstly, you should not use this method to get the access token.

var client = ConfidentialClientApplicationBuilder
    .Create(clientID)
    .WithClientSecret(secret)
    .WithAuthority(new Uri(authority)) 
    .Build();

This method is using client credential flow which is not supported to use IMAP.AccessAsUser.All delegated permission.

This method mentioned by jstedfast is using Interactive provider. The interactive flow is used by mobile applications (Xamarin and UWP) and desktops applications to call Microsoft Graph.

So if configuring "http://localhost" as a Public client (mobile & desktop) redirect URI for your application doesn't work, I don't think you could implement it in the C# .net core Azure Function app. Azure Function app doesn't support login interactively within it. You can only use it in a console app.

But there are 2 workarounds which allow you to get the user access token for Microsoft Graph.

  1. Implement Username/password provider to generate the client and access token. But it is using ROPC flow which is not recommended by Microsoft. See details on Warning tip.

  2. Configure additional Login Params in App service to get the access token to call Microsoft Graph. Please refer to CONFIGURING AN APP SERVICE TO GET AN ACCESS TOKEN FOR AAD GRAPH API. The key point is changing the additionaloginparams to the following [“response_type=code id_token”, “resource=https://graph.microsoft.com”]. Related official document here.

Allen Wu
  • 15,529
  • 1
  • 9
  • 20
  • If my answer is helpful for you, you can accept it as answer( click on the check mark beside the answer to toggle it from greyed out to filled in.). See https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work. This can be beneficial to other community members. Thank you. – Allen Wu Dec 14 '20 at 03:09
  • Any ideas what might be causing a similar problem I'm having here: https://stackoverflow.com/q/72775465/4631427 ? – TheLethalCoder Jul 04 '22 at 12:19
  • In case someone is interested in an ROPC solution, I made a post about it with code: https://stackoverflow.com/questions/72984691/how-to-use-mailkit-with-imap-for-exchange-with-oauth2-for-daemon-non-interacti/72984692#72984692 – laurian Jul 14 '22 at 22:00