如何在 IdentityServer 中启用滑动过期

LP1*_*P13 5 openid oauth-2.0 openid-connect identityserver3 identityserver4

我正在使用 IdentityServer3 进行身份验证,并且我有 ASP.NET MVC 应用程序作为客户端。我想设置身份验证 cookie 的滑动过期。

因此,只要用户在客户端应用程序中主动做某事,他就应该登录。如果他保持不活动状态(浏览器打开)超过 120 分钟,然后尝试使用客户端应用程序,那么他应该被重定向到登录页面。

在 IdentityServer3IdentityServerOptions和客户端应用程序中CookieAuthenticationOptions,有很多与滑动过期相关的设置OpenIdConnectAuthenticationOptions

在身份服务器上,我有以下配置

app.Map("/identity", idsrvApp =>
            {
                idsrvApp.UseIdentityServer(new IdentityServerOptions
                {
                    SiteName = "Login",
                    SigningCertificate = LoadCertificate(),
                    RequireSsl = true,
                    Factory = new IdentityServerServiceFactory()
                        .Configure(),
                    AuthenticationOptions = new AuthenticationOptions()
                    {
                        CookieOptions = new CookieOptions()
                        {
                            AllowRememberMe = false,
                            SlidingExpiration = true                            
                        }
                    }
                    .Configure(ConfigureIdentityProviders),
                    EventsOptions = new EventsOptions().Configure(),
                    EnableWelcomePage = ApplicationConfig.EnableWelcomePage                    
                });
            });
        }
Run Code Online (Sandbox Code Playgroud)

我已经设置Client.IdentityTokenLifetime7200

在客户端应用程序中,我有以下配置

var cookieOptions = new CookieAuthenticationOptions
            {
                AuthenticationType = "Cookies",
                LoginPath = new Microsoft.Owin.PathString("/Home"),
                SlidingExpiration = true                
            };

var openIdOptions = new OpenIdConnectAuthenticationOptions
            {
                Authority = ConfigurationManager.AppSettings["id:Authority"],
                Scope = "openid email profile",
                ClientId = "XXXXXXXXX",
                RedirectUri = "http://localhost/Home",
                ResponseType = "id_token",
                SignInAsAuthenticationType = "Cookies",
                UseTokenLifetime = true,                
                Notifications = new OpenIdConnectAuthenticationNotifications
                {
                    SecurityTokenValidated = (context) =>
                    {
                         // do something
                    },

                    RedirectToIdentityProvider = (context) =>
                    {
                            // do something
                    },

                    AuthenticationFailed = context =>
                    {
                        // do something
                    }
                }
            };

            app.UseCookieAuthentication(cookieOptions);
            app.UseOpenIdConnectAuthentication(openIdOptions);
Run Code Online (Sandbox Code Playgroud)

请注意,我已设置UseTokenLifetimetruecookie 超时将与Client.IdentityTokenLifetime

问题 即使用户活跃了 120 分钟,他也会在 120 分钟后完全注销。

我还需要做什么才能启用滑动到期?

(我已经在 SO 和 IdentityServer 的论坛上浏览了几篇文章,但没有人给出具体答案)

Scu*_*utt 5

@thunk 让我走上了正确的道路,他的回答基本上是为我解决了这个问题的原因,并让我知道要搜索什么才能获得理解。我只是想“添加到它”,希望它能帮助其他人。

我花了大量时间试图弄清楚这一点,但由于样本和文档中缺乏解释,情况变得更加复杂。如果您阅读IdentityServer3的MVC 入门指南,他们会将这个UseTokenLifetime设置偷偷告诉您(示例代码的一半),而没有提到他们添加了它或它的用途。首先,他们使用以下代码(在您的 MVC 应用程序的 Startup.cs 中):

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = "https://localhost:44319/identity",
    ClientId = "mvc",
    RedirectUri = "https://localhost:44319/",
    ResponseType = "id_token",

    SignInAsAuthenticationType = "Cookies"
});
Run Code Online (Sandbox Code Playgroud)

