【问题标题】:Trouble with On-Behalf-Of flow with standalone Blazor WASM, AAD, .NET Core 6 Web API calling MS Graph使用独立 Blazor WASM、AAD、.NET Core 6 Web API 调用 MS Graph 的代理流出现问题
【发布时间】:2022-03-23 08:09:00
【问题描述】:

我有一个独立的 Blazor WASM 站点(客户端)、一个带有受保护端点的单独 .NET 6 Web API(服务器),我正在尝试从 API 调用 MS Graph。

我已经阅读了几乎所有我能找到的关于完成这项工作所需的配置的文章,但我对增量同意失败感到困惑。尝试访问使用 MS Graph 的服务器 API 时出现以下错误:

为下游 Web API 获取令牌时出错 - MsalUiRequiredException 消息为:AADSTS65001:用户或管理员未同意使用 ID 为“[redacted]”且名为“[redacted]”的应用程序。为此用户和资源发送交互式授权请求。

配置...

  1. 为 Web API(服务器)创建 AAD 应用,为 Graph 配置添加机密,设置应用 URI 并在 AAD 的“公开 API”下创建 access_as_user 范围。

  2. 将客户端 ID(来自以下步骤)添加到清单中的 knownClientApplications 部分,以便在 AAD 中注册服务器应用程序。

  3. 对于 API 权限,我添加了图形范围 User.ReadUser.Read.AllGroup.Read.All,并在 AAD UI 中提供了管理员同意。

  4. 在 API 中配置 appsettings.json 以添加来自步骤 2 的 Graph API BaseUrl 及以上范围以及正确的 AzureAD 域 TenantIdClientIdClientSecret 值,以便 MSAL 发挥作用。

  5. 在服务器上配置 MSAL:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApi(builder.Configuration)
    .EnableTokenAcquisitionToCallDownstreamApi()
        .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
    .AddInMemoryTokenCaches();
  1. 为 Blazor WASM 创建了 AAD 应用,使用 SPA 身份验证并重定向到 https://localhost:7014/authentication/login-callback,并将 API 权限设置为仅 api://[redacted]/access_as_user

  2. 根据this article创建自定义授权消息处理程序。

public CustomAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigation) : base(provider, navigation)
{
  ConfigureHandler(
      authorizedUrls: new[]
      {
          "https://localhost:7069"
      },
      scopes: new[]
      {
          "api://[redacted]/.default"
      });
}
  1. 在客户端上配置了 MSAL:
builder.Services.AddMsalAuthentication(options =>
{
  builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
  options.ProviderOptions.DefaultAccessTokenScopes.Add("api://[redacted]/.default");
  options.ProviderOptions.LoginMode = "redirect";
}
  1. 使用自定义消息处理程序在 Blazor 客户端上设置命名 HTTP 客户端:
var baseAddress = builder.Configuration["PublicApiUrl"];

builder.Services.AddHttpClient("PublicApi", client =>
{
    client.BaseAddress = new Uri(baseAddress);
}).AddHttpMessageHandler<CustomAuthorizationMessageHandler>();

builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("PublicApi"));
builder.Services.AddScoped<CustomAuthorizationMessageHandler>();

什么有效...

  1. 我可以作为 AAD 用户向 Blazor 客户端进行身份验证。
  2. 我可以访问托管在不依赖 MS Graph 的服务器上的受保护端点(使用基于策略的授权)。

问题...

  1. this article's guidance 关于增量同意之后,特别是“静态权限”部分,我认为在服务器的应用注册上授予 Graph 的管理员同意就足够了?

  2. 所有显示 Blazor WASM 和受保护 API 调用受保护 API(图形)的文档都假设 Blazor 客户端也由 API 服务器托管。在我的情况下甚至可以使用代表流量吗?如果它是托管的,我可以看到 API 调用 Blazor 导航子系统来执行增量同意重定向,但是当它们分开时,我只能想象静态权限是要走的路。

  3. 需要在客户端设置DefaultAccessTokenScopes吗?

【问题讨论】:

    标签: c# blazor


    【解决方案1】:

    这里的问题是在构建 API 应用程序时使用AddMicrosoftGraph 方法。

    AddMicrosoftGraph 创建的GraphServiceClient 将默认访问分配给用户委派权限,而不是应用程序权限分配给应用程序。这就是抛出 MsalUiRequiredException 的原因,这通常通过提示用户登录来解决。

    您可以阅读更多关于委派应用程序权限here

    您可以改为使用 AddMicrosoftGraphAppOnly 方法创建一个 GraphServiceClient,该方法将使用特定于您的 API 的凭据从 Microsoft Graph API 检索所需的相关数据。

    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApi(builder.Configuration)
        .EnableTokenAcquisitionToCallDownstreamApi()
        .AddMicrosoftGraphAppOnly(
            authenticationProvider => new GraphServiceClient(authenticationProvider))
        .AddInMemoryTokenCaches();
    

    只要您拥有appsettings.json 文件的AzureAd 部分中提供的相关设置和机密,注入到您的应用程序中的GraphServiceClient 现在应该能够访问您需要的数据。

    您可以在appsettings.json 文件here 中阅读有关使用AzureAd 设置的应用配置的更多信息。

    【讨论】:

      猜你喜欢
      • 2022-12-16
      • 1970-01-01
      • 2021-04-07
      • 1970-01-01
      • 2023-01-16
      • 1970-01-01
      • 2021-07-15
      • 2022-11-28
      • 2020-06-20
      相关资源
      最近更新 更多