I am trying to send MIME content to a single user using Chilkat library. For sending mail I am using access token of Graph API client credentials. But getting authentication failure error in chilkat. Below is the sample code.
Calling from Main method:
string mime = System.IO.File.ReadAllText(@"\\Mac\Home\Downloads\12_01.eml");
GetFreshToken(tenantID, clientID, clientSecret);
SendMailUsingChilkat(tenantID,clientID, clientSecret,mime,"user.name@domain.com");
Methods used in:
bool GetFreshToken(string tenantId, string clientId, string clientSecret)
{
bool ret = false;
Chilkat.OAuth2 oauth2 = new Chilkat.OAuth2();
bool success;
oauth2.ListenPort = 3017;
oauth2.AuthorizationEndpoint = "https://login.microsoftonline.com/xxxxxx-xxxx-xxxx-xxxx-xxxx0f78bbd/oauth2/v2.0/authorize";
oauth2.TokenEndpoint = "https://login.microsoftonline.com/xxxxxx-xxxx-xxxx-xxxx-xxxx0f78bbd/oauth2/v2.0/token";
oauth2.ClientId = clientId;
oauth2.ClientSecret = clientSecret;
oauth2.CodeChallenge = false;
oauth2.Scope = "openid profile offline_access https://outlook.office365.com/SMTP.Send https://outlook.office365.com/POP.AccessAsUser.All https://outlook.office365.com/IMAP.AccessAsUser.All";
string url = oauth2.StartAuth();
if (oauth2.LastMethodSuccess != true)
{
MessageBox.Show(oauth2.LastErrorText);
return ret;
}
int numMsWaited = 0;
while ((numMsWaited < 30000) && (oauth2.AuthFlowState < 3))
{
oauth2.SleepMs(100);
numMsWaited = numMsWaited + 100;
}
if (oauth2.AuthFlowState < 3)
{
oauth2.Cancel();
MessageBox.Show("No response from the browser!");
return ret;
}
if (oauth2.AuthFlowState == 5)
{
MessageBox.Show("OAuth2 failed to complete.");
MessageBox.Show(oauth2.FailureInfo);
return ret;
}
if (oauth2.AuthFlowState == 4)
{
MessageBox.Show("OAuth2 authorization was denied.");
MessageBox.Show(oauth2.AccessTokenResponse);
return ret;
}
if (oauth2.AuthFlowState != 3)
{
MessageBox.Show("Unexpected AuthFlowState:" + Convert.ToString(oauth2.AuthFlowState));
return ret;
}
Chilkat.JsonObject json = new Chilkat.JsonObject();
json.Load(oauth2.AccessTokenResponse);
json.EmitCompact = false;
if (json.HasMember("expires_on") != true)
{
Chilkat.CkDateTime dtExpire = new Chilkat.CkDateTime();
dtExpire.SetFromCurrentSystemTime();
dtExpire.AddSeconds(json.IntOf("expires_in"));
json.AppendString("expires_on", dtExpire.GetAsUnixTimeStr(false));
}
json.Emit();
Chilkat.FileAccess fac = new Chilkat.FileAccess();
ret = fac.WriteEntireTextFile("microsoftGraph.json", json.Emit(), "utf-8", false);
return ret;
}
bool GetOrRefreshToken(string clientId, string clientSecret, out string accessToken)
{
bool ret = false;
accessToken = null;
Chilkat.JsonObject json = new Chilkat.JsonObject();
bool success = json.LoadFile("microsoftGraph.json");
if (success != true)
{
return false;
}
Chilkat.CkDateTime dtExpire = new Chilkat.CkDateTime();
dtExpire.SetFromUnixTime(false, json.IntOf("expires_on"));
if (dtExpire.ExpiresWithin(10, "minutes") != true)
{
Debug.WriteLine("No need to refresh, the access token won't expire within the next 10 minutes.");
accessToken = json.StringOf("access_token");
return true;
}
// OK, we need to refresh the access token by sending a POST like this:
Chilkat.OAuth2 oauth2 = new Chilkat.OAuth2();
oauth2.TokenEndpoint = "https://login.microsoftonline.com/xxxxxx-xxxx-xxxx-xxxx-xxxx0f78bbd/oauth2/v2.0/token";
oauth2.ClientId = clientId;
oauth2.ClientSecret = clientSecret;
oauth2.RefreshToken = json.StringOf("refresh_token");
success = oauth2.RefreshAccessToken();
if (success != true)
{
Debug.WriteLine(oauth2.LastErrorText);
return false;
}
// Update the JSON with the new tokens.
json.UpdateString("access_token", oauth2.AccessToken);
json.UpdateString("refresh_token", oauth2.RefreshToken);
json.EmitCompact = false;
Debug.WriteLine(json.Emit());
if (json.HasMember("expires_on") != true)
{
dtExpire.SetFromCurrentSystemTime();
dtExpire.AddSeconds(json.IntOf("expires_in"));
json.AppendString("expires_on", dtExpire.GetAsUnixTimeStr(false));
}
Chilkat.FileAccess fac = new Chilkat.FileAccess();
ret = fac.WriteEntireTextFile("microsoftGraph.json", json.Emit(), "utf-8", false);
accessToken = json.StringOf("access_token");
return ret;
}
async void SendMailUsingChilkat(string tenantId, string clientId, string clientSecret, string mime, string recipient)
{
string accessToken;
GetOrRefreshToken(clientId, clientSecret, out accessToken);
Chilkat.Email email = new Chilkat.Email();
email.LoadEml(mime);
Chilkat.MailMan mailman = new Chilkat.MailMan();
mailman.SmtpHost = "smtp.office365.com";
mailman.SmtpPort = 587;
mailman.StartTLS = true;
mailman.SmtpUsername = email.From;
mailman.OAuth2AccessToken = accessToken;
bool success = mailman.SendMime(email.From, recipient, mime);
if (success == true)
{
Debug.WriteLine("Mail Sent!");
return;
}
if (mailman.LastSmtpStatus != 535)
{
Debug.WriteLine(mailman.LastErrorText);
return;
}
}
I referred below links for implementation
https://www.example-code.com/csharp/office365_oauth2_access_token.asp
https://www.example-code.com/csharp/office365_refresh_access_token.asp
https://www.example-code.com/csharp/office365_smtp_send_email.asp