I have been using Identity Framework packages in my ASP.Net Core Web API Project(.Net8). I have the following setup:
On the Program.cs:
//The AddIdentityApiEndpoints add the authentication itself so i don't need to declare it. The problem is I don't have any way to control the Token
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("GeneralAccess", policy =>
policy.RequireAssertion(context =>
context.User.IsInRole("Admin") ||
context.User.IsInRole("User")));
});
//Setup Database Context
builder.Services.AddDbContext<DemoSecurityDbContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("SecurityConnection")));
//This will add the API endpoints for the Identity DB
builder.Services
.AddIdentityApiEndpoints<DemoUser>(options => options.SignIn.RequireConfirmedAccount = true)
//.AddIdentity<DemoUser, DemoIdentityRoles>()
.AddRoles<DemoIdentityRoles>()
.AddEntityFrameworkStores<DemoSecurityDbContext>();
app.MapGroup("/account").MapIdentityApi<DemoUser>();
I have been digging around the MapIdentityApi and the SignManager to understand how can I change the Token expiry date, at the moment is set to 3600 but I can’t find an easy way to overwrite this value.
I can’t see where the token is generated in the code and 3600 is too much
{
“tokenType”: “Bearer”,
“accessToken”: ““,
“expiresIn”: 3600,
“refreshToken”: “”
}
I have been looking across all the visible code.
I have been searching on the web but no one has raised this question.
Ideally I would like a simple answer where I can use the built in code from the Indentity Framework API ./Account/Login endpoint.
Here is the code from from the AddIdentityApiEndpoints it doesn’t look I have any control on the token
public static IdentityBuilder AddIdentityApiEndpoints<TUser>(this IServiceCollection services, Action<IdentityOptions> configure)
where TUser : class, new()
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(configure);
services
.AddAuthentication(IdentityConstants.BearerAndApplicationScheme)
.AddScheme<AuthenticationSchemeOptions, CompositeIdentityHandler>(IdentityConstants.BearerAndApplicationScheme, null, compositeOptions =>
{
compositeOptions.ForwardDefault = IdentityConstants.BearerScheme;
compositeOptions.ForwardAuthenticate = IdentityConstants.BearerAndApplicationScheme;
})
.AddBearerToken(IdentityConstants.BearerScheme)
.AddIdentityCookies();
return services.AddIdentityCore<TUser>(configure)
.AddApiEndpoints();
}
To change the token expiry duration in ASP.NET Core Identity JWT tokens, you can modify the TokenValidationParameters when configuring JWT authentication. In your Program.cs, where you configure authentication using JWT bearer, you can adjust the TokenValidationParameters as follows:
builder.Services.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])),
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero, // Remove the clock skew
ValidateIssuer = false,
ValidateAudience = false,
};
});
setting ClockSkew to TimeSpan.Zero, you effectively disable the clock skew, meaning the token will expire strictly according to the exp claim value in the token payload.
Now, to set the token expiration time explicitly, you can do it while generating the token. If you’re using SignInManager to generate tokens, you can specify the expiration time there. Here’s how you can do it:
var signInResult = await _signInManager.PasswordSignInAsync(user, password, rememberMe, lockoutOnFailure: true);
if (signInResult.Succeeded)
{
// Generate token
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
// Add other claims as needed
}),
Expires = DateTime.UtcNow.AddMinutes(60), // Set the expiration time here
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"])), SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return Ok(new
{
tokenType = "Bearer",
accessToken = tokenHandler.WriteToken(token),
expiresIn = 3600, // This value will be overwritten by the expiration time set in tokenDescriptor
refreshToken = ""
});
}
1
Add the below to your Program.cs
builder.Services.AddAuthentication().AddBearerToken(IdentityConstants.BearerScheme,
o =>
{
o.BearerTokenExpiration = TimeSpan.FromSeconds(60);
}
5