I would like to setup authentication and authorization for my project, I have a little experience with identity server as most of my clients use it but since it mostly is setup, I don't have experience in setting it up myself.
I'm looking at the documentation samples, codemaze and everything else but I'm stuck. The documentation is to authenticate the frontend to the backend where I like to use username and password, 2FA, ....
My project is going to be a medium sized micro service architecture, which is currently orchestrated in .NET Aspire and using .NET 8.0.
I already setup duende.identityserver as an API purely backend.
For the frontend, I'm going with a Blazor web app or Blazor server and wasm. This template creates 2 assemblies - client and server. Since I want usernames and passwords I went with the account type "individual accounts", this gives me all the pages that I want.
Except there is a problem in the server assembly there is also logic that is already in my backend identity server API project, mainly the ApplicationDbContext
and migrations.
I tried to delete this code and obviously I f*d up. Anyway I can't run my frontend as it is giving me a dependency injection error on UserManager
.
I tried to add this even tough it was never there.
builder.Services.AddScoped<UserManager<ApplicationUser>>();
builder.Services.AddScoped<SignInManager<ApplicationUser>>();
Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore
1[Xyflux.Frontend.Data.ApplicationUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager
1[Xyflux.Frontend.Data.ApplicationUser]'
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.UserManager
1[Xyflux.Frontend.Data.ApplicationUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserManager
1[Xyflux.Frontend.Data.ApplicationUser]': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[Xyflux.Frontend.Data.ApplicationUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager
1[Xyflux.Frontend.Data.ApplicationUser]'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.SignInManager1[Xyflux.Frontend.Data.ApplicationUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.SignInManager
1[Xyflux.Frontend.Data.ApplicationUser]': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[Xyflux.Frontend.Data.ApplicationUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager
1[Xyflux.Frontend.Data.ApplicationUser]'.) (Error while validating the service descriptor 'ServiceType: Xyflux.Frontend.Components.Account.IdentityUserAccessor Lifetime: Scoped ImplementationType: Xyflux.Frontend.Components.Account.IdentityUserAccessor': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[Xyflux.Frontend.Data.ApplicationUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager
1[Xyflux.Frontend.Data.ApplicationUser]'.)'
And full DI
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Xyflux.Frontend.Components;
using Xyflux.Frontend.Components.Account;
using Xyflux.Frontend.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
builder.Services.AddCascadingAuthenticationState();
builder.Services.AddScoped<UserManager<ApplicationUser>>();
builder.Services.AddScoped<SignInManager<ApplicationUser>>();
builder.Services.AddScoped<IdentityUserAccessor>();
builder.Services.AddScoped<IdentityRedirectManager>();
builder.Services.AddScoped<AuthenticationStateProvider, PersistingRevalidatingAuthenticationStateProvider>();
builder.Services.AddBff();
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.Cookie.Name = "BlazorApp.Cookie";
options.Cookie.HttpOnly = true;
options.SlidingExpiration = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
})
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://localhost:5001";
options.ClientId = "blazor-client";
options.ClientSecret = "your_client_secret";
options.ResponseType = "code";
options.Scope.Add("openid");
options.Scope.Add("profile");
options.Scope.Add("api1");
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
options.ForwardSignIn = "";
});
builder.Services.AddAuthorization(options =>
{
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddSingleton<IEmailSender<ApplicationUser>, IdentityNoOpEmailSender>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseWebAssemblyDebugging();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// 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.UseAuthentication();
app.UseAuthorization();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(typeof(Xyflux.Frontend.Client._Imports).Assembly);
// Add additional endpoints required by the Identity /Account Razor components.
app.MapAdditionalIdentityEndpoints();
app.Run();
I'm also using the duende.bff framework.
Can somebody guide me what I did wrong and guide me what my next steps to do are?
The error indicates you didn't register DB related services,try add required services follow this document:
builder.Services.AddIdentityServer()
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlite(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlite(connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddTestUsers(TestUsers.Users);
If you are using ASP.NET Core Identity ,try register services follow this document:
builder.Services
.AddIdentityServer(options =>
{
// ...
})
.AddInMemoryIdentityResources(Config.IdentityResources)
.AddInMemoryApiScopes(Config.ApiScopes)
.AddInMemoryClients(Config.Clients)
.AddAspNetIdentity<ApplicationUser>()
.AddProfileService<CustomProfileService>();