调用 Web API 的 Web API:调用 API

有了令牌后,就可以调用受保护的 Web API 了。 通常从 Web API 的控制器或页面调用下游 API。

控制器代码

使用 Microsoft.Identity.Web 时,有 3 种使用方案:

选项 1:使用 SDK 调用 Microsoft Graph

在此方案中,你添加了 Microsoft.Identity.Web.GraphServiceClient NuGet 包,还按照代码配置中的指定在 Startup.cs 中添加了 .AddMicrosoftGraph(),并且你可在控制器或页构造函数中直接注入 GraphServiceClient,以便在操作中使用。 以下示例 Razor 页面显示已登录用户的照片。

 [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.GetAsync();
         try
         {
             using (var photoStream = await _graphServiceClient.Me.Photo.Content.GetAsync())
             {
                 byte[] photoByte = ((MemoryStream)photoStream).ToArray();
                 ViewData["photo"] = Convert.ToBase64String(photoByte);
             }
             ViewData["name"] = user.DisplayName;
         }
         catch (Exception)
         {
             ViewData["photo"] = null;
         }
     }
 }

选项 2:在使用帮助程序类的情况下调用下游 Web API

在此方案中,你已如代码配置中指定的那样将 .AddDownstreamApi() 添加到 Startup.cs 中,现可直接将 IDownstreamWebApi 服务注入控制器或页构造函数中并在操作中使用它:

 [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.CallApiForUserAsync(
             ServiceName,
             options =>
             {
                 options.RelativePath = $"me";
             });
         return View(value);
     }

CallApiForUserAsync 方法还具有强类型的泛型重写,使你能够直接接收对象。 例如,下面的方法收到一个 Todo 实例,该实例是 Web API 返回的 JSON 的强类型表示形式。

 // GET: TodoList/Details/5
 public async Task<ActionResult> Details(int id)
 {
     var value = await _downstreamWebApi.CallApiForUserAsync<object, Todo>(
         ServiceName,
         null,
         options =>
         {
             options.HttpMethod = HttpMethod.Get;
             options.RelativePath = $"api/todolist/{id}";
         });
     return View(value);
 }

选项 3:在不使用帮助程序类的情况下调用下游 Web API

如果已决定使用IAuthorizationHeaderProvider接口获取授权标头,以下代码会继续执行调用 Web API 的Web API 中显示的示例代码:获取应用的令牌。 该代码在 API 控制器的操作中调用。 它调用下游 API(名为 todolist)。

获取令牌后,将其用作持有者令牌以调用下游 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.
  authorizationHeader = await authorizationHeaderProvider.GetAuthorizationHeaderForUserAsync(scopes);
  _httpClient.DefaultRequestHeaders["Authorization"] = authorizationHeader;

  // Call the todolist service.
  HttpResponseMessage response = await _httpClient.GetAsync(TodoListBaseAddress + "/api/todolist");
  // ...
}

后续步骤

  • 在以下多部分教程系列中详细了解如何生成一个让用户登录的 ASP.NET Core Web 应用

  • 探索 Microsoft 标识平台 Web API 示例