【问题标题】:WebAssembly Razor client app return 401 while calling a protected API in Azure with Admin RoleWebAssembly Razor 客户端应用程序在使用管理员角色调用 Azure 中受保护的 API 时返回 401
【发布时间】:2021-07-16 17:47:54
【问题描述】:

我有受 Azure AD 保护的 API,其中需要身份验证才能获取访问数据,我现在只用一个简单的范围公开 API。

API 和客户端应用程序都在 Azure AD 中注册。 还为 API 配置了角色,只有具有 Admin 角色的用户才能调用我的 API。

我是否也需要将此管理员角色分配给客户端应用程序?还是AccessApi 范围就够了?

Scopes  Who can consent     Admin consent display name     User consent display name   State 

api://xx  User              AccessApi                      AccessApi                 Enable

使用webassembly blazor 构建的客户端应用程序也在Azure AD 中注册,并配置了Api permission 以使用delegated 访问AccessApi

API / Permissions name  Type       Description   Admin consent required    Status
myApi (1)   

AccessApi              Delegated     AccessApi              No

我将 webassembly blazor 客户端应用程序配置为针对 azure 进行身份验证并获取令牌并使用该令牌调用 myApi,但是我不断收到 loading,但没有显示任何数据而没有任何错误。

我不确定这里出了什么问题?

program 客户端应用类:

 private static string scope = @"api://xxx/AccessApi";

...

            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("app");


            builder.Services.AddScoped<GraphAPIAuthorizationMessageHandler>();

            builder.Services.AddHttpClient("ServerAPI",
                client => client.BaseAddress = new Uri("https://localhost:44314"))
                .AddHttpMessageHandler<GraphAPIAuthorizationMessageHandler>();

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

            builder.Services.AddMsalAuthentication(options =>
            {
                builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
                options.ProviderOptions.DefaultAccessTokenScopes.Add(scope);
            });

fetch data razor page 我导入了所有必要的库

@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@inject IAccessTokenProvider TokenProvider
@attribute [Authorize]

@inject NavigationManager UriHelper
@inject HttpClient Http

...

data = await Http.GetFromJsonAsync<data[]>(@"API-url--runs-locally-on-docker");

授权消息处理类

 private static string scope = @"api://xxx/AccessApi";
    public GraphAPIAuthorizationMessageHandler(IAccessTokenProvider provider,
        NavigationManager navigationManager)
        : base(provider, navigationManager)
    {
        ConfigureHandler(
            authorizedUrls: new[] { "https://localhost:44314" },
            scopes: new[] { scope });
    }

使用 Azure AD 帐户对自己进行身份验证后,客户端应用显示loading..,但未显示任何数据。 在控制台级别显示此错误。

Failed to load resource: the server responded with a status of 401 (Unauthorized)

我遵循了 Microsoft 文档,但我不确定我在这里遗漏了什么。 这里有什么问题?

更新

Api 公开选项卡:

客户端应用的 API 权限:

【问题讨论】:

  • 您可能会帮助我们帮助您确定在崩溃发生之前您通过 Main() 的程度。我不了解这个代码环境,但是如果可以的话,你应该逐步完成它,否则从 Main() 的末尾向后删除代码,直到它不崩溃,然后你就知道你最近的代码删除是它崩溃的地方。
  • 我为整个画面和我试图实现的工作流程添加了更多描述。
  • 使用jwt.ms解析访问令牌并提供截图。
  • 我看不到令牌被发送到 Api 的位置。 data = await Http.GetFromJsonAsync&lt;data[]&gt;(@"API-url--runs-locally-on-docker"); 会以某种方式自动完成
  • 能否提供一个API应用的Expose an API的截图?顺便说一句,您还需要将客户端应用程序添加到 api。 i.stack.imgur.com/tG0co.png

标签: .net-core azure-active-directory bearer-token blazor-webassembly


【解决方案1】:

显然,您的scope 设置不正确。您应该将范围设置为 api 应用程序 的客户端 ID,而不是客户端应用程序的客户端 ID。在您的问题中,我认为您的范围应该是:api://7b4d6df9-63cd-4ed7-881bxxx/AccessApi

解析令牌,您应该会看到scp 声明和roles 声明。

【讨论】:

  • 我在这里迷路了,你能解释一下吗?我在 Api 中定义了范围,并且该范围由客户端应用程序使用。这里有什么问题?
  • @ikenahim scope 仅由您授予客户端应用程序,它会显示在令牌中。
  • @ikenahim 按照我的方法试试看效果如何。
  • 我在 Api 中创建了作用域AccessApi 并暴露了这个作用域,客户端应用程序使用这个作用域。我还是不明白你:/。
  • 您的意思是在客户端应用程序中创建了范围?不在 API 上?
猜你喜欢
  • 2021-07-19
  • 2015-07-29
  • 1970-01-01
  • 2023-03-23
  • 2018-10-29
  • 2023-03-10
  • 2019-09-15
  • 1970-01-01
  • 2021-10-26
相关资源
最近更新 更多