【问题标题】:Blazor WASM (standalone) B2C auth with Azure Function App authenticationBlazor WASM(独立)B2C 身份验证与 Azure Function App 身份验证
【发布时间】:2022-01-01 13:41:32
【问题描述】:

我正在开发一个 Blazor WASM 独立(不是 ASP.NET 核心托管)应用程序,该应用程序已与我的 B2C 租户集成以进行用户身份验证。 我能够成功地针对 B2C 进行身份验证。

在另一个 Azure 目录中,我有一个启用了身份验证的 Azure Function App。我正在使用 Microsoft 身份验证和身份验证设置来使用相同的 B2C 租户。作为测试,我可以通过在 API 请求的标头中传递 JWT 不记名令牌来确认我能够使用 auth 成功调用各种函数。 在 httpClient 中添加以下内容即可实现这一点

httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "eyJ0eXAiOiJKV1QiLCJhbGciOiJS_WTAiGTyfEHuXjlFh5FOo8hBk1V7GFjzUn4TUOHIOjg3uDAaL730J8PewVvE8xyaG1MllR1JRjDz1D95bMch7QMqXZ-sRuUzvWdvBK_IkQ…");

不过,这显然只是作为一个测试而已。

我想要实现的是在进行后续 API 调用时使用初始 B2C 登录请求期间获得的 Bearer 令牌......但是我似乎无法弄清楚如何在 Blazor WASM 中执行此操作。我相信在 Blazor Server 这可以通过

var accessToken = await HttpContext.GetTokenAsync("access_token");
var refreshToken = await HttpContext.GetTokenAsync("refresh_token");

查看How to secure an Azure Function accessed by a Blazor Wasm app with Azure AD B2C? 上的文章链接我已按照列出的详细信息(注意新的“应用程序注册”和“应用程序(旧版)”之间存在差异)但运气不佳。在调用 FetchData 页面时,它似乎根本没有传递令牌。

这是我的 Program.cs 页面的副本:

using B2CBlazorWASMNotHosted;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using System.Net.Http;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// register CustomAuthorizationMessageHandler 
builder.Services.AddScoped<CustomAuthorizationMessageHandler>();

// configure httpclient
// call the following code please add packageMicrosoft.Extensions.Http 3.1.0
builder.Services.AddHttpClient("ServerAPI", client =>
  client.BaseAddress = new Uri("https://myfunctionapp.azurewebsites.net"))
        .AddHttpMessageHandler<CustomAuthorizationMessageHandler>();

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

builder.Services.AddMsalAuthentication(options =>
{
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
      options.ProviderOptions.LoginMode = "redirect";
    options.ProviderOptions.DefaultAccessTokenScopes.Add("https://myb2ctenant.onmicrosoft.com/8f7ece0f-a4ef-4f96-9a24-fc4e2ced9504/AccessAPI");

});


await builder.Build().RunAsync();
public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler
{
    public CustomAuthorizationMessageHandler(IAccessTokenProvider provider,
        NavigationManager navigationManager)
        : base(provider, navigationManager)
    {
        ConfigureHandler(
            authorizedUrls: new[] { "myfunctionapp.azurewebsites.net" },
            scopes: new[] { "myb2ctenant.onmicrosoft.com/8f7ece0f-a4ef-4f96-9a24-fc4e2ced9504/AccessAPI" });
    }
}

在 Azure 门户中,我目前有 2 个不同的应用程序注册。 1 个用于 Blazor WASM 应用程序身份验证,另一个用于函数应用程序。应用注册设置截图如下:

调用API的代码在这里:

var httpClient = new HttpClient();
var source = new CancellationTokenSource();
var centreguid = new Centre { centreguid = "CA8E99BC-F5B0-4A54-A8BF-C9AE9E95EE44" };
   
var response = await httpClient.PostAsJsonAsync("https://myfunctionapp.azurewebsites.net/api/GetArenasForCentre?", centreguid, source.Token);
string stringresponse = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<parentArenas>(stringresponse);

arenas = result.ArenaDetails;

Console.WriteLine("json output:");

如果我在 var result 上设置断点,我可以看到返回以下消息:

401 "您无权查看此目录或页面。"

有人能在这里指出我做错了什么吗?也许有更好的方法来实现这一点。


一些附加信息:

与为函数应用程序使用单独的应用程序注册相反,我还尝试使用相同的 SPA 应用程序注册,并已将函数应用程序身份验证配置为使用此应用程序注册......不幸的是,无济于事。 我还在此应用注册上设置了相同的 APIAccess 范围(老实说,我什至不确定是否需要应用范围)

【问题讨论】:

    标签: azure-functions blazor azure-ad-b2c blazor-webassembly


    【解决方案1】:

    我在 API 的 App 注册中的门户中公开了一个 API:

    在客户端我添加一个 API 权限

    在 WASM 客户端上,您需要将作用域的请求添加到配置中。

    【讨论】:

    • Brian 因为我使用 B2C 来保护我的应用程序和 api,所以我只能公开 https:// api 而不是 api://。不确定这是否重要?无论哪种方式,我都尝试过 https:// 但是似乎没有工作。
    猜你喜欢
    • 2021-11-05
    • 2022-11-28
    • 1970-01-01
    • 2021-07-24
    • 2021-04-30
    • 1970-01-01
    • 2019-06-25
    • 2016-04-26
    • 1970-01-01
    相关资源
    最近更新 更多