如何更改“ .AspNetCore.Identity.Application” cookie的有效期?

时间:2019-10-03 15:10:08

标签: authentication asp.net-core asp.net-identity identityserver4 openid-connect

我正在将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);
});

4 个答案:

答案 0 :(得分:2)

在通过AspNetCore 3.1IdentityServer 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);
}