使用 .NET Core Web 进行 Azure AD 身份验证 API

Azure AD Authentication with .NET Core Web API

我们有一个简单的设置。前端 Web 应用程序从 Azure AD 获取令牌。前端使用该令牌来验证对我们后端 .NET Core Web API 的请求。两者都将部署为 Azure Web 应用程序。

我们找到了很多关于这个主题的资源 (Microsoft Docs, Blogs, Youtube) 但是,无论我们尝试什么,当我们从前端向后端发送请求时,我们都会收到 401 未经授权的错误。

这是我们的设置:

  1. 我们有 2 个应用程序注册(一个用于前端,一个用于后端)

  2. 在 Azure 门户中,我导航到 Azure AD -> 应用程序注册 -> 后端应用程序 -> 公开 API -> 添加范围 -> 填写的表格:

  3. 然后导航到前端应用程序注册 -> API 权限 -> 添加权限 -> 添加对步骤 2 中公开的 API 的访问权限。

  4. 然后 select“授予管理员同意”

  5. 进入前端代码:

  6. 在前端,我们使用的是 Microsoft 的 MSAL 库。我们将其配置为:

// Frontend msal config
   {
        msalConfig: {
        auth: {
            clientId: "{frontend clientId}",
            authority: "https://login.microsoftonline.com/{tenantId}/",
            redirectUri: appUri,
            postLogoutRedirectUri: appUri,
            mainWindowRedirectUri: appUri
        },
        cache: {
            cacheLocation: 'localStorage'
        }
    }
  1. 我们发送登录请求:
// login.js
        const request = {
            scopes: [
                "User.Read", 
                "api://{Backend Application Id From AzureAD App Registration}/access_as_user"
            ]
        };
        instance.loginPopup(request).catch(
            (error) => {
                console.log(error);
            }
        );

  1. 这按预期工作,用户可以登录和退出我们的前端应用程序。
  2. 我们将我们的 Azure AD 提供的令牌放在我们对后端 API 的请求中的授权 header(总是 returns 401)。
  3. 后端代码使用 Microsoft.Identity.Web (.NET 5):
// .Net appsettings.json  
 "AzureAd": {
   "Instance": "https://login.microsoftonline.com/",
   "ClientId": "{backend clientId}",
   "TenantId": "{tenantId}"
 }
// Startup.cs

using Microsoft.Identity.Web;

ConfigureServices(IServiceCollection services)
{
 //other services
 services.AddMicrosoftIdentityWebApiAuthentication(Configuration, "AzureAd");
 //other services
}

Configure(IApplicationBuilder app, IWebHostEnvironment env)
{ 
 // other config
 app.UseRouting();
 app.UseAuthentication();
 app.UseAuthorization();
 // other config
}

如能提供有关如何进行的任何帮助,我们将不胜感激。我们现在正在本地进行测试,但是一旦我们获得授权,我们就会将前端和后端应用程序部署到 Azure Web Apps。

更新:

我可以在 401 响应 header 中看到我得到:

承载错误="invalid_token", error_description="签名无效"

  1. 尝试将“受众”参数添加到 AzureAD 部分:"Audience": "api://{Client_Id}"

  2. 要获得有关身份验证的更多信息,您可以将 subscribeToJwtBearerMiddlewareDiagnosticsEvents: true 传递到 services.AddMicrosoftIdentityWebApiAuthentication 并在请求失败后检查您的日志。

  3. 此外,如果需要范围和受众,您可以解码(https://jwt.io)您的令牌并检查有效负载部分。

  4. 可能是令牌(提供给后端)实际上是用于 Microsoft Graph(在此处检查 appId:shawntabrizi.com/aad/...)。如果“scp”是“openid profile User.Read email”,而“aud”是“00000003-0000-0000-c000-000000000000”,那么你的后端使用了错误的令牌。要求前端检查他们如何接收令牌的方式。

前端小哥写代码是这样的,有错请指正:

 
 public static msalInterceptorConfigFactory(): MsalInterceptorConfiguration {
    const resourceMap = new Map<string, Array<string>>();
    resourceMap.set(environment.apiUrl, [environment.scope]);

    return {
      interactionType: InteractionType.Redirect,
      resourceMap
    };
  }

  public static msalGuardConfigFactory(): MsalGuardConfiguration {
    return {
      interactionType: InteractionType.Redirect,
      authRequest: {
        scopes: [environment.scope]
      }
    };
  }

# module.ts
 providers: [
...
    {
      provide: MSAL_GUARD_CONFIG,
      useFactory: msalGuardConfigFactory
    },
    {
      provide: MSAL_INTERCEPTOR_CONFIG,
      useFactory: msalInterceptorConfigFactory
    },
...
  ],