我正在将ASP.NET Core与Identity Server和Open Id Connect结合使用,如here所述。设置“记住我”选项时(默认为14天),我需要更改身份验证Cookie的过期时间。我可以看到名为“ .AspNetCore.Identity.Application”的cookie对此负责。我正在尝试这样设置到期时间:
.AddCookie(options =>
{
options.Cookie.Expiration = TimeSpan.FromDays(1);
options.ExpireTimeSpan = TimeSpan.FromDays(1);
})
但是它会影响另一个名为“ .AspNetCore.Cookies”的cookie(包含相同的令牌值),该cookie具有Session到期时间,并且似乎没有任何作用。我发现的所有更改到期日的方法都只能修改“ .AspNetCore.Cookies” cookie,找不到任何方法可以修改“ .AspNetCore.Identity.Application” cookie。 (顺便说一句,由于某种原因我完全没有触发services.ConfigureApplicationCookie
方法。
任何人都可以解释这两个cookie之间的区别是什么,如何修改“ .AspNetCore.Identity.Application”的有效期?
我在Startup.ConfigureServices
中的代码
services.AddMvc(options =>
{
// ...
})
services.AddAuthorization(options =>
{
options.AddPolicy(PolicyNames.UserPolicy, policyBuilder =>
{
// ...
});
});
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = "oidc";
})
.AddCookie(options =>
{
options.AccessDeniedPath = "/AccessDenied";
options.SlidingExpiration = true;
})
.AddOpenIdConnect("oidc", options =>
{
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.Authority = "<authority>";
options.RequireHttpsMetadata = false;
options.ClientId = "<id>";
options.ClientSecret = "<secret>";
options.ResponseType = "code id_token";
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
// ...
});
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "MyCookie";
options.Cookie.Expiration = TimeSpan.FromDays(1);
options.ExpireTimeSpan = TimeSpan.FromDays(1);
});
答案 0 :(得分:2)
在通过AspNetCore 3.1
和IdentityServer 4.0.4
的仓库进行加扰之后,
我找到了设置默认身份验证Cookie选项的工作方法。
TD; LR:
// in Startup.ConfigureService(IServiceCollection services)
services.PostConfigure<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme, option =>
{
option.Cookie.Name = "Hello"; // change cookie name
option.ExpireTimeSpan = TimeSpan.FromSeconds(30); // change cookie expire time span
});
完整设置:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
// cookie policy to deal with temporary browser incompatibilities
services.AddSameSiteCookiePolicy();
services.AddDefaultAllowAllCors();
// setting up dbcontext for stores;
services.AddDbContext<ApplicationDbContext>(ConfigureDbContext);
services
.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
// read clients from https://stackoverflow.com/a/54892390/4927172
var builder = services.AddIdentityServer(options =>
{
options.Events.RaiseSuccessEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.UserInteraction.LoginUrl = "/identity/account/login";
options.IssuerUri = _configuration.GetValue<string>("IdentityServer:IssuerUri");
})
.AddAspNetIdentity<ApplicationUser>()
.AddDeveloperSigningCredential()
.AddConfigurationStore<ApplicationConfigurationDbContext>(option => option.ConfigureDbContext = ConfigureDbContext)
.AddOperationalStore<ApplicationPersistedGrantDbContext>(option => { option.ConfigureDbContext = ConfigureDbContext; })
.AddJwtBearerClientAuthentication()
.AddProfileService<ApplicationUserProfileService>();
services.PostConfigure<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme, option =>
{
option.Cookie.Name = "Hello";
option.ExpireTimeSpan = TimeSpan.FromSeconds(30);
});
services.AddScoped<Microsoft.AspNetCore.Identity.UI.Services.IEmailSender, EmailSender>();
services.Configure<SmsOption>(_configuration);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// use this for persisted grants store
InitializeDatabase(app);
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseDefaultAllowAllCors();
app.UseStaticFiles();
app.UseRouting();
app.UseIdentityServer();
app.UseAuthorization();
app.UseStatusCodePages(async context =>
{
var response = context.HttpContext.Response;
if (response.StatusCode == StatusCodes.Status401Unauthorized ||
response.StatusCode == StatusCodes.Status403Forbidden)
response.Redirect("/identity/account/login");
if (context.HttpContext.Request.Method == "Get" && response.StatusCode == StatusCodes.Status404NotFound)
{
response.Redirect("/index");
}
});
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapRazorPages();
});
}
答案 1 :(得分:1)
正如柯克·拉金(Kirk Larkin)所说,“。AspNetCore.Identity.Application” cookie可能是由使用Asp.Net Identity的Identity Server应用程序设置的。 因此,如果要在IS4应用程序上管理用户会话,则需要在其中进行配置。
IS4应用程序:“。AspNetCore.Identity.Application” cookie。
如果您使用身份将cookie配置为持久性,则需要在登录用户时设置有效期。
var props = new AuthenticationProperties {
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.Add(AccountOptions.RememberMeLoginDuration)
};
await HttpContext.SignInAsync(userId, userName, props);
如果您未设置IsPersistent=true
,则cookie具有会话生存期,您可以设置包含的身份验证凭单的到期时间,如下所示:
.AddCookie(options => {
options.Cookie.Name = "idsrv_identity";
options.ExpireTimeSpan = TimeSpan.FromHours(8);
options.SlidingExpiration = true;
});
您的客户端应用程序::“。AspNetCore.Cookies” cookie。
services.ConfigureApplicationCookie
不会被调用,因为如果您使用.AddCookie(...)
会优先。选项是相同的。
这会将应用程序cookie设置为 session 。
.AddCookie(options => {
options.Cookie.Name = "myappcookie";
options.ExpireTimeSpan = TimeSpan.FromHours(8);
options.SlidingExpiration = true;
});
使用OIDC保持应用cookie持久的一种方法是在 AddCookie 中的OnSigningIn
事件中设置过期时间。
options.Events.OnSigningIn = (context) =>
{
context.CookieOptions.Expires = DateTimeOffset.UtcNow.AddDays(30);
return Task.CompletedTask;
};
关于用户会话的注释。
每种情况都不同,因此没有最佳解决方案,但是请记住,您必须照顾两个用户会话。一个在IS4应用程序上,另一个在您的客户端应用程序上。这些可能不同步。您需要考虑客户端应用程序上的持久性用户会话是否有意义。您不希望在中央SSO(单点登录)会话期满后用户仍然登录到客户端应用程序中。
答案 2 :(得分:1)
在services.AddAuthentication
之前添加这一行是最终对IS4来说对我有用的方法,取自this github issue:
services.ConfigureApplicationCookie(x =>
{
x.ExpireTimeSpan = TimeSpan.FromDays(1);
});
答案 3 :(得分:0)
我遵循了Github aspnetcore来源的示例AuthSamples.Cookies
。
public void ConfigureServices(IServiceCollection services)
{
...
// Example of how to customize a particular instance of cookie options and
// is able to also use other services.
services.AddSingleton<IConfigureOptions<CookieAuthenticationOptions>, ConfigureMyCookie>();
}
internal class ConfigureMyCookie : IConfigureNamedOptions<CookieAuthenticationOptions>
{
// You can inject services here
public ConfigureMyCookie()
{
}
public void Configure(string name, CookieAuthenticationOptions options)
{
// Identityserver comes with two cookies:
// Identity.Application
// Identity.External
// you can change the options here
{
options.ExpireTimeSpan = TimeSpan.FromHours(8);
}
}
public void Configure(CookieAuthenticationOptions options)
=> Configure(Options.DefaultName, options);
}