首页 > 解决方案 > Identity Server 4 - 空闲时注销用户

问题描述

Hej 社区,

我被卡住了,我需要一些建议或指向解决方案的指针。我有一个相当简单的 Identity Server 4 设置:

  1. 带有 ASP.NET 身份的身份服务器 4
  2. ASP.NET Core 2.2 MVC 客户端

我想在 10 分钟不活动后自动注销用户。在下面的示例中,我使用了 10 秒来加快测试速度。身份验证、重定向和用户强制注销按预期工作,就像使用下面的代码的魅力一样。但是,当用户空闲时间超过设置的 10 秒时,用户仍然登录,并且不会重定向到 IDS 主机的登录页面。

MVC 客户端使用 Hybrid Grant 设置为:

客户定义

var mvcClient = new Client
{
    ClientId = "account-mvc",
    ClientName = "Account MVC",
    ClientUri = "https://localhost:5002",

    AllowedGrantTypes = GrantTypes.Hybrid,
    ClientSecrets = { new Secret("secret".Sha256()) },

    EnableLocalLogin = true,
    RequireConsent = false,
    AllowOfflineAccess = false,
    AccessTokenLifetime = 10,   // 10 s by intention
    IdentityTokenLifetime = 10, // 10 s by intention

    RedirectUris = "https://localhost:5002/signin-oidc",
    PostLogoutRedirectUris = "https://localhost:5002/signout-callback-oidc",
    FrontChannelLogoutUri = "https://localhost:5002/signout-oidc",

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,
    },
};

身份服务器选项

services.AddIdentityServer(options =>
{
    options.Authentication.CheckSessionCookieName = "auth-cookie";
    options.Authentication.CookieLifetime = new System.TimeSpan(0, 0, 10);
    options.Authentication.CookieSlidingExpiration = false;

    options.Csp.Level = IdentityServer4.Models.CspLevel.Two;

    options.Events.RaiseErrorEvents = true;
    options.Events.RaiseInformationEvents = true;
    options.Events.RaiseFailureEvents = true;
    options.Events.RaiseSuccessEvents = true;
})
.Add... // Left out for brevity

在 MVC 客户端的启动中,我添加:

MVC 客户端启动

services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie("Cookies", options => 
        {
            options.ExpireTimeSpan = TimeSpan.FromSeconds(10);
            options.SlidingExpiration = false;
            options.Cookie.Name = "mvc-cookie";
        })
        .AddOpenIdConnect("oidc", options =>
        {
            options.SignInScheme = "Cookies";

            options.Authority = "https://localhost:5001/";
            options.ClientId = "account-mvc";
            options.ClientSecret = "secret";
            options.ResponseType = "code id_token";

            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;

            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.Scope.Add("email");
        });

app.UseAuthentication()Configure方法中添加。

问题

会话超时后,如何确保用户在身份服务器上注销?任何提示和帮助表示赞赏!

标签: c#asp.net-core.net-coreidentityserver4openid-connect

解决方案


经过更多调试后,我发现 MVC 客户端的 cookie 生命周期按预期工作,具有滑动过期时间。但是,一旦 cookie 过期,就会联系身份服务器 (IDS) 并刷新 cookie,因为会话在 IDS 上仍然处于活动状态/活动状态。

我想出了两个解决方案,我决定暂时使用解决方案 1,看看它是否从长远来看是最合适的。

如果有人对安全性和最佳实践有意见或建议,请发表评论或发布其他解决方案。

解决方案 1:客户端的最长 SSO 生命周期

Client 属性UserSsoLifetime(在 Identity Server 4 中可用v2.3)可用于设置用户必须重新进行身份验证才能使用客户端的最长时间。因此,对于问题示例,唯一需要添加的是在客户端定义中添加UserSsoLifetime = 10,例如,

客户定义

var mvcClient = new Client
{
    ClientId = "account-mvc",
    ClientName = "Account MVC",
    ClientUri = "https://localhost:5002",

    AllowedGrantTypes = GrantTypes.Hybrid,
    ClientSecrets = { new Secret("secret".Sha256()) },

    EnableLocalLogin = true,
    RequireConsent = false,
    AllowOfflineAccess = false,
    UserSsoLifetime = 10,       // <- HERE
    AccessTokenLifetime = 10,   // 10 s by intention
    IdentityTokenLifetime = 10, // 10 s by intention

    RedirectUris = "https://localhost:5002/signin-oidc",
    PostLogoutRedirectUris = "https://localhost:5002/signout-callback-oidc",
    FrontChannelLogoutUri = "https://localhost:5002/signout-oidc",

    AllowedScopes =
    {
        IdentityServerConstants.StandardScopes.OpenId,
        IdentityServerConstants.StandardScopes.Profile,
        IdentityServerConstants.StandardScopes.Email,
    },
};

这将强制用户在 10 秒不活动后重新进行身份验证。

解决方案 2:OIDC 属性

这个SO question解决了 OIDC 属性的问题,该属性可用于在会话过期后强制用户通过登录提示重新进行身份验证 - 请参阅@Scotty Brady 的回答

因此,对于问题中表示的示例,应如下所示。请注意,只有 MVC 客户端需要更改,即删除了 Cookie 生命周期并添加了 OIDC 选项以强制重新身份验证并使用来自 IDS 的令牌生命周期(每行标有// <- HERE)。这样,就使用了来自 IDS 的 cookie 设置(滑动寿命为 10 秒)。

MVC 客户端启动

services.AddAuthentication(options =>
        {
            options.DefaultScheme = "Cookies";
            options.DefaultChallengeScheme = "oidc";
        })
        .AddCookie("Cookies") // <- HERE
        .AddOpenIdConnect("oidc", options =>
        {
            options.SignInScheme = "Cookies";

            options.Authority = "https://localhost:5001/";
            options.ClientId = "account-mvc";
            options.ClientSecret = "secret";
            options.ResponseType = "code id_token";

            options.UseTokenLifetime = true; // <- HERE
            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;

            options.Events.OnRedirectToIdentityProvider = context => // <- HERE
            {                                                        // <- HERE
                context.ProtocolMessage.Prompt = "login";            // <- HERE
                return Task.CompletedTask;                           // <- HERE
            };                                                       // <- HERE

            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.Scope.Add("email");
        });

推荐阅读