更新 class 以使用 MFA 访问 Dynamics 365

Updating class to use MFA for accessing Dynamics 365

系统管理员启用了 2FA,所以我必须检查并更新一些程序以利用它来访问 Dynamics API。否则,我们收到以下内容:

{ 

   "error":"interaction_required",
   "error_description":"AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000007-0000-0000-c000-000000000000'.\r\nTrace ID: 24822bc6-9e93-476d-8580-fd04e3889300\r\nCorrelation ID: efd5dbc5-dead-4665-a5a6-570ae15a55fb\r\nTimestamp: 2020-02-24 20:35:15Z",
   "error_codes":[ 

      50076
   ],
   "timestamp":"2020-02-24 20:35:15Z",
   "trace_id":"24822bc6-9e93-476d-8580-fd04e3889300",
   "correlation_id":"efd5dbc5-dead-4665-a5a6-570ae15a55fb",
   "error_uri":"https://login.windows.net/error?code=50076",
   "suberror":"basic_action"
}

This article 听起来非常简单,这是我们必须用于 Outlook 和其他应用程序的过程。基本上,生成应用程序密码。

但是,我正在尝试使用应用程序密码而不是我们已经使用了一段时间的默认密码,但仍然无法获得程序使用的访问令牌。

这是我们一直在使用的:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace CrmQbInvoiceSync
{
  class CrmAuthorization
  {

    // Serialize the JSON response for the access_token
    public class AccessToken
    {
      public string access_token { get; set; }
    }

    public static async Task<string> GetCrmAccessToken()
    {
      var values = new Dictionary<string, string>
      {
        // Connection parameters
        {"client_id", ConfigurationManager.AppSettings["clientId"]},
        {"client_secret", ConfigurationManager.AppSettings["clientSecret"]},
        {"resource", ConfigurationManager.AppSettings["crmOrg"]},
        {"username", ConfigurationManager.AppSettings["username"]},
        {"password", ConfigurationManager.AppSettings["userPassword"]},
        {"grant_type", "password"}
      };

      // Console.WriteLine(values);

      // Convert to x-www-form-urlencoded
      var content = new FormUrlEncodedContent(values);
      try
      {
        // Send the x-www-form-urlencoded info to the OAuth2 end point
        HttpResponseMessage response = await Services.Client.PostAsync(ConfigurationManager.AppSettings["crmUri"], content);
        // Get the body from the response
        var responseContent = await response.Content.ReadAsStringAsync();

        // Extract out the access token from the response
        AccessToken responseBody = JsonConvert.DeserializeObject<AccessToken>(responseContent);

        // Test if there is an access token present
        if (responseBody.access_token != null)
        {
          // If there is an access token, take it and use it in
          // generating the query
          var accessToken = responseBody.access_token;
          return accessToken;
        }
        else
        {
          var accessToken = "Could not get the access token.";
          Services.WriteLogFile(accessToken);
          Console.WriteLine(accessToken);
          return null;
        }

      }
      catch (Exception e)
      {
        var error = e;
        Services.WriteLogFile(error.ToString());
        Console.WriteLine(error);
        throw;
      }
    }
  }
}

{"password", ConfigurationManager.AppSettings["userPassword"]} 行应该受到影响,因此我使用新的应用程序密码更新了 AppSettings。收到此错误,但鉴于我使用的是应用程序密码,它似乎应该可以正常工作:

Formatted JSON Data
{ 

   "error":"invalid_grant",
   "error_description":"AADSTS50126: Error validating credentials due to invalid username or password.\r\nTrace ID: 17bf1365-32a0-439e-bd99-9eaf8e3bab00\r\nCorrelation ID: 4d24cac1-dae9-49b7-961f-c7c739f885f4\r\nTimestamp: 2020-02-24 20:33:43Z",
   "error_codes":[ 

      50126
   ],
   "timestamp":"2020-02-24 20:33:43Z",
   "trace_id":"17bf1365-32a0-439e-bd99-9eaf8e3bab00",
   "correlation_id":"4d24cac1-dae9-49b7-961f-c7c739f885f4",
   "error_uri":"https://login.windows.net/error?code=50126"
}

真的,不确定我是否应该更新程序中的其他内容以适应 MFA,但我读过的文章表明我应该只生成应用程序密码,这应该很好。建议?

我建议你使用a refresh token to refresh the access token。使用刷新令牌,您可以绕过 MFA 的这一限制。

要获取刷新令牌,您需要按照Azure AD OAuth2 auth code flow以交互方式获取刷新令牌。然后你可以用你得到的刷新令牌得到一个新的令牌。

请注意,刷新令牌应保密。如果它遭到破坏,您可以使用 PowerShell 撤销特定用途的所有刷新令牌 Revoke-AzureADUserAllRefreshToken