Created
July 8, 2020 15:52
-
-
Save Sn3akyP3t3/e84d451e63845d0e566b2127f7e1e45f to your computer and use it in GitHub Desktop.
Files For [Bug] AcquireTokenForClient Causes Application To Terminate With Code 0 Without Any Explanation
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
using System.Security.Cryptography.X509Certificates; | |
namespace TestingGetEwsToken | |
{ | |
/// <summary> An incomplete data Model for authentication modded for testing acquisition of a token. </summary> | |
public class AuthenticationConfigModel | |
{ | |
/// <summary> (Required) Also known as the Application ID in Microsoft Azure. | |
/// Gets or sets the identifier of the client. </summary> | |
/// <value> The identifier of the client. </value> | |
public string ClientId { get; set; } | |
/// <summary> (Required) Also known as Directory ID in Microsoft Azure. | |
/// Gets or sets the identifier of the tenant. </summary> | |
/// <value> The identifier of the tenant. </value> | |
public string TenantId { get; set; } | |
/// <summary> (Required) Gets or sets the certificate thumbprint. </summary> | |
/// <value> The certificate thumbprint. </value> | |
public string CertificateThumbprint { get; set; } | |
/// <summary> Gets or sets the certificate. </summary> | |
/// <value> The certificate. </value> | |
internal X509Certificate2 Certificate { get; set; } | |
} | |
} |
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
using System; | |
using System.Linq; | |
using System.Security.Cryptography.X509Certificates; | |
namespace TestingGetEwsToken | |
{ | |
/// <summary> Authentication configuration provisioning logic. </summary> | |
internal class AuthenticationConfigProvider | |
{ | |
internal readonly AuthenticationConfigModel _authenticationModel; | |
/// <summary> Constructor requiring full path to the json configuration file. </summary> | |
public AuthenticationConfigProvider() | |
{ | |
_authenticationModel = new AuthenticationConfigModel | |
{ | |
ClientId = "ChangeMe", | |
CertificateThumbprint = "ChangeMe-GetFromCertificateManager", | |
TenantId = "ChangeMe" | |
}; | |
_authenticationModel.Certificate = ReadCertificate(_authenticationModel.CertificateThumbprint); | |
} | |
/// <summary> Reads a certificate installed on the current server given the cert thumbprint. </summary> | |
/// <exception cref="ArgumentException"> Thrown when one or more arguments have unsupported or illegal values. </exception> | |
/// <param name="certificateThumbprint"> The certificate thumbprint matching one installed on the server. </param> | |
/// <returns> The matching certificate. </returns> | |
private static X509Certificate2 ReadCertificate(string certificateThumbprint) | |
{ | |
if (string.IsNullOrWhiteSpace(certificateThumbprint)) | |
{ | |
throw new ArgumentException("certificateThumbprint should not be empty. Please set the certificateThumbprint", "certificateThumbprint"); | |
} | |
X509Certificate2 cert = null; | |
using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) | |
{ | |
store.Open(OpenFlags.ReadOnly); | |
X509Certificate2Collection certCollection = store.Certificates; | |
// Find unexpired certificates. | |
X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); | |
// From the collection of unexpired certificates, find the ones with the correct name. | |
X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindByThumbprint, certificateThumbprint, false); | |
// Return the first certificate in the collection, has the matching thumbprint and is current. | |
cert = signingCert.OfType<X509Certificate2>().OrderByDescending(c => c.NotBefore).FirstOrDefault(); | |
} | |
return cert; | |
} | |
} | |
} |
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
using Microsoft.Exchange.WebServices.Data; | |
using Microsoft.Identity.Client; | |
using System; | |
namespace TestingGetEwsToken | |
{ | |
class Program | |
{ | |
private static AuthenticationConfigProvider _authenticationConfigProvider; | |
static void Main(string[] args) | |
{ | |
_authenticationConfigProvider = new AuthenticationConfigProvider(); | |
_ = AttemptToGetToken(); | |
} | |
private static async System.Threading.Tasks.Task AttemptToGetToken() | |
{ | |
// Configure the MSAL client to get tokens | |
var ewsScopes = new string[] { "https://outlook.office.com/.default" }; | |
var app = ConfidentialClientApplicationBuilder.Create(_authenticationConfigProvider._authenticationModel.ClientId) | |
.WithAuthority(AzureCloudInstance.AzurePublic, _authenticationConfigProvider._authenticationModel.TenantId) | |
.WithCertificate(_authenticationConfigProvider._authenticationModel.Certificate) | |
.Build(); | |
AuthenticationResult result = null; | |
try | |
{ | |
// Make the interactive token request. This is where the bug seems to occur. | |
result = await app.AcquireTokenForClient(ewsScopes).ExecuteAsync(); | |
// Configure the ExchangeService with the access token | |
var ewsClient = new ExchangeService(); | |
ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"); | |
ewsClient.Credentials = new OAuthCredentials(result.AccessToken); | |
} | |
catch (MsalException ex) | |
{ | |
Console.WriteLine($"Error acquiring access token: {ex.ToString()}"); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine($"Error: {ex.ToString()}"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment