简体   繁体   中英

How to redirect to login page in ASP.NET Core 6 web app with Angular frontend?

I developed an ASP.NET Core 6 based web application which uses Angular for the frontend. I also implemented a custom authentication handler (based on Microsoft.AspNetCore.Authentication.AuthenticationHandler) because I need to authenticate against a custom 3rd party API in this application. Here is how the application is currently initialized:

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContextFactory<DatabaseContextName>();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

builder.Services.AddAuthentication(CustomAuthDefaults.AuthenticationScheme)
   .AddScheme<CustomAuthSchemeOptions, CustomAuthHandler>(
        CustomAuthDefaults.AuthenticationScheme, options => { });
builder.Services.AddAuthorization(options =>
{
    options.FallbackPolicy = options.DefaultPolicy;
});

builder.Services.AddControllers();
builder.Services.AddDistributedMemoryCache();

builder.Services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromHours(8);
    options.Cookie.HttpOnly = true;
    options.Cookie.IsEssential = true;
    options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});

WebApplication app = builder.Build();

app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseSession();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

// Backend-Routes for the treatment of 404-Errors
app.Map("api/{**slug}", HandleApiFallback);

// Fallback-Route to the Frontend
app.MapFallbackToFile("{**slug}", "index.html");

app.Run();

static Task HandleApiFallback(HttpContext context)
{
    context.Response.StatusCode = StatusCodes.Status404NotFound;
    return Task.CompletedTask;
}

In the Angular frontend I already have a HttpInterceptor in place to redirect to the login page if the user is no longer authenticated. While this currently works just fine when hosting the app on Kestrel, the redirect does not work at all while hosting the app on an IIS webserver.

Not only does the IIS webserver ignore my session timeout of 8 hours as configured in builder.Services.AddSession() and lets the session expire much quicker (it seems to expire after less than a few minutes already), but it also seems to block any http requests entirely as soon as the session expired. This results in a blank page being shown to the user after refreshing the site (because IIS returns a HTTP 401 error), instead of redirecting to the login page.

How can I configure the application to use the correct session timeout and also fix the redirect to the login page after the session expired in IIS?

I already found some suggestions such as adding .AddCookie(options => options.LoginPath = "/login") after builder.Services.AddAuthentication() or adding builder.Services.ConfigureApplicationCookie(options => options.LoginPath = "/login") but none of those worked for me so far.

After some further troubleshooting and with the help of several people I was able to finally solve this problem.

It turns out that the fallback I added via MapFallbackToFile did not work properly when not authenticated. After changing this line to app.MapFallbackToFile("{**slug}", "index.html").AllowAnonymous() , everything seems to work fine. No idea if this is the proper solution, but it works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM