diff --git a/Documentation/FullyAnnotatedConfigReference.xml b/Documentation/FullyAnnotatedConfigReference.xml
index 6b3ab7e..96abd7c 100644
--- a/Documentation/FullyAnnotatedConfigReference.xml
+++ b/Documentation/FullyAnnotatedConfigReference.xml
@@ -297,6 +297,27 @@
-->
+
+
+
+ 00000000-0000-0000-0000-000000000000
+
+ 00000000-0000-0000-0000-000000000000
+
+ .\Resources\mail2bugAppClientSecret.bin
+
+ Mail2Bug/1.0.0.0
+
+
.\Resources\mail2bug.bin
+
+
+ 00000000-0000-0000-0000-000000000000
+ 00000000-0000-0000-0000-000000000000
+
+ .\Resources\mail2bugAppClientSecret.bin
+ Mail2Bug/1.0.0.0
+
+
true
diff --git a/Mail2Bug/Config.cs b/Mail2Bug/Config.cs
index 515e9d4..e97f192 100644
--- a/Mail2Bug/Config.cs
+++ b/Mail2Bug/Config.cs
@@ -28,6 +28,14 @@ public class KeyVaultSecret
public string ApplicationSecretEnvironmentVariableName { get; set; }
}
+ public class OAuthSecret
+ {
+ public string TenantID { get; set; }
+ public string ClientID { get; set; }
+ public string ClientSecretFile { get; set; }
+ public string UserAgentName { get; set; }
+ }
+
public class TfsServerConfig
{
// The TFS collection URL to connect to. e.g:
@@ -202,6 +210,7 @@ public enum MailboxServiceType
public string EWSUsername { get; set; }
public string EWSPasswordFile { get; set; }
public KeyVaultSecret EWSKeyVaultSecret { get; set; }
+ public OAuthSecret EWSOAuthSecret { get; set; }
#endregion
diff --git a/Mail2Bug/Email/EWS/EWSConnectionManger.cs b/Mail2Bug/Email/EWS/EWSConnectionManger.cs
index 2769ef0..04aa348 100644
--- a/Mail2Bug/Email/EWS/EWSConnectionManger.cs
+++ b/Mail2Bug/Email/EWS/EWSConnectionManger.cs
@@ -1,7 +1,13 @@
using System;
using System.Collections.Generic;
+using System.IO;
+using System.Net.Cache;
+using System.Net;
+using System.Text;
using log4net;
using Microsoft.Exchange.WebServices.Data;
+using Newtonsoft.Json.Linq;
+using Mail2Bug.Helpers;
namespace Mail2Bug.Email.EWS
{
@@ -22,6 +28,24 @@ public struct Credentials
public string EmailAddress;
public string UserName;
public string Password;
+ public CredentialsOAuth OAuthCredentials;
+ }
+
+ public class CredentialsOAuth
+ {
+ public CredentialsOAuth() { }
+ public CredentialsOAuth(Config.EmailSettings emailSettings, string clientSecret)
+ {
+ TenantID = emailSettings.EWSOAuthSecret.TenantID;
+ ClientID = emailSettings.EWSOAuthSecret.ClientID;
+ ClientSecret = clientSecret;
+ UserAgentName = emailSettings.EWSOAuthSecret.UserAgentName;
+ }
+
+ public string TenantID { get; set; }
+ public string ClientID { get; set; }
+ public string ClientSecret { get; set; }
+ public string UserAgentName { get; set; }
}
public struct EWSConnection
@@ -82,11 +106,21 @@ static private Tuple GetKeyFromCredentials(Credential
static private EWSConnection ConnectToEWS(Credentials credentials, bool useConversationGuidOnly)
{
Logger.DebugFormat("Initializing FolderMailboxManager for email adderss {0}", credentials.EmailAddress);
- var exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
+ ExchangeService exchangeService;
+ if (credentials.OAuthCredentials != null)
{
- Credentials = new WebCredentials(credentials.UserName, credentials.Password),
- Timeout = 60000
- };
+ Logger.DebugFormat("OAuth authentication for email address {0}", credentials.EmailAddress);
+ exchangeService = EWSOAuthHelper.OAuthConnectPost(credentials.OAuthCredentials, credentials.EmailAddress);
+ }
+ else
+ {
+ Logger.DebugFormat("Basic authentication for email address {0}", credentials.EmailAddress);
+ exchangeService = new ExchangeService(ExchangeVersion.Exchange2010_SP1)
+ {
+ Credentials = new WebCredentials(credentials.UserName, credentials.Password),
+ Timeout = 60000
+ };
+ }
exchangeService.AutodiscoverUrl(
credentials.EmailAddress,
@@ -108,7 +142,6 @@ static private EWSConnection ConnectToEWS(Credentials credentials, bool useConve
};
}
-
private readonly Dictionary, EWSConnection> _cachedConnections;
private readonly bool _enableConnectionCaching;
diff --git a/Mail2Bug/Email/MailboxManagerFactory.cs b/Mail2Bug/Email/MailboxManagerFactory.cs
index fcc86cf..9e6a98d 100644
--- a/Mail2Bug/Email/MailboxManagerFactory.cs
+++ b/Mail2Bug/Email/MailboxManagerFactory.cs
@@ -21,11 +21,15 @@ public IMailboxManager CreateMailboxManager(Config.EmailSettings emailSettings)
{
var credentialsHelper = new Helpers.CredentialsHelper();
string password = credentialsHelper.GetPassword(emailSettings.EWSPasswordFile, emailSettings.EncryptionScope, emailSettings.EWSKeyVaultSecret);
+ string clientSecret = emailSettings.EWSOAuthSecret != null
+ ? credentialsHelper.GetPassword(emailSettings.EWSOAuthSecret.ClientSecretFile, emailSettings.EncryptionScope, emailSettings.EWSKeyVaultSecret)
+ : null;
var credentials = new EWSConnectionManger.Credentials
{
EmailAddress = emailSettings.EWSMailboxAddress,
UserName = emailSettings.EWSUsername,
- Password = password
+ Password = password,
+ OAuthCredentials = emailSettings.EWSOAuthSecret != null ? new EWSConnectionManger.CredentialsOAuth(emailSettings, clientSecret) : null,
};
var exchangeService = _connectionManger.GetConnection(credentials, emailSettings.UseConversationGuidOnly);
diff --git a/Mail2Bug/Helpers/EWSOAuthHelper.cs b/Mail2Bug/Helpers/EWSOAuthHelper.cs
new file mode 100644
index 0000000..deb475f
--- /dev/null
+++ b/Mail2Bug/Helpers/EWSOAuthHelper.cs
@@ -0,0 +1,73 @@
+using Microsoft.Exchange.WebServices.Data;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Cache;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using Mail2Bug.Email.EWS;
+
+namespace Mail2Bug.Helpers
+{
+ public class EWSOAuthHelper
+ {
+ public static ExchangeService OAuthConnectPost(EWSConnectionManger.CredentialsOAuth oAuthCredentials, string emailAddress)
+ {
+ string LoginURL = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", oAuthCredentials.TenantID);
+
+ var LogValues = new Dictionary
+ {
+ { "grant_type", "client_credentials" },
+ { "client_id", oAuthCredentials.ClientID },
+ { "client_secret", oAuthCredentials.ClientSecret },
+ { "scope", "https://outlook.office365.com/.default" }
+ };
+ string postData = "";
+ foreach (var v in LogValues)
+ {
+ postData += (String.IsNullOrWhiteSpace(postData) ? "" : "&") + v.Key + "=" + v.Value;
+ }
+ var data = Encoding.ASCII.GetBytes(postData);
+
+ ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
+ ServicePointManager.Expect100Continue = true;
+ ServicePointManager.DefaultConnectionLimit = 9999;
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
+ | SecurityProtocolType.Tls11
+ | SecurityProtocolType.Tls12
+ | SecurityProtocolType.Ssl3;
+
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(LoginURL);
+ request.Method = "POST";
+ request.ContentType = "application/x-www-form-urlencoded";
+ request.Accept = "*/*";
+ request.UserAgent = oAuthCredentials.UserAgentName;
+ request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
+ request.ContentLength = data.Length;
+ using (var stream = request.GetRequestStream())
+ {
+ stream.Write(data, 0, data.Length);
+ }
+
+ using (var response = (HttpWebResponse)request.GetResponse())
+ using (Stream stream = response.GetResponseStream())
+ using (var reader = new StreamReader(stream))
+ {
+ var json = reader.ReadToEnd();
+ var aToken = JObject.Parse(json)["access_token"].ToString();
+
+ var ewsClient = new ExchangeService();
+ ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
+ ewsClient.Credentials = new OAuthCredentials(aToken);
+ //Impersonate and include x-anchormailbox headers are required!
+ ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, emailAddress);
+ ewsClient.HttpHeaders.Add("X-AnchorMailbox", emailAddress);
+ ewsClient.Timeout = 60000;
+ return ewsClient;
+ }
+ }
+ }
+}
diff --git a/Mail2Bug/Mail2Bug.csproj b/Mail2Bug/Mail2Bug.csproj
index 22bbdc2..522d3f3 100644
--- a/Mail2Bug/Mail2Bug.csproj
+++ b/Mail2Bug/Mail2Bug.csproj
@@ -1,5 +1,5 @@
-
+
Debug
@@ -9,12 +9,13 @@
Properties
Mail2Bug
Mail2Bug
- v4.5
+ v4.8
512
..\
true
+
AnyCPU
@@ -58,9 +59,11 @@
..\packages\Microsoft.Azure.KeyVault.1.0.0\lib\net45\Microsoft.Azure.KeyVault.dll
True
-
- False
- ..\packages\Microsoft.Exchange.WebServices.1.2\lib\Microsoft.Exchange.WebServices.dll
+
+ ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.dll
+
+
+ ..\packages\Microsoft.Exchange.WebServices.2.2\lib\40\Microsoft.Exchange.WebServices.Auth.dll
..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.16.204221202\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll
@@ -318,6 +321,7 @@
+
@@ -378,4 +382,4 @@
-->
-
+
\ No newline at end of file
diff --git a/Mail2Bug/packages.config b/Mail2Bug/packages.config
index 1dfc183..849ce6f 100644
--- a/Mail2Bug/packages.config
+++ b/Mail2Bug/packages.config
@@ -11,7 +11,7 @@
-
+
diff --git a/Mail2BugUnitTests/Mail2BugUnitTests.csproj b/Mail2BugUnitTests/Mail2BugUnitTests.csproj
index 9af2262..36668be 100644
--- a/Mail2BugUnitTests/Mail2BugUnitTests.csproj
+++ b/Mail2BugUnitTests/Mail2BugUnitTests.csproj
@@ -1,5 +1,5 @@
-
+
Debug
AnyCPU
@@ -8,7 +8,7 @@
Properties
Mail2BugUnitTests
Mail2BugUnitTests
- v4.5
+ v4.8
512
{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10.0
@@ -18,6 +18,7 @@
UnitTest
..\
true
+
true
@@ -170,4 +171,4 @@
-->
-
+
\ No newline at end of file
diff --git a/Tools/DpapiTool/DpapiTool.csproj b/Tools/DpapiTool/DpapiTool.csproj
index 757f1d3..34e91fb 100644
--- a/Tools/DpapiTool/DpapiTool.csproj
+++ b/Tools/DpapiTool/DpapiTool.csproj
@@ -1,5 +1,5 @@
-
+
Debug
@@ -9,7 +9,7 @@
Properties
DpapiTool
DpapiTool
- v4.5
+ v4.8
512
..\..\
true