Remember to add authentication entries (localhost is needed for .net core):
Then you need to apply correct API permissions and grant the admin consent for your domain.
In the API permissions / Add a permission wizard, select Microsoft Graph and then Delegated permissions to find the following permission scopes listed:
offline_access
email
IMAP.AccessAsUser.All
POP.AccessAsUser.All
SMTP.Send
Remember to grant admin consent.
Use Microsoft Authentication Library for .NET (MSAL.NET) nuget package to obtain an access token:
var pcaOptions = new PublicClientApplicationOptions
{
ClientId = "Application (client) ID",
TenantId = "Directory (tenant) ID",
// -or-
// for @outlook.com/@hotmail accounts instead of setting TenantId use:
// AadAuthorityAudience = AadAuthorityAudience.PersonalMicrosoftAccount,
RedirectUri = "https://login.microsoftonline.com/common/oauth2/nativeclient"
// RedirectUri = "http://localhost" // for .net core
};
var pca = PublicClientApplicationBuilder
.CreateWithApplicationOptions(pcaOptions)
.Build();
var scopes = new string[]
{
"offline_access",
"email",
"https://outlook.office.com/IMAP.AccessAsUser.All",
"https://outlook.office.com/POP.AccessAsUser.All",
"https://outlook.office.com/SMTP.Send",
};
In addition, you can request for offline_access scope. When a user approves the offline_access scope, your app can receive refresh tokens from the Microsoft identity platform token endpoint. Refresh tokens are long-lived. Your app can get new access tokens as older ones expire.
Now acquire the access token and user email address:
var authResult = pca.AcquireTokenInteractive(scopes).ExecuteAsync().Result;
string user = authResult.Account.Username;
string accessToken = authResult.AccessToken;
Finally you can connect to IMAP/POP3/SMTP server and authenticate:
using (Imap client = new Imap())
{
client.ConnectSSL("outlook.office365.com");
client.LoginOAUTH2(user, accessToken);
client.SelectInbox();
// ...
client.Close();
}
As this is fairly new feature for Exchange/Office365, here are some useful links:
Here’s the latest version that supports Visual Studio 2019.
Extension is convention based. It matches ClassName file with ClassNameTest or ClassNameTests and vice-versa, so you can easily navigate to the test file and back.
Here are some screenshots:
Here’s the toolbar name, in case it is not added automatically: