如何为客户端cookie设置过期日期?

11

我配置了身份验证服务器:

public void Configuration(IAppBuilder app)
{
    var factory = new IdentityServerServiceFactory().UseInMemoryClients(new Client[] {
        new Client()
        {
            ClientName = "MyClient",
            ClientId = "MyClientId",
            Enabled = true,
            Flow = Flows.Implicit,
            RedirectUris = new List<string> { "MyClientServer/callback" },
        };
    });
}

客户端与服务器:

public void Configuration(IAppBuilder app)
{
    var cookieOptions = new CookieAuthenticationOptions();
    cookieOptions.AuthenticationType = "Cookies";
    app.UseCookieAuthentication(cookieOptions);

    var authenticationOptions = new OpenIdConnectAuthenticationOptions() {
        Authority = "https://MyIdentityServer/core",
        ClientId = "MyClientId",
        SignInAsAuthenticationType = "Cookies",
        UseTokenLifetime = true,
        RedirectUri = "MyClientServer/callback"
    });

    app.UseOpenIdConnectAuthentication(authenticationOptions);
}
当用户使用“记住我”选项登录时,身份验证cookie具有过期日期:
idsvr.session    expires 04 October ...

但是客户端 cookie 不会:

.AspNet.Cookies  at end of session

我应该怎么做才能将客户端cookie设置为相同的过期日期?

更新:

我可以在客户端应用程序中设置任何过期日期:

authenticationOptions.Provider = new CookieAuthenticationProvider()
{
    OnResponseSignIn = (context) =>
    {
        var isPersistent = context.Properties.IsPersistent;
        if (isPersistent) // Always false
        {
            context.CookieOptions.Expires = DateTime.UtcNow.AddDays(30);
        }
    }
};

但是我无法确定何时设置过期日期。它应该只在用户选择“记住我”时设置,但是IsPersistent选项始终在客户端上为false。

这个问题也存在于简单的样板项目中: https://identityserver.github.io/Documentation/docsv2/overview/mvcGettingStarted.html

更新2:

我需要客户端cookie是持久的,因为Safari中有一个错误 - https://openradar.appspot.com/14408523

也许存在某些解决方法,所以我可以通过从Identity到Client的回调中传递过期日期来解决吗?

更新3:

实际上,我们的Identity和Client服务器具有相同的父域,例如app.server.localid.server.local。也许我可以通过属于父域(.server.local)的附加cookie传递过期日期?但我不知道在Identity上它可以写在哪里,在Client上可以应用在哪里。


1
寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括期望的行为,一个具体的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建一个最小、完整和可验证的示例。 - Noctis Skytower
.Provider是cookieOptions的属性,而不是authenticationOptions的属性。 - dstr
3个回答

3
由IdentityServer发出的cookie和客户端应用程序发出的cookie没有任何联系。IdentityServer无法控制客户端应用程序中的cookie。
当您登录IdentityServer时,会发出一个cookie,用于在IdentityServer中跟踪已验证的用户。这样可以使用户在每个客户端应用程序中都无需输入凭据,从而实现单点登录。
默认情况下,此cookie仅持续该会话(因此在浏览器关闭时过期),否则如果您设置“记住我”,它将在一定数量的天数内持续,跨会话。
客户端应用程序中的cookie将在成功验证来自IdentityServer的身份令牌后发出。此cookie可以具有任何到期时间、任何策略和任何名称。它完全由客户端应用程序控制。在您的情况下,客户端cookie到期时间可以在客户端应用程序中的CookieAuthenticationOptions中设置。

没有相应的机制可以实现这个。这需要进行定制实现,超出规范范围。顺便问一下,为什么需要持久化客户端 cookie? - Scott Brady
Safari浏览器存在一个错误 - http://openradar.appspot.com/14408523,因此我需要一个持久的cookie来解决问题。 - Artem
请说明一下,在您的IdentityServer代码中,“UseCookieAuthentication”中间件的目的是什么? - Scott Brady
我认为如果您更改cookie的名称(不要同时使用“Cookies”的AuthenticationType),并更新您所期望的问题,事情可能会变得更加清晰。我询问了IdentityServer应用程序中的UseCookieAuthentication中间件,因为它不需要存在于IdentityServer中才能工作。IdentityServer会发出自己的cookie,不需要额外的中间件。 - Scott Brady
我从身份验证中删除了UseCookieAuthentication并更新了我的问题。 - Artem
显示剩余2条评论

1
你需要处理cookie授权事件。OpenID中间件只是创建了一个授权cookie,因此你可以从这些事件中处理此cookie的所有方面。你需要查看事件,并进行一些试错,就可以管理cookie的生命周期。

如果用户选中“记住我”,那么我可以在哪个事件中设置 Cookie 的过期日期? - Artem

1

您可以在javascript中使用以下代码来实现,我在这里创建了一个cookie,使其在14天内过期。

var exdate = new Date();
exdate.setDate(exdate.getDate() + 14);

document.cookie = "yourcookie=" + yourCookieValue + ";expires=" + exdate.toUTCString() + ";";

1
客户端和身份验证的Cookie是httpOnly的,出于安全考虑。 - Artem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接