温馨提示:本文翻译自stackoverflow.com,查看原文请点击:c# - Migrating From ExchangeWebService Basic Authentication to OAuth2.0
asp.net c# oauth-2.0 exchangewebservices

c# - 从ExchangeWebService基本身份验证迁移到OAuth2.0

发布于 2020-04-07 10:27:32

我的目标是迁移我们的Exchange连接以使用OAuth2.0,因此我们将在2020年删除基本身份验证。

我当前使用基本身份验证的代码是:

ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials(MailBox, Password, "domamer");
try
{
    service.AutodiscoverUrl(MailBox, RedirectionUrlValidationCallback);
}
catch
{
    service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
}

在此处查看Microsoft提供的文档:(链接)我对以下代码进行了编码,期望它将取代上面的代码。

var pcaOptions = new PublicClientApplicationOptions
{
    ClientId = AppSettings.GetOauthClientID(),
    TenantId = AppSettings.GetOauthTenantID()
};

var pca = PublicClientApplicationBuilder.CreateWithApplicationOptions(pcaOptions).Build();

// The permission scope required for EWS access
var ewsScopes = new string[] { "https://outlook.office.com/EWS.AccessAsUser.All" };

// Make the interactive token request
var authResult = await pca.AcquireTokenInteractive(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(authResult.AccessToken);
ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, MailBox);

我以为新代码中的“ ewsClient”相当于原始代码中的“ service”。

当我尝试单步执行项目时,它仅在以下这一行结束:

var authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();

我仔细检查了我的ClientID,TenantID是否正确。

有人遇到过这个问题吗?可能的解决方案或要检查的东西?

我尝试使用“尝试/捕获”功能,希望得到一条错误消息,但是我从未遇到在所有Console.WriteLine上设置的断点。它只是锁定并停止在ExecuteAsync()行响应

try
{
    // Make the interactive token request
    var authResult = await pca.AcquireTokenInteractive(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(authResult.AccessToken);
    ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, EmailBox);

    Console.WriteLine("Made it Here");
}
catch (MsalException ex)
{
    Console.WriteLine($"Error acquiring access token: {ex.ToString()}");
}
catch (Exception ex)
{
    Console.WriteLine($"Error: {ex.ToString()}");
}

查看更多

提问者
MrMatt
被浏览
108
MrMatt 2020-01-31 20:28

与微软通电话后,他们努力地帮助我使其正常运行。花了一段时间,但是我终于能够使用以下代码建立与Microsoft Services的OAuth连接:

private const string TenantID = "[Your Tenant ID]";
private const string ClientID = "[Your Client ID]";
private const string ClientSecret = "[Your Secret ID]";

private const string AgentName = "My Agent Name";

public static ExchangeService OAuthConnectPost()
{
    string LoginURL = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", TenantID);

    var LogValues = new Dictionary<string, string>
    {
        { "grant_type", "client_credentials" },
        { "client_id", ClientID },
        { "client_secret", ClientSecret },
        { "scope", "https://graph.microsoft.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 = AgentName;
    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);
        return ewsClient;
    }
}

然后,我可以连接到该服务并使用类似于我之前所做的用户帐户进行身份验证

var service = OAuthConnectPost();
service.Credentials = new WebCredentials(EmailBox, EmailPass, EmailDomain);
FolderId rootFolderId = new FolderId(WellKnownFolderName.Inbox);
ItemView view = new ItemView(500);
FindItemsResults<Item> findResults = service.FindItems(rootFolderId, view);