调用 Web API 的 Web API:调用 APIA web API that calls web APIs: Call an API
有了令牌后,就可以调用受保护的 Web API 了。After you have a token, you can call a protected web API. 通常从 Web API 的控制器或页面调用下游 API。You usually call the downstream APIs from the controller or pages of your web API.
控制器代码Controller code
使用 Microsoft.Identity.Web 时,有 3 种使用方案:When you use Microsoft.Identity.Web, you have three usage scenarios:
- 选项 1:通过 Microsoft Graph SDK 调用 Microsoft GraphOption 1: Call Microsoft Graph with the Microsoft Graph SDK
- 选项 2:在使用帮助程序类的情况下调用下游 Web APIOption 2: Call a downstream web API with the helper class
- 选项 3:在不使用帮助程序类的情况下调用下游 Web APIOption 3: Call a downstream web API without the helper class
选项 1:使用 SDK 调用 Microsoft GraphOption 1: Call Microsoft Graph with the SDK
在此方案中,你已如代码配置中指定的那样将 .AddMicrosoftGraph()
添加到 Startup.cs 中,现可直接将 GraphServiceClient
注入控制器或页构造函数中,以便在操作中使用。In this scenario, you've added .AddMicrosoftGraph()
in Startup.cs as specified in Code configuration, and you can directly inject the GraphServiceClient
in your controller or page constructor for use in the actions. 以下示例 Razor 页面显示已登录用户的照片。The following example Razor page displays the photo of the signed-in user.
[Authorize]
[AuthorizeForScopes(Scopes = new[] { "https://microsoftgraph.chinacloudapi.cn/user.read" })]
public class IndexModel : PageModel
{
private readonly GraphServiceClient _graphServiceClient;
public IndexModel(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
public async Task OnGet()
{
var user = await _graphServiceClient.Me.Request().GetAsync();
try
{
using (var photoStream = await _graphServiceClient.Me.Photo.Content.Request().GetAsync())
{
byte[] photoByte = ((MemoryStream)photoStream).ToArray();
ViewData["photo"] = Convert.ToBase64String(photoByte);
}
ViewData["name"] = user.DisplayName;
}
catch (Exception)
{
ViewData["photo"] = null;
}
}
}
选项 2:在使用帮助程序类的情况下调用下游 Web APIOption 2: Call a downstream web API with the helper class
在此方案中,你已如代码配置中指定的那样将 .AddDownstreamWebApi()
添加到 Startup.cs 中,现可直接将 IDownstreamWebApi
服务注入控制器或页构造函数中并在操作中使用它:In this scenario, you've added .AddDownstreamWebApi()
in Startup.cs as specified in Code configuration, and you can directly inject an IDownstreamWebApi
service in your controller or page constructor and use it in the actions:
[Authorize]
[AuthorizeForScopes(ScopeKeySection = "TodoList:Scopes")]
public class TodoListController : Controller
{
private IDownstreamWebApi _downstreamWebApi;
private const string ServiceName = "TodoList";
public TodoListController(IDownstreamWebApi downstreamWebApi)
{
_downstreamWebApi = downstreamWebApi;
}
public async Task<ActionResult> Details(int id)
{
var value = await _downstreamWebApi.CallWebApiForUserAsync(
ServiceName,
options =>
{
options.RelativePath = $"me";
});
return View(value);
}
CallWebApiForUserAsync
方法还具有强类型的泛型重写,使你能够直接接收对象。The CallWebApiForUserAsync
method also has strongly typed generic overrides that enable you to directly receive an object. 例如,下面的方法收到一个 Todo
实例,该实例是 Web API 返回的 JSON 的强类型表示形式。For example, the following method received a Todo
instance, which is a strongly typed representation of the JSON returned by the web API.
// GET: TodoList/Details/5
public async Task<ActionResult> Details(int id)
{
var value = await _downstreamWebApi.CallWebApiForUserAsync<object, Todo>(
ServiceName,
null,
options =>
{
options.HttpMethod = HttpMethod.Get;
options.RelativePath = $"api/todolist/{id}";
});
return View(value);
}
选项 3:在不使用帮助程序类的情况下调用下游 Web APIOption 3: Call a downstream web API without the helper class
如果已决定使用 ITokenAcquisition
服务手动获取令牌,现在需要使用令牌。If you've decided to acquire a token manually by using the ITokenAcquisition
service, you now need to use the token. 在这种情况下,以下代码继续演示调用 Web API 的 Web API:获取应用的令牌中显示的示例代码。In that case, the following code continues the example code shown in A web API that calls web APIs: Acquire a token for the app. 该代码在 API 控制器的操作中调用。The code is called in the actions of the API controllers. 它调用下游 API(名为 todolist)。It calls a downstream API named todolist.
获取令牌后,将其用作持有者令牌以调用下游 API。After you've acquired the token, use it as a bearer token to call the downstream API.
private async Task CallTodoListService(string accessToken)
{
// After the token has been returned by Microsoft.Identity.Web, add it to the HTTP authorization header before making the call to access the todolist service.
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
// Call the todolist service.
HttpResponseMessage response = await _httpClient.GetAsync(TodoListBaseAddress + "/api/todolist");
// ...
}
后续步骤Next steps
转到此方案中的下一篇文章:转向生产。Move on to the next article in this scenario, Move to production.