fix(central-ui): resolve CentralUI-005 — sliding cookie session expiry (Security AddCookie + AuthEndpoints + SessionExpiry)

This commit is contained in:
Joseph Doherty
2026-05-16 23:54:31 -04:00
parent b1f4251d75
commit 1e2e7d2e7c
6 changed files with 240 additions and 42 deletions

View File

@@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace ScadaLink.Security;
@@ -25,6 +26,28 @@ public static class ServiceCollectionExtensions
options.Cookie.SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.Always;
});
// CentralUI-005: configure the cookie session as a sliding window so the
// code matches the documented policy ("sliding refresh, 30-minute idle
// timeout"). ASP.NET cookie auth exposes a single ExpireTimeSpan plus a
// SlidingExpiration flag — it cannot natively model a 15-minute sliding
// token AND a separate 30-minute absolute idle cap. The faithful
// interpretation: the cookie window IS the idle timeout
// (SecurityOptions.IdleTimeoutMinutes, default 30) and SlidingExpiration
// renews it on activity (the middleware re-issues the cookie once past
// the halfway mark of the window). An active user is therefore kept
// signed in; an idle user is signed out after the idle timeout. The
// 15-minute JwtExpiryMinutes governs the lifetime of the embedded JWT
// itself (see JwtTokenService) — a separate layer from the cookie
// session window. Bound here via PostConfigure so SecurityOptions
// (configured by the Host after AddSecurity) is honoured.
services.AddOptions<CookieAuthenticationOptions>(CookieAuthenticationDefaults.AuthenticationScheme)
.Configure<IOptions<SecurityOptions>>((cookieOptions, securityOptions) =>
{
var idleMinutes = securityOptions.Value.IdleTimeoutMinutes;
cookieOptions.ExpireTimeSpan = TimeSpan.FromMinutes(idleMinutes);
cookieOptions.SlidingExpiration = true;
});
services.AddScadaLinkAuthorization();
return services;