Created
November 5, 2020 11:16
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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