首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何修复调用GetAccessTokenForAppAsync以获取令牌,从而生成NullReferenceException?

如何修复调用GetAccessTokenForAppAsync以获取令牌,从而生成NullReferenceException?
EN

Stack Overflow用户
提问于 2021-08-26 20:13:28
回答 1查看 2.3K关注 0票数 0

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

目前,由于无法使用ITokenAcquisition GetAccessTokenForAppAsync方法检索令牌,所以我陷入了困境。它一直产生一个NullReferenceException。我不知道我的启动设置是否错了什么的,但我搞不懂。

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

我知道获得没有用户的访问权限指南,我理解并能够开始工作,但我特别希望使用GetAccessTokenForAppAsync方法,因为它将为我管理刷新令牌。否则,我将不得不继续使用每个API调用来查询一个新的令牌,并且不断地生成有效的令牌似乎是个坏主意。

Startup.cs ConfigureServices方法:

代码语言:javascript
复制
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。我就是在这里打电话要钱的:

代码语言:javascript
复制
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");
    }
}

appSettings.json。这些值由用户机密json填充。

代码语言:javascript
复制
{
  "AzureAd": {
    "Instance": "",
    "ClientId": "",
    "TenantId": "",
    "CallbackPath": "",
    "ClientSecret": "",
    "TimeoutInMinutes": ""
  },
  "ConnectionStrings": {
    "DefaultConnection": ""
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-27 03:35:00

首先,我成功地转载了你的问题,如下所示:

你得到这个是因为private readonly ITokenAcquisition _tokenAcquisition;

注意:,这实际上是一项服务,它帮助您代表应用程序提供访问令牌。不能将此服务用作构造函数变量。

解决方案:

相反,您应该按照以下方式使用ITokenAcquisition服务:

代码语言:javascript
复制
   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下的配置

代码语言:javascript
复制
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:

代码语言:javascript
复制
"DownstreamApi": {
    "BaseUrl": "https://graph.microsoft.com/v1.0",
    "Scopes": "https://graph.microsoft.com/.default"
  }

输出:

希望它能解决你的问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68944805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档