Identity Server 4 - 当用户空闲时注销用户

5

大家好,我需要一些建议或指针来解决问题。我有一个非常简单的Identity Server 4设置:

  1. 使用ASP.NET Identity的Identity Server 4
  2. ASP.NET Core 2.2 MVC客户端

我想在用户停止活动10分钟后自动注销。在下面的示例中,我使用了10秒钟来加速测试。身份验证、重定向和用户强制注销使用下面的代码可以正常工作。但是,当用户空闲时间超过设定的10秒时,用户仍然登录,并且没有被重定向到IDS主机的登录页面。

MVC客户端使用混合授权进行设置:

客户端定义

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");
        });

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

问题

如何确保用户在会话超时后在身份验证服务器上注销?任何提示和帮助都将不胜感激!


请查看此答案 - https://dev59.com/Wanka4cB1Zd3GeqPV-2G?noredirect=1&lq=1 - Kavindu Dodanduwa
2个回答

8

经过更多的调试,我发现MVC客户端的cookie生命周期在滑动过期方面起到了预期的作用。但是,一旦cookie过期,就会联系Identity Server(IDS),并且在IDS仍然处于活动/活跃状态时刷新cookie。

我考虑了两个解决方案,最终选择了解决方案1,并希望在长期运行中它是最合适的。

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

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

Client属性UserSsoLifetime(从v2.3开始在Identity Server 4中可用)可用于设置用户必须重新验证以使用客户端的最长时间。因此,对于问题样例,唯一需要添加的内容是在客户端定义中添加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问题通过一个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");
        });

你说这是从版本2.3可用。这是否意味着它可以在身份服务器2.0中使用? - LOKI
抱歉可能不太清楚,但这都与Identity Server 4有关,我指的是v4.2.3。我编辑了答案以避免混淆。请参见Identity Server 4文档 - 在Authentication/Logout部分中的最后一项。 - mmr

1
您可以利用IdentityServer的End Session Endpoint

该端点可用于触发单点注销(请参阅规范)。

要使用终止会话端点,客户端应用程序将重定向用户的浏览器到终止会话 URL。用户在会话期间通过浏览器登录的所有应用程序都可以参与注销。

您可以利用此端点使用 post_logout_redirect_uri 参数将最终用户重定向回登录页。

1
谢谢您的提示。我已经想出了如何解决这个问题,并将在另一个答案中记录下来。 - mmr

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