web-dev-qa-db-ja.com

401- REST API Dynamics CRM with Azure ADを使用した不正認証

Dynamics CRM OnlineにアクセスしようとしていますREST Azure ADを使用したAPI oAuth 2認証。これを行うには、次の手順に従います。

-AzureにWebアプリケーションまたはWeb APIを登録しました
-委任された権限 "組織ユーザーとしてCRM Onlineにアクセス"を持つようにDynamics CRMへの権限を構成しました
-有効期限が1年間のキーを作成し、クライアントIDを生成したままにしました。

AzureでWebアプリを構成した後、ADALを使用して簡単なリクエストを作成するコンソールアプリケーションを.NET/C#で作成しました。この場合は、アカウントのリストを取得します。

    class Program
{
    private static string ApiBaseUrl = "https://xxxxx.api.crm4.dynamics.com/";
    private static string ApiUrl = "https://xxxxx.api.crm4.dynamics.com/api/data/v8.1/";
    private static string ClientId = "2a5dcdaf-2036-4391-a3e5-9d0852ffe3f2";
    private static string AppKey = "symCaAYpYqhiMK2Gh+E1LUlfxbMy5X1sJ0/ugzM+ur0=";

    static void Main(string[] args)
    {
        AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(new Uri(ApiUrl)).Result;

        var clientCredential = new ClientCredential(ClientId, AppKey);

        var authenticationContext = new AuthenticationContext(ap.Authority);
        var authenticationResult = authenticationContext.AcquireToken(ApiBaseUrl, clientCredential);

        var httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);

        var result = httpClient.GetAsync(Path.Combine(ApiUrl, "accounts")).Result;         
    }
}

アクセストークンを正常に取得しましたが、CRMにhttpリクエストを実行しようとすると、常に401-Unauthorized status codeが返されます。何が欠けていますか?

13
André Cavaca

1年と2か月後、この同じコードは完全に機能します。多くの人が述べたように、Dynamics 365は当面サーバー間(S2S)認証をサポートし始めました。私が当時しなかった唯一の手順は、アプリケーションユーザーを作成することでした。この認証を機能させる方法の詳細については、次のWebサイトを確認してください。 https://msdn.Microsoft.com/en-us/library/mt790170.aspx

5
André Cavaca

回答ありがとうございます。最終的にADAL 3を使用してDynamics CRM OData APIにアクセスできました。

多くの人々はまだこれを行うのに問題を抱えているので、次のステップを見てください:

アプリの登録

  1. ログインportal.Azure.com Dynamics CRMサブスクリプションのOffice 365管理者ユーザーを使用します。

  2. Azure Active Director\App登録に移動し、新しいアプリケーション登録を追加します

  3. 「名前」と「サインオンURL」を入力します。URLは何でもかまいません(たとえば、 https:// localhost

  4. 作成した登録済みアプリを選択し、Settings\Keysに移動します

  5. キーの説明を入力し、[保存]をクリックして値をコピーします(後で必要になるため、そのままにしておきます)。また、登録済みアプリのアプリケーションIDをコピーします。

  6. [必要な権限]に移動し、[追加]をクリックして、[Dynamics CRM Online]を選択し、[組織ユーザーとしてCRM Onlineにアクセスする]を選択します。

これらの手順により、クライアントアプリケーションは、手順5で作成したアプリケーションIDとクライアントシークレットを使用してDynamics CRMにアクセスできるようになります。これで、クライアントアプリケーションをauthenticatedCRM Onlineにアクセスする権限を持つAzure ADに対して。ただし、CRM Onlineはこの「クライアントアプリケーション」または「ユーザー」を認識していません。 CRM APIは、アクセスしようとすると401を応答します。

CRMアプリケーションユーザーを追加する

CRMに「クライアントアプリケーション」または「ユーザー」を知らせるには、アプリケーションユーザーを追加する必要があります。

  1. CRM \セキュリティロールに移動し、新しいセキュリティロールを作成するか、「システム管理者」ロールをコピーします

  2. CRM\Settings\Security\Usersに移動し、新しいユーザーを作成して、フォームを「アプリケーションユーザー」に変更します。

  3. 前のステップで取得したアプリケーションIDを使用して必須フィールドに入力します。保存すると、CRMはAzure ADオブジェクトIDとURIを自動的に入力します。

  4. 前の手順で作成したセキュリティロールにユーザーを追加します。

これで、以下のサンプルコードを使用して、HttpClientおよびADALを使用してCRM APIにアクセスできるようになります。

var ap = await AuthenticationParameters.CreateFromResourceUrlAsync(
                new Uri("https://*****.api.crm6.dynamics.com/api/data/v9.0/"));

String authorityUrl = ap.Authority;
String resourceUrl = ap.Resource;

var authContext = new AuthenticationContext(authorityUrl);
var clientCred = new ClientCredential("Application ID", "Client Secret");
var test = await authContext.AcquireTokenAsync(resourceUrl, clientCred);

Console.WriteLine(test.AccessToken);

using (var client = new HttpClient())
{
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", test.AccessToken);

    var response = await client.GetAsync("https://*****.api.crm6.dynamics.com/api/data/v9.0/contacts");
    var contacts = await response.Content.ReadAsStringAsync();

    Console.WriteLine(contacts);
}
10
Van Nguyen

最新のリリースでDynamics 365に追加されたサーバー間(S2S)認証を確認することをお勧めします。

S2Sを使用することで、有料のDynamics 365ライセンスは必要ありません。アプリケーションは、ユーザーの資格情報ではなく、Dynamics 365アプリケーションのユーザーレコードに格納されているAzure ADオブジェクトID値によって識別されるサービスプリンシパルに基づいて認証されます。

詳細については、こちらをご覧ください: https://msdn.Microsoft.com/en-us/library/mt790168.aspxhttps://msdn.Microsoft.com/en-us /library/mt790170.aspx

3
Hendry Timmer

ClientId、AzureのAppKeyなので、var authenticationContext = new AuthenticationContext(ap.Authority);ではap.Authorityhttps://login.microsoftonline.com/tenantidである必要があります

0
Lily_user4045

少なくともある種の「統合アカウント」にユーザー資格情報を提供することはできません。次のようにすると、より伝統的なポップアップ/リダイレクトOAUTHフローを回避できます。

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.IO;
using System.Net;

namespace ConsoleApplication2
{
    class Program
    {
        private static string API_BASE_URL = "https://<CRM DOMAIN>/";
        private static string API_URL = "https://<CRM DOMAIN>/api/data/v8.1/";
        private static string CLIENT_ID = "<CLIENT ID>";

        static void Main(string[] args)
        {
            var userCredential = new UserCredential("<USERNAME>", "<PASSWORD>");
            var authContext = new AuthenticationContext("https://login.windows.net/common", false);
            var result = authContext.AcquireToken(API_BASE_URL, CLIENT_ID, userCredential);

            var httpClient = HttpWebRequest.CreateHttp(Path.Combine(API_URL, "accounts"));
            httpClient.Headers.Add(HttpRequestHeader.Authorization, "Bearer:" + result.AccessToken);
            using (var sr = new StreamReader(httpClient.GetResponse().GetResponseStream()))
            {
                Console.WriteLine(sr.ReadToEnd());
            }

            Console.ReadLine();
        }
    }
}

注:passwordパラメーターがUserCredentialコンストラクターから取り出されているように見えるので、ADALの古いバージョン( 2.19.20802021 )を使用しています。

EDIT:CRMで サーバーからサーバーへの認証 がサポートされるようになりました。これにより、アプリケーションユーザーを作成できます。

0
Matt Dearing

Azureアプリケーションと一致するようにCRM内でアプリケーションユーザーの設定が必要になる場合があります。 https://msdn.Microsoft.com/en-us/library/mt790170.aspx

C#でベアラートークンの設定を取得できますが、CRMレベルの権限により、CRMリソースへのWebリクエストが失敗する場合があります。

0
user14114