.NET 6中基于IdentityServer 6实现SPA首次加载前身份认证问题
问题描述
我尝试使用IdentityServer 6搭建认证服务器,为不同域名的多个SPA应用提供身份认证服务。在.NET 3.1+IdentityServer 4环境中,首次访问SPA时可正常跳转至认证服务器的登录页,但在.NET 6+IdentityServer 6环境下,SPA会直接加载首页而不跳转;访问带有[Authorize]特性的资源时,返回200状态码及登录URL,但不会自动跳转至登录页。我参考了相关方案,但无法在新版本中实现预期效果,以下是Angular SPA的配套后端代码:
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.OpenIdConnect; using Serilog; Log.Logger = new LoggerConfiguration() .WriteTo.Console() .CreateBootstrapLogger(); Log.Information("Starting up"); try { var builder = WebApplication.CreateBuilder(args); builder.Host.UseSerilog((ctx, lc) => lc .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}") .Enrich.FromLogContext() .ReadFrom.Configuration(ctx.Configuration)); // Add services to the container. builder.Services.AddControllersWithViews(); builder.Services.AddAuthentication(authenticationOptions => { authenticationOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; authenticationOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; }) .AddCookie("cookie") .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, openIdConnectOptions => { openIdConnectOptions.Authority = builder.Configuration["InteractiveServiceSettings:AuthorityUrl"]; openIdConnectOptions.ClientId = builder.Configuration["InteractiveServiceSettings:ClientId"]; openIdConnectOptions.ClientSecret = builder.Configuration["InteractiveServiceSettings:ClientSecret"]; openIdConnectOptions.Scope.Add(builder.Configuration["InteractiveServiceSettings:Scopes:0"]); openIdConnectOptions.GetClaimsFromUserInfoEndpoint = true; openIdConnectOptions.ResponseType = "code"; openIdConnectOptions.SaveTokens = true; openIdConnectOptions.UsePkce = true; openIdConnectOptions.ResponseMode = "query"; openIdConnectOptions.RequireHttpsMetadata = false; }); builder.Services.AddAuthorization(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { // 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.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseCors("AllowAll"); app.Use(async (context, next) => { if (!(context.User.Identity.IsAuthenticated && context.Request.Path != "/signin-oidc")) { await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme); } else { await next(); } }); //app.UseEndpoints(endpoints => //{ // endpoints.MapControllers(); // //fallback to SPA // //endpoints.MapFallbackToFile("index.html"); // endpoints.MapFallback(CreateRequestDelegate(endpoints, "index.html")); // //local function // RequestDelegate CreateRequestDelegate(IEndpointRouteBuilder endpoints, string filePath) // { // var app = endpoints.CreateApplicationBuilder(); // //Use Cookie authentication to secure angular index.html file // app.Use(async (context, next) => // { // bool isAuth = false; // //TODO: run logic to check authentication // //.... // if (!isAuth) // { // await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme); // } // else // { // await next.Invoke(); // } // }); // //to SPA index.html // app.Use(next => context => // { // context.Request.Path = "/" + filePath; // // Set endpoint to null so the static files middleware will handle the request. // context.SetEndpoint(null); // return next(context); // }); // app.UseStaticFiles(); // return app.Build(); // } //}); app.MapControllerRoute( name: "default", pattern: "{controller}/{action=Index}/{id?}"); app.MapFallbackToFile("index.html"); app.Run(); } catch (Exception ex) { Log.Fatal(ex, "Unhandled exception"); } finally { Log.Information("Shut down complete"); Log.CloseAndFlush(); }
内容的提问来源于stack exchange,提问作者Raja Somu
相关产品推荐
相关产品推荐

