|
| 1 | +--- |
| 2 | +title: Update ASP.NET or ASP.NET Core App Session to Last Longer Than Entra ID Tokens |
| 3 | +description: Describes a problem in which Microsoft Entra ID is sending the token to an incorrect reply URL endpoint or localhost. |
| 4 | +ms.date: 08/26/2022 |
| 5 | +ms.reviewer: bernawy |
| 6 | +ms.service: entra-id |
| 7 | +ms.custom: sap:Developing or Registering apps with Microsoft identity platform |
| 8 | +--- |
| 9 | +# Update ASP.NET or ASP.NET Core App Session to Last Longer Than Azure AD Tokens |
| 10 | + |
| 11 | +Microsoft Entra ID tokens (ID tokens, access tokens, and SAML tokens) by default last one hour. Asp.Net and Asp.Net Core Middleware set their authentication ticket to the expiration of these tokens by default. If you do not want your web application to redirect users to Microsoft Entra ID to sign in again, you can customize the Middleware authentication ticket. |
| 12 | + |
| 13 | +This customization can also help resolve AJAX issues (such as CORS errors to `login.microsoftonline.com`) where your app is both a Web App and Web API. |
| 14 | + |
| 15 | +## For ASP.NET |
| 16 | + |
| 17 | +In most cases, In the `ConfigureAuth` method of your `Startup.Auth.cs` file, update the `app.UseCookieAuthentication()` method to: |
| 18 | + |
| 19 | +```csharp |
| 20 | +app.UseCookieAuthentication(new CookieAuthenticationOptions() |
| 21 | +{ |
| 22 | + CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(), |
| 23 | + Provider = new CookieAuthenticationProvider() |
| 24 | + { |
| 25 | + OnResponseSignIn = (context) => |
| 26 | + { |
| 27 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 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 | + |
| 43 | +## For Asp.Net Core |
| 44 | + |
| 45 | +In ASP.NET Core, you need to add the `OnTokenValidated` event to update the ticket properties. This sets the ticket expiration time before the application redirects to Microsoft Entra ID for re-authentication. |
| 46 | + |
| 47 | +``` |
| 48 | +services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options => |
| 49 | +{ |
| 50 | + // decouple the token lifetime from the Web App |
| 51 | + options.UseTokenLifetime = false; |
| 52 | + |
| 53 | + // other configurations... |
| 54 | + // ... |
| 55 | +
|
| 56 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 57 | + options.Events ??= new OpenIdConnectEvents(); |
| 58 | + options.Events.OnTokenValidated = async context => |
| 59 | + { |
| 60 | + await onTokenValidated(context); |
| 61 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 62 | + }; |
| 63 | +}); |
| 64 | +``` |
| 65 | + |
| 66 | +### Examples |
| 67 | + |
| 68 | +Here are a few examples of how to do this: |
| 69 | + |
| 70 | +**If you're using code similar to the following to add Microsoft Entra ID authentication**: |
| 71 | + |
| 72 | +``` |
| 73 | +services.AddAuthentication(AzureADDefaults.AuthenticationScheme) |
| 74 | + .AddAzureAD(options => Configuration.Bind("AzureAd", options)) |
| 75 | +``` |
| 76 | + |
| 77 | +Then add the following codes: |
| 78 | + |
| 79 | +```csharp |
| 80 | +services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options => |
| 81 | +{ |
| 82 | + // decouple the id_token lifetime from the Web App |
| 83 | + options.UseTokenLifetime = false; |
| 84 | + |
| 85 | + //… |
| 86 | +
|
| 87 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 88 | + options.Events ??= new OpenIdConnectEvents(); |
| 89 | + options.Events.OnTokenValidated = async context => |
| 90 | + { |
| 91 | + await onTokenValidated(context); |
| 92 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 93 | + }; |
| 94 | +}); |
| 95 | +``` |
| 96 | +Your configuration in Startup.cs should look something like this: |
| 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 | +```csharp |
| 128 | +app.UseCookieAuthentication(new CookieAuthenticationOptions() |
| 129 | +{ |
| 130 | + CookieManager = new Microsoft.Owin.Host.SystemWeb.SystemWebChunkingCookieManager(), |
| 131 | + Provider = new CookieAuthenticationProvider() |
| 132 | + { |
| 133 | + OnResponseSignIn = (context) => |
| 134 | + { |
| 135 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 136 | + } |
| 137 | + } |
| 138 | +}); |
| 139 | +``` |
| 140 | + |
| 141 | +**If you're using `Microsoft.Identity.Web` to add your Microsoft Entra ID configuration:** |
| 142 | + |
| 143 | +``` |
| 144 | +//… |
| 145 | +using Microsoft.Identity.Web; |
| 146 | +//… |
| 147 | +public class Startup |
| 148 | +{ |
| 149 | + // ... |
| 150 | + public void ConfigureServices(IServiceCollection services) |
| 151 | + { |
| 152 | + // ... |
| 153 | + services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) |
| 154 | + .AddMicrosoftIdentityWebApp(options => |
| 155 | + { |
| 156 | + Configuration.Bind("AzureAD", options); |
| 157 | + |
| 158 | + // decouple the token lifetime from the Web App |
| 159 | + options.UseTokenLifetime = false; |
| 160 | + |
| 161 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 162 | + options.Events ??= new OpenIdConnectEvents(); |
| 163 | + |
| 164 | + options.Events.OnTokenValidated = async context => |
| 165 | + { |
| 166 | + await onTokenValidated(context); |
| 167 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 168 | + }; |
| 169 | + }); |
| 170 | + // ... |
| 171 | +} |
| 172 | +``` |
| 173 | + |
| 174 | +**If you're implementing your own custom `OpenIdConnectOptions` to configure Microsoft Entra ID authentication:** |
| 175 | + |
| 176 | +```csharp |
| 177 | +services.Configure<OpenIdConnectOptions>(options => |
| 178 | +{ |
| 179 | + //… |
| 180 | + options.Events.OnTokenValidated = async context => |
| 181 | + { |
| 182 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 183 | + }; |
| 184 | +}); |
| 185 | +``` |
| 186 | + |
| 187 | +If you're integrating a Asp.Net Core WS-Fed application, then it might look something like the following: |
| 188 | + |
| 189 | +```csharp |
| 190 | +public void ConfigureServices(IServiceCollection services) |
| 191 | +{ |
| 192 | + services.AddAuthentication(WsFederationDefaults.AuthenticationScheme) |
| 193 | + .AddCookie() |
| 194 | + .AddWsFederation(options => |
| 195 | + { |
| 196 | + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; |
| 197 | + |
| 198 | + // decouple the token lifetime from the Web App |
| 199 | + options.UseTokenLifetime = false; |
| 200 | + |
| 201 | + // MetadataAddress for your Azure Active Directory instance. |
| 202 | + options.MetadataAddress = "https://login.microsoftonline.com/common/federationmetadata/2007-06/federationmetadata.xml"; |
| 203 | + |
| 204 | + // Wtrealm is the app's identifier in the Active Directory instance. |
| 205 | + // For ADFS, use the relying party's identifier, its WS-Federation Passive protocol URL: |
| 206 | + options.Wtrealm = "https://localhost:44307/"; |
| 207 | + |
| 208 | + // For AAD, use the Application ID URI from the app registration's Overview blade: |
| 209 | + options.Wtrealm = "https://contoso.onmicrosoft.com/wsfedapp"; |
| 210 | + |
| 211 | + // Set the Authentication Ticket to expire at a custom time |
| 212 | + var onTokenValidated = options.Events.OnTokenValidated; |
| 213 | + options.Events ??= new OpenIdConnectEvents(); |
| 214 | + |
| 215 | + options.Events.OnSecurityTokenValidated = async context => |
| 216 | + { |
| 217 | + context.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddHours(12); |
| 218 | + } |
| 219 | +``` |
| 220 | +## More information |
| 221 | + |
| 222 | +These settings control the expiration of the authentication ticket, which determines how long a user stays signed in. You can configure this expiration to suit your requirement. |
| 223 | + |
| 224 | +>[!NOTE] |
| 225 | +> If you modify the ticket expiration, users may still have access to your application even if they've been deleted or disabled in Microsoft Entra ID, until the ticket expires. |
| 226 | + |
| 227 | +[!INCLUDE [Azure Help Support](../../../includes/azure-help-support.md)] |
| 228 | + |
0 commit comments