IdentityServer4部署Azure后登录会话仅20分钟,如何实现持久登录?
Hey there, let's tackle why your IdentityServer4 setup on Azure is kicking users back to the login page after just 20 minutes, even though you've tried configuring cookie lifetimes. Here's what's likely going wrong and how to fix it:
1. Check Your Client Configuration First
You're using a custom ClientStore, so the first thing to verify is that your client settings have sufficiently long token lifetimes and allow offline access (critical for persistent logins):
// Make sure your Client instance in ClientStore includes these settings new Client { ClientId = "your-client-id", // ... other client configs // Set access token lifetime to something long (e.g., 24 hours = 86400 seconds) AccessTokenLifetime = 86400, // Enable offline access to get refresh tokens for persistent logins AllowOfflineAccess = true, // Set refresh token lifetime (e.g., 7 days = 604800 seconds) RefreshTokenLifetime = 604800, // Turn on sliding expiration to extend refresh token validity with use SlidingRefreshTokenExpiration = true, // Choose refresh token behavior: OneTimeOnly (safer) or ReUse RefreshTokenUsage = TokenUsage.OneTimeOnly }
The default AccessTokenLifetime is 1 hour, but if your client is set to 1200 seconds (20 minutes), that's exactly why users are being logged out. This is the most common culprit here.
2. Fix IdentityServer's Authentication Cookie Setup
You already set options.Authentication.CookieLifetime = TimeSpan.FromHours(24) and CookieSlidingExpiration = true—that part is correct. However, the custom cookie config you added later might be overriding IdentityServer's default authentication scheme:
// Remove or adjust this section, as it can interfere with IdentityServer's built-in cookie auth // services.AddAuthentication("MyCookie") // .AddCookie("MyCookie", options => { // options.ExpireTimeSpan = TimeSpan.FromHours(24); // });
IdentityServer uses its own default authentication scheme (IdentityServerConstants.DefaultCookieAuthenticationScheme), so adding a custom default scheme can break its cookie handling. If you need a custom cookie for other parts of your app, configure it after AddIdentityServer and don't set it as the default.
3. Verify Operational Store Cleanup (Optional)
While this won't cause immediate 20-minute logouts, a too-aggressive token cleanup interval could delete refresh tokens early. Adjust it in your AddOperationalStore setup:
.AddOperationalStore(options => { options.ConfigureDbContext = builder => builder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), db => db.MigrationsAssembly(migrationsAssembly)); // Set token cleanup to run once a day (86400 seconds) instead of the default options.TokenCleanupInterval = 86400; })
4. Add Token Refresh Logic on the Client Side
If your client uses the Authorization Code Flow, you need to handle refresh tokens to automatically get new access tokens before they expire. For an ASP.NET Core client, that looks like this:
services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; options.DefaultChallengeScheme = "oidc"; }) .AddCookie("Cookies", options => { options.ExpireTimeSpan = TimeSpan.FromHours(24); options.SlidingExpiration = true; }) .AddOpenIdConnect("oidc", options => { options.Authority = "your-identityserver-url"; options.ClientId = "your-client-id"; options.ClientSecret = "your-client-secret"; options.ResponseType = "code"; options.SaveTokens = true; // Critical: Add offline_access scope to get refresh tokens options.Scope.Add("offline_access"); options.GetClaimsFromUserInfoEndpoint = true; });
Without the offline_access scope, your client won't receive a refresh token, so when the access token expires, the user has to log back in.
Quick Recap
The most likely fixes for your 20-minute logout issue are:
- Your client's
AccessTokenLifetimeis set to 20 minutes (1200 seconds) — update it to a longer value - You haven't enabled
AllowOfflineAccesson the client or added theoffline_accessscope on the client side, so refresh tokens aren't being used to extend sessions
Start with checking the client configuration—that's almost always the root cause here.
内容的提问来源于stack exchange,提问作者Henrique Mauri

