繁体   English   中英

从 Blazor WASM 中的 AccountClaimsPrincipalFactory 调用 API

[英]Call API from AccountClaimsPrincipalFactory in Blazor WASM

我正在使用 Blazor WASM 和 AzureB2C 来调用 Azure 函数中托管的 API。 我想在成功登录时调用我的 API 以将用户信息添加/更新到数据库中。 我一直在关注本指南 当尝试将我输入的 httpclient 注入 AccountClaimsPrincipalFactory 时,我遇到了运行时错误:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:ValueFactory 试图访问此实例的 Value 属性。 System.InvalidOperationException:ValueFactory 试图访问此实例的 Value 属性。

这显示在浏览器中,但应用程序编译并运行得很好。 如果我不注入我的PlatformServiceClient ,这些代码效果很好,但我需要调用 API 来记录用户。 涉及以下文件。 我调整了一些东西来简化。 这似乎是合适的方法,但我没有看到在索赔工厂中进行 api 调用的示例。

CustomAccountFactory.cs

 public class CustomAccountFactory: AccountClaimsPrincipalFactory<CustomUserAccount>
    {
        public IPlatformServiceClient client { get; set; }
        public CustomAccountFactory(NavigationManager navigationManager,
            IPlatformServiceClient platformServiceClient,
            IAccessTokenProviderAccessor accessor) : base(accessor)
        {
            client = platformServiceClient;
        }

        public override async ValueTask<ClaimsPrincipal> CreateUserAsync(
            CustomUserAccount account, RemoteAuthenticationUserOptions options)
        {
            var initialUser = await base.CreateUserAsync(account, options);

            if (initialUser.Identity.IsAuthenticated)
            {
                //call the API here
                await client.RegisterUserAsync();
                
            }

            return initialUser;
        }
    }

Program.cs摘录

builder.Services.AddScoped<CustomAuthorizationMessageHandler>();

builder.Services.AddHttpClient<IPlatformServiceClient, PlatformServiceClient>(
    client => client.BaseAddress = new Uri(builder.Configuration["PlatformServiceUrl"]))
.AddHttpMessageHandler<CustomAuthorizationMessageHandler>();

builder.Services.AddMsalAuthentication<RemoteAuthenticationState, CustomUserAccount>(options =>
{
    builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
    options.ProviderOptions.DefaultAccessTokenScopes.Add("openid");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("offline_access");
    options.ProviderOptions.DefaultAccessTokenScopes.Add("access_as_user");
    options.ProviderOptions.LoginMode = "redirect";
    options.UserOptions.RoleClaim = "roles";
}).AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount, CustomAccountFactory>();

CustomAuthorizationMessageHandler.cs

 public class CustomAuthorizationMessageHandler : AuthorizationMessageHandler
    {
        public CustomAuthorizationMessageHandler(IAccessTokenProvider provider,
            NavigationManager navigationManager)
            : base(provider, navigationManager)
        {
            ConfigureHandler(
                authorizedUrls: new[] { "http://localhost:7071" },
                scopes: new[] { "access_as_user" });
        }
    }

我通过创建客户端的命名实例并将 IHttpClientFactory 传递给 CustomAccountFactory 解决了这个问题。

builder.Services.AddHttpClient<PlatformServiceClient>("PlatformServiceClient",
    client => client.BaseAddress = new Uri(builder.Configuration["PlatformServiceUrl"]))
.AddHttpMessageHandler<CustomAuthorizationMessageHandler>();

在那里我可以创建一个客户端,但我必须手动设置我的网址,而不是使用我已经完成这项工作的类型化客户端。

var client = factory.CreateClient("PlatformServiceClient");
var response = await client.GetAsync("/user/me");

我还在调用 AddMsalAuthenication 之前注册了新客户端

builder.Services.AddTransient(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("PlatformServiceClient"));

我按照Coding Flamingo 在此处找到的代码完成了所有这些工作。 这一切都按预期工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM