I have a blazor WASM Hosted project using IdentityServer4 ( default from VS templates ). When I launch my application, however, I get the following error. Debugging shows that the options.Value.SigningCredential is null so the .Key is causing the NullReferenceException. So I am missing something, somewhere.
Here is the Client Program.cs
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
//builder.RootComponents.Add<App>("#app");
builder.Services.AddHttpClient("BBQFriend.API", client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("BBQFriend.API"));
builder.Services.AddApiAuthorization();
var baseAddress = new Uri("https://localhost:44395/api/");
void RegisterTypedClient<TClient, TImplementation>(Uri apiBaseUrl)
where TClient : class where TImplementation : class, TClient
{
builder.Services.AddHttpClient<TClient, TImplementation>(client =>
{
client.BaseAddress = apiBaseUrl;
});
}
RegisterTypedClient<ICountryService, CountryService>(baseAddress);
await builder.Build().RunAsync();
}
Here is the Server Startup.cs
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//Register EntityFramework Core Datacontext for Dependency Injection
services.AddDbContext<DataContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
//Add common Identity Screens
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<DataContext>();
//Set up IdentityServer
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, DataContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
//Register Services for DirectNavigation
services.AddScoped<ICountryService, CountryService>();
//Register Repositories for Dependency Injection
services.AddScoped<ICountryRepository, CountryRepository>();
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddControllersWithViews();
services.AddRazorPages();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebAssemblyDebugging();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
//endpoints.MapFallbackToFile("index.html");
endpoints.MapFallbackToPage("/_Host");
});
}
And here is the applications DataContext.cs
public class DataContext : ApiAuthorizationDbContext<ApplicationUser>
{
public DataContext(DbContextOptions options, IOptions<OperationalStoreOptions> operationalStoreOptions) : base(options, operationalStoreOptions)
{
ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
public DbSet<Country> Countries { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfiguration(new CountryConfiguration());
base.OnModelCreating(modelBuilder);
}
}
Issue is that you are missing the client config values. As you are using
builder.Services.AddApiAuthorization();
it tries to load configuration from default: