【问题标题】:Azure AD Authentication with .NET Core Web API使用 .NET Core Web API 进行 Azure AD 身份验证
【发布时间】:2022-02-04 07:48:27
【问题描述】:

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

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

这是我们的设置:

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

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

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

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

  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 的请求中的 Authorization 标头中(始终返回 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 应用程序。

更新:

我可以在收到的 401 响应标头中看到:

Bearer error="invalid_token", error_description="签名无效"

【问题讨论】:

  • 您的 API 端点是否受到 Authorize 属性的保护?如果是这样,您如何验证用户身份?
  • 我已经在我的控制器上放置了 [Authorize] 属性,是的。用户在客户端使用 Azure AD 进行身份验证,然后将他们的令牌发送到我的后端 api,它只返回 401 错误
  • 您是否尝试解码您的令牌并比较范围和受众参数?范围(或 scp)是否具有值 access_as_user?受众(或 aud)是否包含后端客户端 ID?可能是该令牌(提供给后端)实际上是用于 Microsoft Graph。
  • @Serhii 我在前端获取并发送到后端的令牌似乎在令牌有效负载中都没有。 "scp": "openid profile User.Read email" ... "aud": "00000003-0000-0000-c000-000000000000"
  • 您正在使用 Microsoft Graph 的令牌(在此处查看 appId:shawntabrizi.com/aad/…)。前端已收到 MS Graph 的令牌并将其发送到后端

标签: azure asp.net-core azure-active-directory msal


【解决方案1】:
  1. 尝试将“Audience”参数添加到 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
    },
...
  ],

【讨论】:

  • 嗨@Serhii我已经在我的项目中复制了这个,当 aud 声明是时,我得到错误是无效的观众 这是我从 azure 门户复制和粘贴的那个,scp 声明也一样
  • 嗨@kintela,您在后端使用什么配置?
  • 嗨@Serhii 显示在我的帖子中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 2017-04-08
  • 1970-01-01
  • 2020-07-27
  • 1970-01-01
  • 2021-03-14
相关资源
最近更新 更多