Skip to content

Instantly share code, notes, and snippets.

@vSzemkel
Created November 5, 2020 11:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vSzemkel/e1675b97af5577d76ee260bdfb8a415e to your computer and use it in GitHub Desktop.
Save vSzemkel/e1675b97af5577d76ee260bdfb8a415e to your computer and use it in GitHub Desktop.
Demonstrates how to send and receive emails with OAuth2 authentication and Office 365
namespace OAuthWithO365
{
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using MailKit;
using MailKit.Net.Imap;
using MailKit.Net.Smtp;
using MailKit.Search;
using MailKit.Security;
using MimeKit;
using Newtonsoft.Json.Linq;
class Program {
static readonly string tenant = "some GUID";
static readonly string smtp_server = "smtp.office365.com";
static readonly string imap_server = "outlook.office365.com";
static readonly string aad_app_id = "some GUID";
static readonly string aad_app_secret = "***** ***";
static readonly string user = "username@domain";
static readonly string pass = "***** ***";
/// <summary>
/// W oparciu o aplikację OAuth zarejestrowaną w AAD z uprawnieniami User.Read, Mail.Send
/// generuje token umożliwiający wysyłanie maili w imieniu uzytkownika <see cref="mailUser"/>
/// https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth-ropc
/// </summary>
/// <returns>Access token owinięty w specyficzna dla MailKit strukture</returns>
static async Task<SaslMechanismOAuth2> GetAccessToken(string api_perm)
{
var content = new FormUrlEncodedContent(new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("scope", api_perm),
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("resource", "https://outlook.office365.com"),
new KeyValuePair<string, string>("client_id", aad_app_id),
new KeyValuePair<string, string>("client_secret", aad_app_secret),
new KeyValuePair<string, string>("username", user),
new KeyValuePair<string, string>("password", pass)
});
var client = new HttpClient();
var response = await client.PostAsync($"https://login.microsoftonline.com/{tenant}/oauth2/token", content).ConfigureAwait(continueOnCapturedContext: false);
var jsonString = await response.Content.ReadAsStringAsync();
var jobj = JObject.Parse(jsonString);
var token = jobj["access_token"];
client.Dispose();
return new SaslMechanismOAuth2(user, token.ToString());
}
static void SendTo365()
{
var at = GetAccessToken("SMTP.Send").Result;
using (var client = new SmtpClient(/*new MailKit.ProtocolLogger("smtp.log")*/)) {
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
try {
client.Connect(smtp_server, 587, SecureSocketOptions.Auto);
client.Authenticate(at);
var msg = new MimeMessage();
msg.From.Add(MailboxAddress.Parse(user));
msg.To.Add(MailboxAddress.Parse(user));
msg.Subject = "Testing SMTP";
msg.Body = new TextPart("plain"){ Text = "Zażółć gęślą jaźń\n" + DateTime.Now.ToLongTimeString() };
client.Send(msg);
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
}
static void ReceiveFrom365()
{
var at = GetAccessToken("IMAP.AccessAsUser.All").Result;
using (var client = new ImapClient(/*new MailKit.ProtocolLogger("imap.log")*/)) {
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
try {
client.Connect(imap_server, 993, SecureSocketOptions.Auto);
client.Authenticate(at);
client.Inbox.Open(FolderAccess.ReadOnly);
var uids = client.Inbox.Search(SearchQuery.New);
foreach (var uid in uids) {
var msg = client.Inbox.GetMessage(uid);
Console.WriteLine("\nGot email from: " + msg.From[0].ToString());
Console.WriteLine(msg.TextBody);
}
} catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
}
static void Main(string[] args)
{
SendTo365();
System.Threading.Thread.Sleep(2000);
ReceiveFrom365();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment