Microsoft Dataverse で OAuth 認証を使用する
OAuth 2.0 は、認証の業界標準プロトコルです。 アプリケーションのユーザーが認証に資格情報を提供した後、OAuth はリソースにアクセスする権限があるかどうかを判断します。
クライアント アプリケーションは、Web API を使用してデータにアクセスする OAuth の使用をサポートする必要があります。 OAuth は、サーバー間アプリケーション シナリオの、2 要素認証 (2FA) または証明書ベースの認証を有効にします。
OAuth では、認証に ID プロバイダーが必要です。 Dataverse については、 Azure Active Directory (AAD) が ID プロバイダーとなります。 Microsoftの職場または学校のアカウントを使用してAADで認証するには、 Azure Active Directory Authentication Libraries (ADAL) または Microsoft 認証ライブラリ (MSAL) を使用します。
注意
本トピックでは、OAuth と認証ライブラリを使用した Dataverse への接続に関する共通した概念を扱います。 このコンテンツでは開発者が Dataverse に接続する方法を重点的に扱っており、OAuth やライブラリの内部の動作には焦点をあてていません。 認証に関する完全な情報については、 Azure Active Directory ドキュメントを参照してください。 認証とは何か のページから参照することをお勧めします。
提供するサンプルは適切な登録値で事前に構成されているため、独自のアプリ登録を生成せずに実行できます。 独自のアプリを公開する場合は、独自の登録値を使用する必要があります。
アプリ登録
OAuth を使用して接続するには、 ご利用の Azure AD テナントにてアプリケーションを登録する必要があります。 アプリを登録する方法は、作成するアプリの種類によって異なります。
どちらの場合でも、次のAAD topicに記載された基本的な手順に従って着手してください: クイックスタート: Azure Active Directory v1.0 エンドポイントでアプリを登録する。 Dataverse の特定の手順については、ウォークスルー : Azure Active Directory でアプリを登録する > アプリケーションの登録を行うを参照してください。
このステップで実行する必要のある決定のほとんどは、アプリケーションの種類の選択に依存します (以下を参照)。
アプリ登録の種類
Azure AD にてアプリケーションを登録する際には、アプリケーションの種別を選択する必要があります。 登録できるアプリケーションには 2 種類あります。
| アプリケーションの種類 | 説明 |
|---|---|
| Web アプリ /API | Web クライアント Web サーバーですべてのコードを実行する クライアント アプリケーション の種類。 ユーザー エージェント ベースのクライアント Single Page Application (SPA) などの Web サーバーからコードをダウンロードし、ユーザー エージェント内で実行する (たとえば、Web ブラウザー) クライアント アプリケーション の種類。 |
| ネイティブ モード | デバイスでネイティブにインストールされる クライアント アプリケーション の種類。 |
Web アプリ /API を選択する際に、 サインオンするURL を指定する必要があります。これは Azure AD が認証の応答を送信するURLであり、認証が成功した際にはトークンが含まれます。 アプリの開発中に、これは通常 https://localhost/appname:[port] に設定され、アプリをローカルに開発およびデバッグできます。 アプリを公開する場合、アプリの公開された URL へのこの値を変更する必要があります。
ネイティブ を選択する場合、リダイレクト URI を提供する必要があリます。 Azure AD がOAuth 2.0リクエストにて、ユーザエージェントをリダイレクトするために使用する一意の識別子です。 これは通常、次のように書式設定された値です: app://<guid>。
Dataverse へのアクセス権を付与する
アプリが、認証されたユーザーに操作を実行させるクライアントである場合、アクセス許可を委任された組織のユーザーとして Dynamics 365 にアクセスするようアプリケーションを構成する必要があります。
これを行うために必要となる手順は、 ウォークスルー: Azure Active Directory でアプリを登録する > 権限の付与を参照してください。
アプリがサーバー間 (S2S) の認証を使用する場合、この手順は必要ありません。 その構成には特定のシステム ユーザーが必要であり、その操作は認証が必要である任意のユーザーによるのではなく、そのユーザー アカウントにより実行されます。
暗黙的なフローを有効にする
アプリを Single Page Application (SPA) に構成している場合、マニフェストの oauth2AllowImplicitFlow 値を true に設定するよう変更する必要があります。 詳細: チュートリアル: adal.js で SPA アプリケーションを登録および構成する
クライアント シークレット & 証明書の使用
サーバ間のシナリオでは、認証する対話型ユーザー アカウントはありません。 このような場合、アプリケーションが信頼できることを確認するためのいくつかの手段を提供する必要があります。 これはクライアント シークレットまたは証明書を使用して実行されます。
Web アプリ /API アプリケーションの種類で登録されるアプリに関しては、シークレットを構成できます。 これらは、アプリ登録の 設定 で API アクセス にある キー 領域を使用して設定されます。
どちらのアプリケーションの種類でも、証明書をアップロードできます。
詳細: アプリとして接続
認証ライブラリを使用して接続する
Microsoft がサポートする Azure Active Directory 認証クライアント ライブラリの 1 つを使用して Dataverse に接続します。 Microsoft が提供するそのようなライブラリは 2 つあります: Azure Active Directory 認証ライブラリ (ADAL)、Microsoft 認証ライブラリ (MSAL)。 提供されたリンクの説明のように、これらのライブラリはさまざまなプラットフォームで利用できます。
注意
上記の 2 つの認証ライブラリのうち、ADAL は現在アクティブに更新されておらず、2022 年 6 月までサポートされる予定です。 MSAL は、新しいプロジェクトで使用するように推奨される認証ライブラリです。
現在は、JavaScript ADAL.js ライブラリを使用する OAuth を使用するクロス オリジン リソース共有を使用して、単一のページ アプリケーションに接続する を除くすべてのサンプルは .NET クライアント ライブラリを使用します。Dataverse の認証で ADAL と MSAL ライブラリを使用する方法を示すコード サンプルについては、クイックスタート サンプル を参照してください。
ADAL .NET クライアント ライブラリ バージョン
Dataverse は、OAuth 2.0 プロトコルを使用した Web API エンドポイントで、アプリケーション認証をサポートします。 カスタム .NET アプリケーションの場合、Web API エンドポイントでのアプリケーション認証に ADAL v3.19 以降を使用します。 Microsoft.CrmSdk.XrmTooling.CoreAssembly NuGet パッケージが含む XrmTooling API (CrmServiceClient など) を使用する場合、適切なバージョンの ADAL ライブラリが Visual Studio プロジェクトに自動でインポートされます。 v9.1.0.13 以降の NuGet パッケージが含む XrmTooling API を使用します。 リリース履歴についてはパッケージのリリース ノートを参照してください。
要求で AccessToken を使用します
認証ライブラリを使用するポイントは、要求に含めることができるアクセス トークンを取得することです。 これにはコードの数行のみが必要で、HttpClient がリクエストを実行するよう構成するにはさらにいくつかの行が必要です。
単純な例
単一の Web API 要求を実行するために必要な最小コード数は次のとおりですが、推奨されている方法ではありません。 このコードは ADAL ライブラリを使用しており、上記のクイック スタート サンプルから取得したコードであることに注意してください。
string resource = "https://contoso.api.crm.dynamics.com";
var clientId = "51f81489-12ee-4a9e-aaae-a2591f45987d";
var redirectUri = new Uri("app://58145B91-0C36-4500-8554-080854F2AC97");
var authContext = new AuthenticationContext(
"https://login.microsoftonline.com/common", false);
var token = authContext.AcquireTokenAsync(
resource, clientId, redirectUri,
new PlatformParameters(
PromptBehavior.SelectAccount // Prompt the user for a logon account.
),
UserIdentifier.AnyUser
).Result;
var client = new HttpClient
{
BaseAddress = new Uri(resource + "/api/data/v9.2/"),
Timeout = new TimeSpan(0, 2, 0)
};
HttpRequestHeaders headers = client.DefaultRequestHeaders;
headers.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
headers.Add("OData-MaxVersion", "4.0");
headers.Add("OData-Version", "4.0");
headers.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.GetAsync("WhoAmI").Result;
token が 1 時間以内に期限切れになるため、この単純な方法は従うべき良いパターンとは言えません。 ADAL ライブラリはトークンをキャッシュし、AcquireTokenAsync メソッドが呼び出されるたびにそれを更新します。 ただし、この単純な例ではトークンを 1 回だけ取得しています。
委任メッセージ ハンドラーを示す例
推奨されている方法は、HttpClient のコンストラクタに渡される DelegatingHandler から派生したクラスを実装することです。 このハンドラーでは HttpClient を上書きすることができるようになります。SendAsync メソッドによって、HTTP クライアントが要求を送信するたびに AcquireToken* メソッドの呼び出しでアクセス トークンが更新されます。
DelegatingHandler から派生したカスタム クラスの例を以下に示します。 このコードは、MSAL 認証ライブラリを使用する 拡張クイック スタート のサンプルから取得したものです。
class OAuthMessageHandler : DelegatingHandler
{
private AuthenticationHeaderValue authHeader;
public OAuthMessageHandler(string serviceUrl, string clientId, string redirectUrl, string username, string password,
HttpMessageHandler innerHandler)
: base(innerHandler)
{
string apiVersion = "9.2";
string webApiUrl = $"{serviceUrl}/api/data/v{apiVersion}/";
//Build Microsoft.Identity.Client (MSAL) OAuth Token Request
var authBuilder = PublicClientApplicationBuilder.Create(clientId)
.WithAuthority(AadAuthorityAudience.AzureAdMultipleOrgs)
.WithRedirectUri(redirectUrl)
.Build();
var scope = serviceUrl + "//.default";
string[] scopes = { scope };
AuthenticationResult authBuilderResult;
if (username != string.Empty && password != string.Empty)
{
//Make silent Microsoft.Identity.Client (MSAL) OAuth Token Request
var securePassword = new SecureString();
foreach (char ch in password) securePassword.AppendChar(ch);
authBuilderResult = authBuilder.AcquireTokenByUsernamePassword(scopes, username, securePassword)
.ExecuteAsync().Result;
}
else
{
//Popup authentication dialog box to get token
authBuilderResult = authBuilder.AcquireTokenInteractive(scopes)
.ExecuteAsync().Result;
}
//Note that an Azure AD access token has finite lifetime, default expiration is 60 minutes.
authHeader = new AuthenticationHeaderValue("Bearer", authBuilderResult.AccessToken);
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
request.Headers.Authorization = authHeader;
return base.SendAsync(request, cancellationToken);
}
}
この OAuthMessageHandler クラスを使用した、単純な Main メソッドを次に示します。
class Program
{
static void Main(string[] args)
{
try
{
//Get configuration data from App.config connectionStrings
string connectionString = ConfigurationManager.ConnectionStrings["Connect"].ConnectionString;
using (HttpClient client = SampleHelpers.GetHttpClient(connectionString, SampleHelpers.clientId,
SampleHelpers.redirectUrl))
{
// Use the WhoAmI function
var response = client.GetAsync("WhoAmI").Result;
if (response.IsSuccessStatusCode)
{
//Get the response content and parse it.
JObject body = JObject.Parse(response.Content.ReadAsStringAsync().Result);
Guid userId = (Guid)body["UserId"];
Console.WriteLine("Your UserId is {0}", userId);
}
else
{
Console.WriteLine("The request failed with a status of '{0}'",
response.ReasonPhrase);
}
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}
catch (Exception ex)
{
SampleHelpers.DisplayException(ex);
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}
}
構成文字列値は App.config ファイルの接続文字列に移動し、HTTP クライアントは GetHttpClient メソッドで構成します。
public static HttpClient GetHttpClient(string connectionString, string clientId, string redirectUrl, string version = "v9.2")
{
string url = GetParameterValueFromConnectionString(connectionString, "Url");
string username = GetParameterValueFromConnectionString(connectionString, "Username");
string password = GetParameterValueFromConnectionString(connectionString, "Password");
try
{
HttpMessageHandler messageHandler = new OAuthMessageHandler(url, clientId, redirectUrl, username, password,
new HttpClientHandler());
HttpClient httpClient = new HttpClient(messageHandler)
{
BaseAddress = new Uri(string.Format("{0}/api/data/{1}/", url, version)),
Timeout = new TimeSpan(0, 2, 0) //2 minutes
};
return httpClient;
}
catch (Exception)
{
throw;
}
}
完全なコードは 拡張クイックスタート のサンプルを参照してください。
その場合この例では、HttpClient を使用します。GetAsync SendAsync を上書きするのではなく、要求に送信される HttpClient メソッドのいずれかを適用します。
実行時の権限を確認します
認証の権限 URL、およびリソース URLは、次の ADAL コードを使用して実行時に動的に検出されます。 これは上記のコード スニペットで表示されている有名な権限 URL ("https://login.microsoftonline.com/common") と比較して使用するための、推奨されている方法です。
AuthenticationParameters ap = AuthenticationParameters.CreateFromResourceUrlAsync(
new Uri("https://mydomain.crm.dynamics.com/api/data/")).Result;
String authorityUrl = ap.Authority;
String resourceUrl = ap.Resource;
Web API の場合、権限 URL を取得する別の方法は、Web サービスに、アクセス トークンを指定しないメッセージ要求を送信することです。 これを ベアラー チャレンジ と呼びます。 反応は、権限 URL を取得するために解析されます。
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "");
アプリとして接続
作成する一部のアプリは、ユーザーが対話的に実行するためのものではありません。 たとえば、Dataverse データに対する操作を実行できる Web クライアント アプリケーションや、あるスケジュールに基づいたタスクを実行するコンソールアプリケーションを作成するなどのケースが考えられます。
一般のユーザーの資格情報を使用してこれらのシナリオを実行することはできますが、そのユーザー アカウントでは有料ライセンスを使用する必要があります。 これは推奨されている方法ではありません。
このような場合は、 Azure Active Directory に登録されたアプリケーションにバインドされる特別なアプリケーションユーザーを作成し、そのアプリケーション用に設定されたキー シークレットを使用するか、 X.509 の証明書をアップロードします。 この方法の別の利点は、有料ライセンスを使用しないことです。
アプリとして接続するための要求
アプリとして接続するには以下の点が必要です。
- 登録済みアプリ
- 登録されたアプリにバインドされた Dataverse ユーザー
- アプリケーション シークレットまたは証明書サムプリントのいずれかを使用して接続する
アプリの登録
アプリを登録する際は、 ウォークスルー: Azure Active Directoryにてアプリを登録する に記載されて手順と以下の例外処理に従ってください。
組織のユーザーとして Dynamics 365 にアクセスする アクセス許可の付与は必要ありません。
このアプリケーションは特定のユーザー アカウントにバインドされます。
アプリ登録のシークレットを構成するか、公開キー証明書をアップロードする必要があります。
アプリを登録している間に、設定 ページの キー セクションを選択します。
証明書を追加するには:
- 公開キーのアップロード を選択します。
- アップロードするファイルを選択します。 次のいずれかのファイルの種類である必要があります: .cer、.pem、.crt。
パスワードを追加するには:
- キーに関する説明を追加します。
- 期間を選択します。
- 保存 を選びます。
構成の変更を保存した後、一番右の列にキー値が表示されます。 このページから一旦離れるとアクセスできないため、クライアント アプリケーション コードで使用するためにキーをコピーしておいてください。
登録されたアプリにバインドされた Dataverse のユーザー アカウント
最初に必須となる作業は、セキュリティ役割のカスタマイズです。ここで Dataverse の内部でこのアカウントにどのようなアクセス権や権限を付与するかを定義します。 詳細: ユーザー定義セキュリティ ロールの作成または編集
ユーザー定義セキュリティ ロールを作成した後、使用するユーザー アカウントを作成する必要があります。
Dataverse アプリケーション ユーザーを手動で作成します
このユーザーを作成する手順は、ライセンスを受けたユーザーを作成する手順とは異なります。 次の手順を実行します。
設定 > セキュリティ > ユーザー の順に移動します
ビュー ドロップダウンで、アプリケーション ユーザー を選択します。
新規 をクリックします。 次に アプリケーション ユーザー フォームを使用していることを確認します。
フォーム上に アプリケーション ID, アプリケーション ID URI 、 Azure AD オブジェクト ID フィールドがない場合は、リストから アプリケーション ユーザー を選択してください:

フィールドに適切な値を追加します:
フィールド 値 ユーザー名 ユーザーの名前 アプリケーション ID Azure AD に登録されたアプリケーションのアプリケーションID の値 氏名 アプリケーションの名前。 電子メール 1 ユーザーの電子メール アドレス。 アプリケーション ID URI および Azure AD オブジェクト ID フィールドはロックされており、これらのフィールドに入力することはできません。
このユーザーを作成すると、これらフィールドの値には当該ユーザーを保存した際の アプリケーションID 値に基づいて Azure AD から取得されます。
アプリケーション ユーザーを作成したユーザー定義セキュリティ ロールに関連付けます。
アプリケーション シークレットを使用して接続する
アプリケーション用に構成されたシークレットを使用して接続している場合、userName および password パラメーターの UserCredential ではなく、clientId および clientSecret で渡している ClientCredential クラスを使用します。
string serviceUrl = "https://yourorg.crm.dynamics.com";
string clientId = "<your app id>";
string secret = "<your app secret>";
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/<Tenant-ID-here>");
ClientCredential credential = new ClientCredential(clientId, secret);
AuthenticationResult result = authContext.AcquireToken(serviceUrl, credential);
string accessToken = result.AccessToken;
証明書サムプリントを使用して接続する
証明書を使用し Microsoft.Xrm.Tooling.Connector を使用して接続している場合。CrmServiceClient 次のようなコードを使用できます。
string CertThumbPrintId = "DC6C689022C905EA5F812B51F1574ED10F256FF6";
string AppID = "545ce4df-95a6-4115-ac2f-e8e5546e79af";
string InstanceUri = "https://yourorg.crm.dynamics.com";
string ConnectionStr = $@"AuthType=Certificate;
SkipDiscovery=true;url={InstanceUri};
thumbprint={CertThumbPrintId};
ClientId={AppID};
RequireNewInstance=true";
using (CrmServiceClient svc = new CrmServiceClient(ConnectionStr))
{
if (svc.IsReady)
{
//your code goes here
}
}
関連項目
Microsoft Dataverse ウェブサービス を使用した認証
.NET Framework アプリケーションを認証する
Microsoft 認証ライブラリの概要
注意
ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)
この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。
フィードバック
フィードバックの送信と表示