3

オンラインでホストされている Dynamics 2016 インスタンスに接続するために内部管理アプリケーションを変更しています。

いくつかのオンライン チュートリアルに従って、SDKのOrganizationServiceProxyアウト アウトを使用しています。Microsoft.Xrm.Sdk.Client

接続するにはユーザー名とパスワードが必要なようですが、これは問題なく動作しますが、特定のユーザーのアカウントの詳細を必要としない方法で接続したいと考えています。UI がなく、OAuth 要求を表示する実際の人がいないため、私が見た OAuth の例は適切ではないと思います。

public class DynamicsHelper
{
    private OrganizationServiceProxy service;

    public void Connect(string serviceUri, string username, string password)
    {
            var credentials = new ClientCredentials();
            credentials.UserName.UserName = username;
            credentials.UserName.Password = password;

            var organizationUri = new Uri(serviceUri);
            this.service = new OrganizationServiceProxy(organizationUri, null, credentials, null);
    }
}

アプリケーション トークンまたは API キーで接続する方法はありますか?

4

3 に答える 3

1

これを正常に行うには、次のすべてをセットアップする必要があることがわかりました。

  1. Azure AD でアプリケーション登録を作成します。
    • Dynamics の API アクセス許可、具体的には「組織ユーザーとして Dynamics 365 にアクセスする」を付与します。
    • 次のようなダミーの Web リダイレクト URI を指定します。http://localhost/auth
    • クライアント シークレットを生成し、後で使用するために保存する
  2. Azure AD でユーザー アカウントを作成し、Dynamics へのアクセス許可を付与します。
  3. 上記の非対話型ユーザー アカウントと同じ電子メールを使用して、Dynamics でアプリケーション ユーザー レコードを作成します。
  4. 作成したユーザー アカウントを使用してアプリケーションを認証します。

ステップ 4 では、新しいシークレット ウィンドウを開き、次のパターンを使用して URL を作成し、ステップ 2 でユーザー アカウントの資格情報を使用してログインします。

https://login.microsoftonline.com/<your aad tenant id>/oauth2/authorize?client_id=<client id>&response_type=code&redirect_uri=<redirect uri from step 1>&response_mode=query&resource=https://<organization name>.<region>.dynamics.com&state=<random value>

これが完了すると、Dynamics アプリケーション ユーザーにアプリケーション ID とアプリケーション ID URI があることがわかります。

これで、ClientId と ClientSecret、および他のいくつかの組織固有の変数を使用して、Azure Active Directory (AAD) で認証し、oauth トークンを取得してOrganizationWebProxyClient. これを行う完全なコード例を見つけたことはありませんが、独自の目的で次のコードを開発しました。取得したトークンの有効期限は 1 時間です。

internal class ExampleClientProvider
{
    // Relevant nuget packages:
    // <package id="Microsoft.CrmSdk.CoreAssemblies" version="9.0.2.9" targetFramework="net472" />
    // <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="4.5.1" targetFramework="net461" />

    // Relevant imports:
    // using Microsoft.IdentityModel.Clients.ActiveDirectory;
    // using Microsoft.Crm.Sdk.Messages;
    // using Microsoft.Xrm.Sdk;
    // using Microsoft.Xrm.Sdk.Client;
    // using Microsoft.Xrm.Sdk.WebServiceClient;

    private const string TenantId = "<your aad tenant id>";                 // from your app registration overview "Directory (tenant) ID"
    private const string ClientId = "<your client id>";                     // from your app registration overview "Application (client) ID"
    private const string ClientSecret = "<your client secret>";             // secret generated in step 1
    private const string LoginUrl = "https://login.microsoftonline.com";    // aad login url
    private const string OrganizationName = "<your organization name>";     // check your dynamics login url, e.g. https://<organization>.<region>.dynamics.com
    private const string OrganizationRegion = "<your organization region>"; // might be crm for north america, check your dynamics login url    

    private string GetServiceUrl()
    {
        return $"{GetResourceUrl()}/XRMServices/2011/Organization.svc/web";
    }

    private string GetResourceUrl()
    {
        return $"https://{OrganizationName}.api.{OrganizationRegion}.dynamics.com";
    }

    private string GetAuthorityUrl()
    {
        return $"{LoginUrl}/{TenantId}";
    }

    public async Task<OrganizationWebProxyClient> CreateClient()
    {
        var context = new AuthenticationContext(GetAuthorityUrl(), false);
        var token = await context.AcquireTokenAsync(GetResourceUrl(), new ClientCredential(ClientId, ClientSecret));

        return new OrganizationWebProxyClient(new Uri(GetServiceUrl()), true)
        {
            HeaderToken = token.AccessToken,
            SdkClientVersion = "9.1"
        };
    }

    public async Task<OrganizationServiceContext> CreateContext()
    {
        var client = await CreateClient();
        return new OrganizationServiceContext(client);
    }

    public async Task TestApiCall()
    {
        var context = await CreateContext();

        // send a test request to verify authentication is working
        var response = (WhoAmIResponse) context.Execute(new WhoAmIRequest());
    }
}
于 2019-02-19T21:57:30.803 に答える