1

我使用ABP CLI生成了一个 MVC 模板,我想用它来尝试一个Blazor Server项目。我确实添加了一个与每个常见模块相同的 MyProjBlazorModule,就像ConsoleTestApp 项目一样:

namespace MyProj.Blazor
{
    [DependsOn(
        typeof(MyProjHttpApiClientModule),
        typeof(AbpHttpClientIdentityModelModule)
        )]
    public class MyProjBlazorModule : AbpModule
    {
    }
}

然后我将模块作为服务添加到ConfigureServices 方法:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSyncfusionBlazor();
        services.AddRazorPages();
        services.AddServerSideBlazor();
        services.AddSingleton<WeatherForecastService>();
        services.AddApplication<TaurusBlazorModule>();

    }

为了进行快速测试,我还从模板项目MyProj.HttpApi.Client.ConsoleTestApp复制了ClientDemoService类,并在我的 index.razor 中使用它,如下所示:

@inject ClientDemoService _clientService
...
protected override async Task OnInitializedAsync()
{

    await base.OnInitializedAsync();
    profile = await _clientService.RunAsync();
}

但它无法工作,浏览器中出现错误消息:

InvalidOperationException:未指定 authenticationScheme,也未找到 DefaultAuthenticateScheme。可以使用 AddAuthentication(string defaultScheme) 或 AddAuthentication(Action configureOptions) 设置默认方案。

而如果我复制与控制台测试项目相同的代码,如下所示:

        using (var application = AbpApplicationFactory.Create<MyProjConsoleApiClientModule>())
        {
            application.Initialize();

            var demo = application.ServiceProvider.GetRequiredService<ClientDemoService>();
            profile = AsyncHelper.RunSync(() => demo.RunAsync());

        }

它奏效了。我想知道在这里使用 ABP 模块和显式调用丑陋的 ServiceProvider 方法之间的区别,以及如何以正确而美观的方式解决这个问题?

感谢大家的帮助!

4

1 回答 1

2

最后,我知道这有什么问题。在abp CLI的模板源代码中,MyProjHttpApiHostModule 的 ConfigureAuthentication方法注册身份验证服务,如下所示:

    private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddAuthentication()
            .AddIdentityServerAuthentication(options =>
            {
                options.Authority = configuration["AuthServer:Authority"];
                options.RequireHttpsMetadata = false;
                options.ApiName = "MyProj";
                options.JwtBackChannelHandler = new HttpClientHandler()
                {
                    ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
                };
            });
    }

其中 AddAuthentication() 方法使用了空参数重载,导致No authenticationScheme is specified错误。我参考了IdentityServer4官方文档,找到了正确的做法:

context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddIdentityServerAuthentication(options =>
            {
                ...
            });

这很简单,我应该使用不同的 AddAuthentication 方法重载来设置默认方案JwtBearerDefaults.AuthenticationScheme ,就像错误报告的那样。

我希望这篇文章可以帮助面临相同或类似问题的人。

于 2020-01-18T05:46:51.490 回答