I used ABP CLI generated a MVC template, with which I would like to try a Blazor Server project. I do add a MyProjBlazorModule which was as same as every common Module, just like the ConsoleTestApp project did:
namespace MyProj.Blazor
{
[DependsOn(
typeof(MyProjHttpApiClientModule),
typeof(AbpHttpClientIdentityModelModule)
)]
public class MyProjBlazorModule : AbpModule
{
}
}
Then I added the module as service to ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
services.AddSyncfusionBlazor();
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddApplication<TaurusBlazorModule>();
}
for a rapid test, I also copied ClientDemoService class from template project MyProj.HttpApi.Client.ConsoleTestApp , and I consume it in my index.razor like this:
@inject ClientDemoService _clientService
...
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
profile = await _clientService.RunAsync();
}
But it couldn't work, with a error message in browser:
InvalidOperationException: No authenticationScheme was specified, and there was no DefaultAuthenticateScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action configureOptions).
while If I copy code identical to the console test project like this:
using (var application = AbpApplicationFactory.Create<MyProjConsoleApiClientModule>())
{
application.Initialize();
var demo = application.ServiceProvider.GetRequiredService<ClientDemoService>();
profile = AsyncHelper.RunSync(() => demo.RunAsync());
}
and it worked. I would like to know the difference between using ABP module and explicitly calling an ugly ServiceProvider method here, and how can I fix this issue in some correct and beautiful way?
Thanks for everyone's help!
Finally, I have got what's wrong with that. In the template source code from abp CLI, the MyProjHttpApiHostModule's ConfigureAuthentication method register authenticate service like this:
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
};
});
}
where AddAuthentication() method used empty parameter overload, that caused the No authenticationScheme was specified error. I referenced IdentityServer4 official document and found the right way to do:
context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication(options =>
{
...
});
That's easy, I should set the default scheme JwtBearerDefaults.AuthenticationScheme using a different overload of AddAuthentication method just as the error had reported.
I hope this post could help someone facing the same or similar issue.