ASP.NET Core Web API 6中如何基于已有配置构建GraphServiceClient的AuthProvider
问题
我使用VS 2022生成了带有Microsoft Identity认证的ASP.NET Core Web API 6项目,已填写AzureAD登录所需标识,AzureAD:ClientSecret也存储在secrets.json中。
项目配置代码如下:
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.Identity.Web; using Microsoft.Identity.Web.Resource; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi() .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph")) .AddInMemoryTokenCaches(); builder.Services.AddAuthorization(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthentication(); app.UseAuthorization(); var scopeRequiredByApi = app.Configuration["AzureAd:Scopes"] ?? "";
appsettings.json配置如下:
{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "Domain": "xxxxxxxxx", "TenantId": "xxxxxxxxxxxxxxxxxxxxxxxxxxx", "ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxx", "CallbackPath": "/signin-oidc", "Scopes": "access_as_user", "ClientSecret": "Client secret from app-registration. Check user secrets/azure portal.", "ClientCertificates": [] }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "MicrosoftGraph": { "BaseUrl": "https://graph.microsoft.com/v1.0", "Scopes": "user.read" } }
注:标识信息已替换为xxxxxx。
我需要调用Microsoft Graph的“获取用户”等接口,微软文档示例需用authProvider实例化GraphServiceClient:
GraphServiceClient graphClient = new GraphServiceClient( authProvider ); var user = await graphClient.Users["{user-id}"] .Request() .GetAsync();
请问如何利用项目已配置的标识创建该authProvider变量?
解决方案
不需要手动创建authProvider,你已经通过.AddMicrosoftGraph()把GraphServiceClient注册到了依赖注入容器中,直接通过构造函数注入即可使用:
方式一:直接注入GraphServiceClient(推荐)
在你的API控制器或者端点中,直接注入GraphServiceClient:
[ApiController] [Route("[controller]")] public class UsersController : ControllerBase { private readonly GraphServiceClient _graphServiceClient; public UsersController(GraphServiceClient graphServiceClient) { _graphServiceClient = graphServiceClient; } [HttpGet("{userId}")] [Authorize] public async Task<IActionResult> GetUser(string userId) { var user = await _graphServiceClient.Users[userId] .Request() .GetAsync(); return Ok(user); } }
方式二:手动获取TokenAcquisition创建AuthProvider
如果你确实需要手动创建authProvider,可以利用已注册的ITokenAcquisition服务,它会自动使用你配置的AzureAD信息获取令牌:
- 注入
ITokenAcquisition和IConfiguration:
private readonly ITokenAcquisition _tokenAcquisition; private readonly IConfiguration _configuration; public YourController(ITokenAcquisition tokenAcquisition, IConfiguration configuration) { _tokenAcquisition = tokenAcquisition; _configuration = configuration; }
- 创建
DelegateAuthenticationProvider作为authProvider:
var graphScopes = _configuration.GetSection("MicrosoftGraph:Scopes").Value.Split(' '); var authProvider = new DelegateAuthenticationProvider(async (requestMessage) => { // 获取访问Microsoft Graph的令牌 var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(graphScopes); requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); }); // 实例化GraphServiceClient var graphClient = new GraphServiceClient(authProvider);
关键说明
- 你的项目已经通过
.EnableTokenAcquisitionToCallDownstreamApi().AddMicrosoftGraph()完成了Graph客户端的注册,依赖注入会自动处理令牌的获取和缓存,无需手动管理authProvider。 - 确保API端点添加
[Authorize]特性,这样才能在上下文中获取到用户的身份信息,进而获取对应的Graph访问令牌。
内容的提问来源于stack exchange,提问作者bmi
相关产品推荐
相关产品推荐

