|
| 1 | +--- |
| 2 | +title: Configure ASP.NET or ASP.NET Core App Session to Last Longer Than Entra ID Tokens |
| 3 | +description: Discusses how to configure ASP.NET or ASP.NET Core App session to last longer than Microsoft Entra ID token. |
| 4 | +ms.date: 05/31/2025 |
| 5 | +ms.reviewer: willfid |
| 6 | +ms.service: entra-id |
| 7 | +ms.custom: sap:Developing or Registering apps with Microsoft identity platform |
| 8 | +--- |
| 9 | +# Customize middleware authentication ticket to extend user sign-in duration |
| 10 | + |
| 11 | +By default, Microsoft Entra ID tokens (ID tokens, access tokens, and SAML tokens) expire after one hour. Also by default, ASP.NET and ASP.NET Core middleware set their authentication tickets to the expiration of these tokens. If you don't want your web application to redirect users to Microsoft Entra ID to have them sign in again, you can customize the middleware authentication ticket. |
| 12 | + |
| 13 | +This customization can also help resolve AJAX-related issues, such as coss-origin resource sharing (CORS) errors to login.microsoftonline.com. These issues often occur when your app functions as both a web application and a web API. |
| 14 | +## For ASP.NET |
| 15 | + |
| 16 | +In the `ConfigureAuth` method of the `Startup.Auth.cs` file, update the `app.UseCookieAuthentication()` method to: |
| 17 | + |
| 18 | +```csharp |
| 19 | +app.UseCookieAuthentication(new CookieAuthenticationOptions() |
| 20 | +{ |
| 21 | + CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(), |
| 22 | + Provider = new CookieAuthenticationProvider() |
| 23 | + { |
| 24 | + OnResponseSignIn = (context) => |
| 25 | + { |
| 26 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 27 | + } |
| 28 | + } |
| 29 | +}); |
| 30 | +``` |
| 31 | + |
| 32 | +Then, decouple the token lifetime from the web app: |
| 33 | + |
| 34 | +```csharp |
| 35 | +app.UseOpenIdConnectAuthentication( |
| 36 | + new OpenIdConnectAuthenticationOptions |
| 37 | + { |
| 38 | + UseTokenLifetime = false, |
| 39 | + ... |
| 40 | +``` |
| 41 | + |
| 42 | +## For ASP.NET Core |
| 43 | + |
| 44 | +In ASP.NET Core, you have to add the `OnTokenValidated` event to update the ticket properties. This addition sets the ticket expiration time to occur before the application redirects to Microsoft Entra ID for reauthentication. |
| 45 | + |
| 46 | +```csharp |
| 47 | +services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options => |
| 48 | +{ |
| 49 | + // decouple the token lifetime from the Web App |
| 50 | + options.UseTokenLifetime = false; |
| 51 | + |
| 52 | + // other configurations... |
| 53 | + // ... |
| 54 | +
|
| 55 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 56 | + options.Events ??= new OpenIdConnectEvents(); |
| 57 | + options.Events.OnTokenValidated = async context => |
| 58 | + { |
| 59 | + await onTokenValidated(context); |
| 60 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 61 | + }; |
| 62 | +}); |
| 63 | +``` |
| 64 | + |
| 65 | +### Examples |
| 66 | + |
| 67 | +Here are a few examples of how to do make this setting: |
| 68 | + |
| 69 | +If you're using code similar to the following example to add Microsoft Entra ID authentication: |
| 70 | + |
| 71 | +```csharp |
| 72 | +services.AddAuthentication(AzureADDefaults.AuthenticationScheme) |
| 73 | + .AddAzureAD(options => Configuration.Bind("AzureAd", options)) |
| 74 | +``` |
| 75 | + |
| 76 | +Then add the following code: |
| 77 | + |
| 78 | +```csharp |
| 79 | +services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options => |
| 80 | +{ |
| 81 | + // decouple the id_token lifetime from the Web App |
| 82 | + options.UseTokenLifetime = false; |
| 83 | + |
| 84 | + //… |
| 85 | +
|
| 86 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 87 | + options.Events ??= new OpenIdConnectEvents(); |
| 88 | + options.Events.OnTokenValidated = async context => |
| 89 | + { |
| 90 | + await onTokenValidated(context); |
| 91 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 92 | + }; |
| 93 | +}); |
| 94 | +``` |
| 95 | + |
| 96 | +Your configuration in Startup.cs should resemble the following example: |
| 97 | + |
| 98 | +```csharp |
| 99 | +public void ConfigureServices(IServiceCollection services) |
| 100 | +{ |
| 101 | + //... |
| 102 | +
|
| 103 | + services.AddAuthentication(AzureADDefaults.AuthenticationScheme) |
| 104 | + .AddAzureAD(options => Configuration.Bind("AzureAd", options)) |
| 105 | + .AddCookie(); |
| 106 | + |
| 107 | + //... |
| 108 | +
|
| 109 | + services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options => |
| 110 | + { |
| 111 | + // decouple the token lifetime from the Web App |
| 112 | + options.UseTokenLifetime = false; |
| 113 | + |
| 114 | + //... |
| 115 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 116 | + options.Events ??= new OpenIdConnectEvents(); |
| 117 | + options.Events.OnTokenValidated = async context => |
| 118 | + { |
| 119 | + await onTokenValidated(context); |
| 120 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 121 | + }; |
| 122 | + }); |
| 123 | + |
| 124 | + //... |
| 125 | +} |
| 126 | +``` |
| 127 | + |
| 128 | +If you're using `Microsoft.Identity.Web` to add your Microsoft Entra ID configuration: |
| 129 | + |
| 130 | +```csharp |
| 131 | +//… |
| 132 | +using Microsoft.Identity.Web; |
| 133 | +//… |
| 134 | +public class Startup |
| 135 | +{ |
| 136 | + // ... |
| 137 | + public void ConfigureServices(IServiceCollection services) |
| 138 | + { |
| 139 | + // ... |
| 140 | + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) |
| 141 | + .AddMicrosoftIdentityWebApp(options => |
| 142 | + { |
| 143 | + Configuration.Bind("AzureAD", options); |
| 144 | + |
| 145 | + // decouple the token lifetime from the Web App |
| 146 | + options.UseTokenLifetime = false; |
| 147 | + |
| 148 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 149 | + options.Events ??= new OpenIdConnectEvents(); |
| 150 | + |
| 151 | + options.Events.OnTokenValidated = async context => |
| 152 | + { |
| 153 | + await onTokenValidated(context); |
| 154 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 155 | + }; |
| 156 | + }); |
| 157 | + // ... |
| 158 | +} |
| 159 | +``` |
| 160 | + |
| 161 | +If you're implementing your own custom `OpenIdConnectOptions` to configure Microsoft Entra ID authentication: |
| 162 | + |
| 163 | +```csharp |
| 164 | +services.Configure<OpenIdConnectOptions>(options => |
| 165 | +{ |
| 166 | + //… |
| 167 | + options.Events.OnTokenValidated = async context => |
| 168 | + { |
| 169 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 170 | + }; |
| 171 | +}); |
| 172 | +``` |
| 173 | + |
| 174 | +If you're integrating an ASP.NET Core WS-Fed application: |
| 175 | + |
| 176 | +```csharp |
| 177 | +public void ConfigureServices(IServiceCollection services) |
| 178 | +{ |
| 179 | + services.AddAuthentication(WsFederationDefaults.AuthenticationScheme) |
| 180 | + .AddCookie() |
| 181 | + .AddWsFederation(options => |
| 182 | + { |
| 183 | + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; |
| 184 | + |
| 185 | + // decouple the token lifetime from the Web App |
| 186 | + options.UseTokenLifetime = false; |
| 187 | + |
| 188 | + // MetadataAddress for your Azure Active Directory instance. |
| 189 | + options.MetadataAddress = "https://login.microsoftonline.com/common/federationmetadata/2007-06/federationmetadata.xml"; |
| 190 | + |
| 191 | + // Wtrealm is the app's identifier in the Active Directory instance. |
| 192 | + // For ADFS, use the relying party's identifier, its WS-Federation Passive protocol URL: |
| 193 | + options.Wtrealm = "https://localhost:44307/"; |
| 194 | + |
| 195 | + // For AAD, use the Application ID URI from the app registration's Overview blade: |
| 196 | + options.Wtrealm = "https://contoso.onmicrosoft.com/wsfedapp"; |
| 197 | + |
| 198 | + // Set the Authentication Ticket to expire at a custom time |
| 199 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 200 | + options.Events ??= new OpenIdConnectEvents(); |
| 201 | + |
| 202 | + options.Events.OnSecurityTokenValidated = async context => |
| 203 | + { |
| 204 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 205 | + } |
| 206 | +``` |
| 207 | +## More information |
| 208 | + |
| 209 | +These settings control the expiration of the authentication ticket that determines how long a user stays signed in. You can configure this expiration to suit your requirement. |
| 210 | + |
| 211 | +> [!NOTE] |
| 212 | +> If you modify the ticket expiration, users might still have access to your application even if they're deleted or disabled in Microsoft Entra ID. This condition remains true until the ticket expires. |
| 213 | + |
| 214 | +[!INCLUDE [Azure Help Support](../../../includes/azure-help-support.md)] |
0 commit comments