前の質問: ADAL JS で Azure AD と OAuth2 の暗黙的な許可を使用してクレームをグループ化する に続いて、ユーザーが Azure/ADAL JS を使用して認証できるように設定し、トークンを使用して Azure Graph API にアクセスします。そのユーザーに代わって。これはうまく機能し、ユーザーとグループの情報を取得できます。
ただし、別のシステムが個々のユーザーとしてではなく、アプリケーションのコンテキストでアプリケーションにログインするというユース ケースがあります。正しく行っているかどうかはわかりませんが、AAD API からトークンを要求することによって認証するクライアント キーを持つ 2 つ目の Azure AD アプリケーションを取得しました。トークンを取得して、それをアプリケーションに渡すことができます。ただし、そのトークンを使用して、そのユーザー (現在はアプリケーション) に代わって Azure Graph API にアクセスすることはできなくなりました。
まず、これは実際に可能ですか、それとも私は不可能を試みていますか?
可能であれば、それを機能させるにはどうすればよいですか? Azure アプリケーションのアクセス許可だけですか? コードで別の方法で行う必要がありますか?
ユーザーに代わって Graph API にアクセスするために使用するコード (例外処理と null チェックを削除) は次のとおりです。
var authContext = new AuthenticationContext("https://login.microsoftonline.com/common");
var clientCredential = new ClientCredential("clientId", "key");
var userAssertion = new UserAssertion(((BootstrapContext)identity.BootstrapContext).Token);
var result = await authContext.AcquireTokenAsync("https://graph.windows.net", clientCredential, userAssertion);
return result.AccessToken;
私が得る例外はAADSTS50034: To sign into this application the account must be added to the {directory ID of my main application} directory
、のエラーですinvalid_grant
。
すべての Azure アプリケーションが正しく構成されていると信じているため、少なくともユーザー認証用であるため、何が間違っていたのかわかりません。また、他のディレクトリがユーザー認証に必要とする 2 番目の Azure AD (クライアント) アプリケーションにも、同じアプリケーションと委任されたアクセス許可を適用しました。
どんな助けでも大歓迎です。
更新: システムの概要/構成
そのため、システムがどのように構成されているかについて十分なコンテキストを提供していないように見えるので、ここでそれに対処しようとしましょう。
Azure で実行されているエンタープライズ SaaS アプリケーションがあります (これをアプリケーションと呼びましょう)。Azure AD には "アプリケーション" があります (混乱を避けるために、これを AAD アプリケーションと呼びましょう)。これはマルチテナント AAD アプリケーションであり、ユーザーは AAD 経由で OAuth2 を使用して認証します。
エンタープライズ アプリケーションであるため、お客様はすべて独自の Azure AD (オンプレミス AD と同期されている場合とされていない場合があります) を持っています (これを AADと呼びましょう)。アプリケーションと連携するようにシステムを構成する場合、AADのグローバル管理者に、Windows Azure Active Directory に対する次のアクセス許可に対するAAD アプリケーションの同意を付与してもらいます (管理者の同意付与を使用) 。
- アプリケーションの権限:
- ディレクトリ データの読み取り
- 委任された権限:
- サインインしたユーザーとしてディレクトリにアクセスする
- ディレクトリ データの読み取り
- サインインしてユーザー プロファイルを読む
ユーザーがアプリケーションを参照すると、認証のために Azure にリダイレクトされます。( AADまたはAADに接続されたオンプレミスの AD を介して)認証された後、Web アプリを介して行われたすべての API 呼び出しにはベアラー トークンが含まれます。各 Bearer トークンを初めて確認すると、それを使用して Azure Graph API (ユーザーに代わって) の新しいトークンを取得し、Graph API にユーザーの詳細とグループ メンバーシップを照会します。これはすべて、ユーザーが自分のユーザー アカウントを使用して UI を介して認証する場合に機能します。
私たちが今目指していることは、顧客が別のダウンストリーム アプリケーション (ダウンストリーム アプリケーション) に独自の Bearer トークンを取得させて、アプリケーションを使用できるようにすることです。今回はユーザーがいないため、クライアント資格情報の付与フローを見ています。これを行うために、お客様は独自の AAD アプリケーション ( AAD アプリケーション) を所有しており、これはAADに含まれています (上記のように既に同意が付与されています)。ダウンストリーム アプリケーションはベアラー トークンを取得して、アプリケーションにアクセスできます。ただし、Azure Graph API のトークンを取得しようとすると (ダウンストリーム アプリケーションの代わりに)、上に貼り付けたエラー メッセージで失敗します。
更新 2
私のチームの別のメンバーがいくつかの調査を行い、これらは彼の発見です.
SDK が舞台裏で何をしているのかを調べ、すべてのリクエストを手動で行って、私たちが行っていることをより適切に再現できるようにすることで、手動でプロセスを進めてきました。
そのため、呼び出し元のサービス (Azure Active Directory 内の Web アプリケーション セットアップ) は、Azure から OAuth トークンを取得します。
POST https://login.microsoftonline.com/<tenant-id>/oauth2/token grant_type client_credentials client_id (the client ID of the calling service application in the AD) client secret (the key configured in the calling service application in the AD) resource (the client ID of our web service)
そして、、、 などを含み、 、 などを
appid
含まない有効なトークンを取得します(ユーザーではなくアプリケーションであるため)。tid
oid
iss
name
upn
次に、Graph API からサービス プリンシパルの詳細を検索し、アプリケーションに代わって Graph API トークンを取得するように要求します。
POST https://login.microsoftonline.com/common/oauth2/token grant_type urn:ietf:params:oauth:grant-type:jwt-bearer client_id (our web service application client ID) client_secret (our web service application client key) resource https://graph.windows.net assertion (the token that was sent by the calling client service, obtained by the process above) requested_token_use on_behalf_of scope openid
これは基本的に、次のコード (SDK コードから抽出) を呼び出すとどうなるかです。
var authContext = new AuthenticationContext("https://login.microsoftonline.com/common"); var clientCredential = new ClientCredential("clientId", "key"); var userAssertion = new UserAssertion(((BootstrapContext)identity.BootstrapContext).Token); var result = await authContext.AcquireTokenAsync("https://graph.windows.net", clientCredential, userAssertion); return result.AccessToken;
返されるのは次のとおりです。
{ "error": "invalid_grant", "error_description": "AADSTS50034: To sign into this application the account must be added to the <customer tenant id> directory.\r\nTrace ID: <removed>\r\nCorrelation ID: <removed>\r\nTimestamp: 2015-10-08 06:37:58Z", "error_codes": [ 50034 ], "timestamp": "2015-10-08 06:37:58Z", "trace_id": "<removed>", "correlation_id": "<removed>" }
質問は、呼び出し元が実際のユーザーではなく Web/ネイティブ アプリケーションである場合、ベアラー トークンを使用して呼び出し元に代わってグラフ API トークンを取得できるかということだと思います。