如何修复调用 GetAccessTokenForAppAsync 以获取导致 NullReferenceException 的令牌?

问题描述 投票:0回答:1

我正在研究如何在 ASP.NET Core 3.1 Razor Pages 应用程序中使用 Microsoft Graph API。我找到了 this 指南并使它的大部分工作(以及检索令牌),直到我意识到我需要在没有用户的情况下访问 API。

此刻,我被卡住了,因为我无法使用

ITokenAcquisition
GetAccessTokenForAppAsync
方法检索令牌。它一直导致
NullReferenceException
。我不知道是我的启动设置错误还是什么,但我想不通。

System.NullReferenceException: 'Object reference not set to an instance of an object.'

我知道 Get access without a user guide 我理解并且可以开始工作,但我特别想使用

GetAccessTokenForAppAsync
方法,因为它将为我管理刷新令牌。否则,我将不得不在每次 API 调用时不断查询新令牌并不断生成有效令牌似乎是个坏主意。

Startup.cs ConfigureServices方法:

public void ConfigureServices(IServiceCollection services)
{
    ...
    
    services.AddHttpClient();
    services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
        .EnableTokenAcquisitionToCallDownstreamApi()
        // Use in-memory token cache
        // See https://github.com/AzureAD/microsoft-identity-web/wiki/token-cache-serialization
        .AddInMemoryTokenCaches();
        
    ...

}

Index.cshtml.cs。这是我打电话获取令牌的地方:

public class IndexModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;
    private readonly ITokenAcquisition _tokenAcquisition;

    public IndexModel(IHttpClientFactory clientFactory, ITokenAcquisition tokenAcquisition)
    {
        _clientFactory = clientFactory;
        _tokenAcquisition = tokenAcquisition;
    }

    public async Task OnGet()
    {
        // results in NullReferenceException
        string token = await _tokenAcquisition.GetAccessTokenForAppAsync("https://graph.microsoft.com/.default", tenant:"tenantId");
    }
}

应用程序设置.json。这些值由用户机密 json 填充。

{
  "AzureAd": {
    "Instance": "",
    "ClientId": "",
    "TenantId": "",
    "CallbackPath": "",
    "ClientSecret": "",
    "TimeoutInMinutes": ""
  },
  "ConnectionStrings": {
    "DefaultConnection": ""
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

c# asp.net-core microsoft-graph-api bearer-token
1个回答
1
投票

首先我已经成功重现了你的问题,如下所示:

你得到这个是因为

private readonly ITokenAcquisition _tokenAcquisition;

注意: 这实际上是一个帮助您代表应用程序获取访问令牌的服务。您不能将此服务作为构造函数变量使用。

解决方案:

取而代之的是,您应该使用

ITokenAcquisition
服务,如下所示:

   public async Task OnGet()
        {
            var _tokenAcquisition = this.HttpContext.RequestServices
                 .GetRequiredService<ITokenAcquisition>() as ITokenAcquisition;
            string token = await _tokenAcquisition.GetAccessTokenForAppAsync("https://graph.microsoft.com/.default", tenant: "tenantId");
        }

Startup.cs下的配置

public void ConfigureServices(IServiceCollection services)
{
    string[] initialScopes = Configuration.GetValue<string>("DownstreamApi:Scopes")?.Split(' ');

    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
        .EnableTokenAcquisitionToCallDownstreamApi(initialScopes)
        .AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
        .AddInMemoryTokenCaches();

    services.AddControllersWithViews(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    });
    services.AddRazorPages()
            .AddMicrosoftIdentityUI();
}

DownstreamApi appsettings.json下:

"DownstreamApi": {
    "BaseUrl": "https://graph.microsoft.com/v1.0",
    "Scopes": "https://graph.microsoft.com/.default"
  }

输出:

注意: 确保您已在 program.cs 或 startup.cs 文件中包含

app.UseAuthentication();

希望它能相应地解决您的问题。

© www.soinside.com 2019 - 2024. All rights reserved.