然后他们偷偷溜进来UseTokenLifetime

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = "https://localhost:44319/identity",

    ClientId = "mvc",
    Scope = "openid profile roles",
    RedirectUri = "https://localhost:44319/",
    ResponseType = "id_token",

    SignInAsAuthenticationType = "Cookies",
    UseTokenLifetime = false,

    // other stuff continues...
});
Run Code Online (Sandbox Code Playgroud)

当我在学习教程并输入我自己的代码时,我错过了UseTokenLifetime = false偷偷摸摸的事情,他们没有提到它已经完成,或者为什么这样做。

这是我发现的一些不错的信息,证实我不是唯一一个有这种困惑的人,并且更好地解释了正在发生的事情

对于后代,我发现最令人困惑的是我可以在我的 cookie 选项中设置一个 cookie 生存期:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
   ...
    ExpireTimeSpan = new TimeSpan(4, 0, 0),
    SlidingExpiration = true,
}); 
Run Code Online (Sandbox Code Playgroud)

但是如果我不知道覆盖 OIDC 默认值,那么 ExpireTimeSpan 将被忽略/覆盖。

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions    
{
    ...
    UseTokenLifetime = false, // have to know to do this for ExpireTimeSpan to be respected
    ...    
}); 
Run Code Online (Sandbox Code Playgroud)

这种行为对我来说似乎非常不透明。不确定它是否可以通过不同的命名或什么来帮助,但在实践中这似乎是一个常见的误解,尽管我不自称了解大多数用例。

作为旁注,该物业MSDNUseTokeLifetime(我什至可以找到有关该物业的任何文档的唯一地方!!!)太可怕了:

指示身份验证会话生命周期(例如 cookie)应与身份验证令牌的生命周期相匹配。如果令牌不提供生命周期信息,则将使用正常的会话生命周期。这是默认启用的。

不知道为什么他们只是不出来说令牌生命周期信息将覆盖正常的会话时间。

所有这一切又回到了我仍然不明白的地方......从我读过的内容来看,cookie 的生命周期与 cookie 中的身份验证票的有效性或到期时间没有任何关系. 换句话说,您不能仅查看 cookie 上的过期时间就知道您的身份验证何时过期。而且我不明白CookieAuthenticationOptionscookie中的设置实际上并没有控制 cookie 的过期时间,它们控制的是嵌入式身份验证票的过期时间。来自这篇博文

.AddCookie(options =>
{
    // Configure the client application to use sliding sessions
    options.SlidingExpiration = true;
    // Expire the session of 15 minutes of inactivity
    options.ExpireTimeSpan = TimeSpan.FromMinutes(15);
})
Run Code Online (Sandbox Code Playgroud)

当我第一次配置它时,我错误地认为这会设置 cookie 本身的到期时间,正如浏览器开发工具中所反映的那样。然而,这实际上是存储在 cookie 中的票证的设置,而不是 cookie 本身的设置。每当处理请求时,MVC 客户端都会评估此票证。此票证确定用户身份验证会话的有效性。

TL; 博士

如果UseTokenLifetime未设置或设置为 true,则只要您的 id_token 有效(默认为 5 分钟),您的身份验证票就会有效。

如果UseTokenLifetime设置为 false,则您的CookieAuthenticationOptions设置将接管,即ExpireTimeSpanSlidingExpiration

无论如何,希望这个答案可以帮助其他人获得启示。


thu*_*unk 1

SlidingExpiration 仅适用于您的 Cookie 中间件。当您使用令牌生命周期时,您此处的任何设置都会被覆盖/忽略。

要使其处于活动状态,UseTokenLifetime 必须设置为 false。到目前为止,我的经验是必须在客户端和IdentityServer上UseTokenLifetime = false;进行设置。openIdOptionsCookieOptions