ASP.NET Core 2.0 Web API Azure Ad v2 令牌授权不起作用

2023-12-26

我正在尝试使用 ASP.NET Core 2.0 创建一个 Web API 服务器,该服务器使用 azure ad v2 端点令牌授权。我还有一个 Angular 2 应用程序,其中发生了 Office365 登录。我从那里获取令牌,然后向 Web API 服务器中的授权操作发送一个简单的请求。但是,我的令牌未通过授权检查,并且我收到 401 Unauthorized 响应。提供的描述是:

Bearer error="invalid_token", error_description="未找到签名密钥"

我解码了令牌,解码器也抛出无效签名错误。以下是我用于配置和令牌授权的代码的重要部分:

网络 API 服务器:

应用程序设置.json

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "ClientId": "my-registered-app-client-id",
  },
  "Logging": {
    "IncludeScopes": false,
    "Debug": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "Console": {
      "LogLevel": {
        "Default": "Warning"
      }
    }
  }
}

AzureAdAuthenticationBuilderExtensions.cs

public static class AzureAdServiceCollectionExtensions
{
    public static AuthenticationBuilder AddAzureAdBearer(this AuthenticationBuilder builder)
        => builder.AddAzureAdBearer(_ => { });

    public static AuthenticationBuilder AddAzureAdBearer(this AuthenticationBuilder builder, Action<AzureAdOptions> configureOptions)
    {
        builder.Services.Configure(configureOptions);
        builder.Services.AddSingleton<IConfigureOptions<JwtBearerOptions>, ConfigureAzureOptions>();
        builder.AddJwtBearer();
        return builder;
    }

    private class ConfigureAzureOptions: IConfigureNamedOptions<JwtBearerOptions>
    {
        private readonly AzureAdOptions _azureOptions;

        public ConfigureAzureOptions(IOptions<AzureAdOptions> azureOptions)
        {
            _azureOptions = azureOptions.Value;
        }

        public void Configure(string name, JwtBearerOptions options)
        {
            options.Audience = _azureOptions.ClientId;
            options.Authority = $"{_azureOptions.Instance}common/v2.0";

            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = false,
            };
        }

        public void Configure(JwtBearerOptions options)
        {
            Configure(Options.DefaultName, options);
        }
    }
}

启动.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddAzureAdBearer(options => Configuration.Bind("AzureAd", options));

        services.AddMvc();
        services.AddCors(options =>
        {
            options.AddPolicy("AllowAllOrigins",
             builder =>
             {
                 builder.AllowAnyMethod().AllowAnyHeader().AllowAnyOrigin();
             });
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors("AllowAllOrigins");

        app.UseAuthentication();
        app.UseMvc();
    }
}

现在这是我在 Angular2 应用程序中用于身份验证的代码:

import { Injectable } from '@angular/core';
import { Headers } from '@angular/http';
import * as hello from 'hellojs/dist/hello.all.js';

import * as MicrosoftGraph from "@microsoft/microsoft-graph-types";
import * as MicrosoftGraphClient from "@microsoft/microsoft-graph-client";
import { Configs } from "../../../shared/configs"

@Injectable()
export class HttpService {
  url = `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${Configs.appId}&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&scope=openid%20offline_access%20https%3A%2F%2Fgraph.microsoft.com%2Fmail.read&state=12345`;

  getAccessToken() {
    const msft = hello('msft').getAuthResponse();
    const accessToken = msft.access_token;
    return accessToken;
  }


  getClient(): MicrosoftGraphClient.Client
  {
    var client = MicrosoftGraphClient.Client.init({
      authProvider: (done) => {
          done(null, this.getAccessToken()); //first parameter takes an error if you can't get an access token
      },
      defaultVersion: 'v2.0'
    });
    return client;
  }
}

当从端点返回令牌时,我向 Web API 服务器上的有效端点发送请求。

重要提示:我在 Web API 和 Angular 应用程序中使用相同的 AppId,因为 AzureAd v2.0 端点需要它。

我的观点是,我认为我所做的一切都是按书本进行的,但显然缺少一些东西。如果有人能告诉我我的配置做错了什么,我将不胜感激!

解码令牌的 aud 属性为:

https://graph.microsoft.com https://graph.microsoft.com


经过评论中的不短讨论后,问题得到了解决。

讨论的要点:

  • 访问令牌包含一个aud索赔价值为https://graph.microsoft.com,这意味着该令牌适用于 Microsoft Graph API,而不是其 API
  • 需要在以下位置注册 Web API:https://apps.dev.microsoft.com/ https://apps.dev.microsoft.com/,之后应用程序需要使用scope如同:api://25f66106-edd6-4724-ae6f-3a204cfd9f63/access_as_user

因此请确保aud声明包含您的 API 的客户端 ID 或应用程序 ID URI。这意味着它适用于您的 API。

令牌还需要包含必要的范围。

当向 AAD 请求访问令牌时,请确保指定正确的范围。

此外,如果您使用的是 v1 终结点,请确保使用 ADAL,而不是 MSAL。在 v1 中,您也必须使用而不是范围resource,其值必须设置为 API 的客户端 ID 或应用程序 ID URI。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.NET Core 2.0 Web API Azure Ad v2 令牌授权不起作用 的相关文章

随机推荐