OAuth on_behalf_of の利用 (Azure AD)


(本投稿は、過去に掲載した投稿を分離。。。)

こんにちは。

Azure AD (Azure Active Directory) の Token 認証では、OAuth 2.0 の on_behalf_of を使ってアプリケーション間をまたがった Impersonation の仕組みが利用できます。

過去に「SharePoint 2013 Apps: .NET CSOM を使ったプログラミングと認証 (Authentication)」でも記載しましたが、Access Token には User Context と App Context が含まれています。例えば、User1 が TestClient1 を使って TestService1 を呼び出した場合、TestService1 では、Access Token を確認して、誰 (=User1) が、どんな Application (=TestClient1) を使ってアクセスしているか確認できます。(ただし、Access Token は、App Context のみの場合もあるので注意してください。)

いま、例えば、TestClient1, TestService1, そして もう 1 つ別のサービスとして TestService2 が存在すると仮定します。
ここで紹介する on_behalf_of を使うと、User1 が TestClient1 から TestService1 にアクセスし、この access token を使って、TestService1 が TestService2 に User1 としてアクセスできます。(TestService2 側では、User1 が TestService1 を使ってアクセスしたように見えます。)

今回は、この動作を HTTP Flow で確認してみましょう。

 

Azure AD の事前設定

まず、Azure AD への事前設定として、「Azure AD を使った API (Service) 連携の Client 開発 (OAuth 紹介)」で紹介している手順で、各 Application (TestClient1, TestService1, TestService2) を Azure AD に登録して Permission 設定をおこないます。

TestClient1 に TestService1 へアクセスするための Permission を設定し、さらに、今回のサンプルでは、TestService1 に TestService2 への Permission も付与しておきます。

HTTP Flow

では、TestClient1 から TestService にアクセスするための access token を取得します。

取得方法は「Azure AD を使った API (Service) 連携の Client 開発 (OAuth 紹介)」とまったく同じであり、別に変わったことはしません。(このため、手順詳細は省略します。)
access token を取得したら、Authorization Header に設定して TestService1 (Web API) を呼び出します。

つぎに、要求を受け取った TestService1 側では、Impersonate された token を取得するため、以下の HTTP POST 要求を Azure AD に対して出します。
requested_token_use=on_behalf_of がポイントです。assertion には受け取った access token (TestClient1 が渡した access token) を設定し、resource には TestService2 を指定しています。

POST https://login.microsoftonline.com/common/oauth2/token
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=<received access token>&requested_token_use=on_behalf_of&resource=https%3A%2F%2Fmytenant01.onmicrosoft.com%2FTestService2&scope=openid&client_id=<Client Id of TestService1>&client_secret=<Client Secret of TestService1>

Azure AD は、上記の要求を受け取ると、いつものように jwt 形式で claim や access token などの情報を渡します。この access token には、SignIn をおこなった User Context と、TestService2 の App Context が設定されています。

以降は、この access token を使って、SignIn ユーザーとして TestService2 にアクセスできます。

ADAL を使用した場合

なお、上記の POST 要求は、Azure Active Directory Authentication Library (ADAL) を使うと下記の通りシンプルに記述できます。

string received_access_token =... ;
string client_id =... ;
string client_secret =... ;

AuthenticationContext ctx =
  new AuthenticationContext("https://login.microsoftonline.com/common");
UserAssertion assertion = new UserAssertion(received_access_token);
ClientCredential cred = new ClientCredential(
  client_id,
  client_secret);
AuthenticationResult auth =
  ctx.AcquireToken("https://mytenant01.onmicrosoft.com/TestService2",
    assertion, cred);
. . .

 

使い道はいろいろあります。

例えば、server-to-server 接続で User Context を使用する場合、バックエンドの server 側で SignIn 画面を表示することはできませんが、こうしたケースでこのフローが使えます。
また、この方法を使うと、あるサービス (TestService1) を利用するすべての Client に関連するリソース (TestService2 など多数) へのアクセス権を与えなくても、このサービス (TestService1) が代行して関連リソースすべてにアクセスすることもできます。(Microsoft Graph などは良い例ですね。)
また、「Azure Mobile App の Client-directed Login」で解説した手法を Azure AD でおこなう場合も、このフローを使用します。Native Application 側で SignIn をおこなって access token を取得し、これを Azure Mobile App に渡して、Azure Mobile App 側は、受け取った token が正しいかどうか検証すると共に、Impersonate された token を取得して “そのユーザーとして” (=on_behalf_of) 他のサービスに接続できます。

 

Comments (0)

Skip to main content