Microsoft.Identity.Web には、Microsoft Graph またはダウンストリーム Web API を呼び出す便利なサービスを提供する拡張メソッドが追加されています。 これらのメソッドの詳細については、「Web API を呼び出す Web アプリ: API を呼び出す」を参照してください。 これらのヘルパー メソッドを使用すれば、トークンを手動で取得する必要はありません。
ただし、トークンを手動で取得する場合は、ホーム コントローラーで取得することを目的とした Microsoft.Identity.Web の使用の例が、次のコードによって示されています。 これにより、REST API (Microsoft Graph SDK ではなく) を使用した、Microsoft Graph の呼び出しが行われます。 通常、トークンを取得する必要はありませんが、要求に追加する Authorization ヘッダーを作成する必要があります。 Authorization ヘッダーを取得するには、コントローラーのコンストラクター (Blazor を使用する場合はページ コンストラクター) 内での依存関係の挿入によって、IAuthorizationHeaderProvider
サービスを挿入し、それをコントローラー アクションで使用します。 このインターフェイスには、プロトコル (Bearer や Pop など) とトークンを含む文字列を生成するメソッドが用意されています。 ユーザーに代わって API を呼び出す Authorization ヘッダーを取得するには、(CreateAuthorizationHeaderForUserAsync
) を使用します。 アプリケーション自体に代わってダウンストリーム API を呼び出す Authorization ヘッダーを取得するには、デーモン シナリオで (CreateAuthorizationHeaderForAppAsync
) を使用します。
これらのコントローラー メソッドは、[Authorize]
属性によって保護されていて、認証された呼び出しのみのに Web API の使用が確実に許可されます。
[Authorize]
public class MyApiController : Controller
{
/// <summary>
/// The web API will accept only tokens 1) for users, 2) that have the `access_as_user` scope for
/// this API.
/// </summary>
static readonly string[] scopeRequiredByApi = new string[] { "access_as_user" };
static readonly string[] scopesToAccessDownstreamApi = new string[] { "api://MyTodolistService/access_as_user" };
readonly IAuthorizationHeaderProvider authorizationHeaderProvider;
public MyApiController(IAuthorizationHeaderProvider authorizationHeaderProvider)
{
this.authorizationHeaderProvider = authorizationHeaderProvider;
}
[RequiredScopes(Scopes = scopesToAccessDownstreamApi)]
public IActionResult Index()
{
// Get an authorization header.
IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
return await callTodoListService(authorizationHeader);
}
}
callTodoListService
メソッドの詳細については、「Web API を呼び出す Web API: API の呼び出し」を参照してください。
ASP.NET のコードは、ASP.NET Core 用に示したコードと似ています。
- [Authorize] 属性によって保護されたコントローラー アクションは、コントローラーの
ClaimsPrincipal
メンバーのテナント ID とユーザー ID を抽出します。 (ASP.NET では HttpContext.User
を使用します) Microsoft.Identity.Web.OWIN では、Microsoft Graph またはダウンストリーム Web API を呼び出すための、あるいは Authorization ヘッダーを (またはトークンさえも) 取得するための便利なサービスを提供する拡張メソッドをコントローラーに追加します。 API を直接呼び出すのに使用されるメソッドの詳細については、「Web API を呼び出す Web アプリ: API を呼び出す」を参照してください。 これらのヘルパー メソッドを使用すれば、トークンを手動で取得する必要はありません。
ただし、トークンの取得または Authorization ヘッダーの構築を手動で行いたい場合は、Microsoft.Identity.Web を使用してコントローラーでそれを行う方法を示す次のコードを参照してください。 これにより、Microsoft Graph SDK ではなく REST API を使用した、API (Microsoft Graph) の呼び出しが行われます。
Authorization ヘッダーを取得するには、拡張メソッド IAuthorizationHeaderProvider
を使用してコントローラーから GetAuthorizationHeaderProvider
サービスを取得します。 ユーザーに代わって API を呼び出す Authorization ヘッダーを取得するには、(CreateAuthorizationHeaderForUserAsync
) を使用します。 アプリケーション自体に代わってダウンストリーム API を呼び出す Authorization ヘッダーを取得するには、デーモン シナリオで (CreateAuthorizationHeaderForAppAsync
) を使用します。
コントローラー メソッドは、認証されたユーザーのみが Web アプリを使用できるようにする [Authorize]
属性によって保護されます。
次のスニペットは、HomeController
のアクション (REST API として Microsoft Graph を呼び出す Authorization ヘッダーが取得されます) を示したものです。
[Authorize]
public class MyApiController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
IAuthorizationHeaderProvider authorizationHeaderProvider = this.GetAuthorizationHeaderProvider();
string[] scopes = new string[]{"user.read"};
string authorizationHeader = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);
string json = await client.GetStringAsync(url);
}
}
次のスニペットは、MyApiController
のアクション (REST API として Microsoft Graph を呼び出すアクセス トークンが取得されます) を示したものです。
[Authorize]
public class HomeController : Controller
{
[AuthorizeForScopes(Scopes = new[] { "user.read" })]
public async Task<IActionResult> Profile()
{
// Get an authorization header.
ITokenAcquirer tokenAcquirer = TokenAcquirerFactory.GetDefaultInstance().GetTokenAcquirer();
string[] scopes = new string[]{"user.read"};
string token = await await tokenAcquirer.GetTokenForUserAsync(scopes);
// Use the access token to call a protected web API.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}");
string json = await client.GetStringAsync(url);
}
}
API コントローラーのアクションで呼び出されるコードの例を次に示します。 ダウンストリーム API - Microsoft Graph が呼び出されます。
@RestController
public class ApiController {
@Autowired
MsalAuthHelper msalAuthHelper;
@RequestMapping("/graphMeApi")
public String graphMeApi() throws MalformedURLException {
String oboAccessToken = msalAuthHelper.getOboToken("https://graph.microsoft.com/.default");
return callMicrosoftGraphMeEndpoint(oboAccessToken);
}
}
Python Web API では、クライアントから受信したベアラー トークンを検証するためにミドルウェアを使用する必要があります。 Web API は、acquire_token_on_behalf_of
メソッドを呼び出すことにより、MSAL Python ライブラリを使用してダウンストリーム API のアクセス トークンを取得できます。
acquire_token_on_behalf_of
メソッドと Flask フレームワークを使用してアクセス トークンを取得するコードの例を次に示します。 これはダウンストリーム API (Azure 管理サブスクリプション エンドポイント) を呼び出します。
def get(self):
_scopes = ["https://management.azure.com/user_impersonation"]
_azure_management_subscriptions_uri = "https://management.azure.com/subscriptions?api-version=2020-01-01"
current_access_token = request.headers.get("Authorization", None)
#This example only uses the default memory token cache and should not be used for production
msal_client = msal.ConfidentialClientApplication(
client_id=os.environ.get("CLIENT_ID"),
authority=os.environ.get("AUTHORITY"),
client_credential=os.environ.get("CLIENT_SECRET"))
#acquire token on behalf of the user that called this API
arm_resource_access_token = msal_client.acquire_token_on_behalf_of(
user_assertion=current_access_token.split(' ')[1],
scopes=_scopes
)
headers = {'Authorization': arm_resource_access_token['token_type'] + ' ' + arm_resource_access_token['access_token']}
subscriptions_list = req.get(_azure_management_subscriptions_uri), headers=headers).json()
return jsonify(subscriptions_list)
(上級) バックグラウンドのアプリ、API、サービスからサインイン ユーザーのトークン キャッシュにアクセスする
不在のユーザーに代わって操作を続けられるよう、アクセス トークン キャッシュの使用をバックグラウンドのアプリ、API、サービスに許可するため、MSAL のトークン キャッシュ実装を利用できます。 これは特に、ユーザーがフロントエンド Web アプリを終了した後、バックグラウンドのアプリやサービスがユーザーの代わりに作業を続けなければならない場合に便利です。
現在、ほとんどのバックグラウンド プロセスにおいて、ユーザーの不在時にユーザーのデータを使用して認証または再認証しなければならないとき、アプリケーションのアクセス許可が使用されます。 アプリケーションのアクセス許可は多くの場合、特権の昇格を必要とする管理者の同意を必要とするため、不要な衝突が発生します。その理由は、開発者のアプリに対してユーザーが最初に同意した以上のアクセス権を取得することを開発者が意図しなかったことにあります。
GitHub にあるこのコード サンプルからは、バックグラウンド アプリから MSAL のトークン キャッシュにアクセスすることでこの不要な衝突を回避する方法を確認できます。
バックグラウンドのアプリ、API、サービスからログイン ユーザーのトークン キャッシュにアクセスする