简体   繁体   English

身份服务器 4 - 空闲时注销用户

[英]Identity Server 4 - Log User Out when Idle

Hej Community, Hej社区,

I got stuck and I need some advice or pointer to a solution.我被卡住了,我需要一些建议或指向解决方案的指针。 I have a fairly simple Identity Server 4 Setup:我有一个相当简单的 Identity Server 4 设置:

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

I would like to automatically log out the user after 10 minutes of inactivity.我想在 10 分钟不活动后自动注销用户。 In the sample below I used 10 s to make testing somewhat quicker.在下面的示例中,我使用了 10 秒来加快测试速度。 The authentication, redirect and user enforced logout work as expected and like a charm using the code below.身份验证、重定向和用户强制注销按预期工作,就像使用下面的代码一样。 However, when the user idles for longer than the set 10 s, the user is still signed in and is not redirected to the login page at the IDS host.但是,当用户空闲时间超过设定的 10 s 时,用户仍处于登录状态,不会重定向到 IDS 主机上的登录页面。

The MVC client is setup using Hybrid Grant as: MVC 客户端使用 Hybrid Grant 设置为:

Client Definition客户定义

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,
    },
};

Identity Server Options身份服务器选项

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

In the Startup of the MVC client I add:在 MVC 客户端的启动中,我添加:

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

and added app.UseAuthentication() in the Configure method.并在Configure方法中添加了app.UseAuthentication()

Question

How can I make sure that the user is signed out at the Identity Server once the session timed out?一旦会话超时,如何确保用户在 Identity Server 上注销? Any hint and help appreciated!任何提示和帮助表示赞赏!

After more debugging I found that the cookie lifetime of the MVC client worked as intended with a sliding expiration.经过更多调试后,我发现 MVC 客户端的 cookie 生存期按预期工作,并具有滑动到期时间。 However, once the cookie expired, the Idenity Server (IDS) was contacted and the cookie was refreshed as the session was still alive / active at the IDS.但是,一旦 cookie 过期,就会联系身份服务器 (IDS) 并刷新 cookie,因为会话在 IDS 上仍然处于活动状态/活动状态。

I figured two solutions from which I decided to use Solution 1 for now and see if it is the most suitable in the long-run.我想出了两个解决方案,我决定暂时使用解决方案 1 ,看看它是否最适合长期使用。

If anyone has a comment or recommendation towards security and best practice please comment or post another solution.如果有人对安全性和最佳实践有意见或建议,请发表评论或发布其他解决方案。

Solution 1: Maximum SSO lifetime of client解决方案 1:客户端的最长 SSO 生命周期

The Client property UserSsoLifetime (available in Identity Server 4 from v2.3 ) can be used to set the maximum time until a user must re-authenticate to use the client.客户端属性UserSsoLifetime (在v2.3 Identity Server 4 中可用)可用于设置用户必须重新进行身份验证才能使用客户端的最长时间。 So for the sample of the question the only required addition is in the Client Definition by adding UserSsoLifetime = 10 , such as,因此,对于问题的示例,唯一需要的添加是通过添加UserSsoLifetime = 10客户端定义中,例如,

Client Definition客户定义

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,
    },
};

This will force the user to re-authenticate after 10 s of inactivity.这将强制用户在 10 秒不活动后重新进行身份验证。

Solution 2: OIDC Property解决方案 2:OIDC 财产

This SO question solves the issue with an OIDC property which can be used to force the user to re-authenticate via the login prompt once the session expired - see @Scotty Brady's answer .这个SO 问题解决了 OIDC 属性的问题,该属性可用于在会话过期后强制用户通过登录提示重新进行身份验证 - 请参阅@Scotty Brady 的回答

So for the example denoted in the question should look like the following.因此,问题中表示的示例应如下所示。 Note that only the MVC client needs changes, namely the Cookie lifetime was removed and OIDC options were added forcing the re-authentication and to use the token lifetime from IDS (each line marked with a // <- HERE ).请注意,只有 MVC 客户端需要更改,即删除了 Cookie 生存期,并添加了 OIDC 选项以强制重新身份验证并使用来自 IDS 的令牌生存期(每行标有// <- HERE )。 This way, the cookie settings from IDS are used (sliding lifetime of 10s).这样,就使用了来自 IDS 的 cookie 设置(滑动寿命为 10 秒)。

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

You can utilize End Session Endpoint of the IdentityServer.您可以使用 IdentityServer 的End Session Endpoint

The end session endpoint can be used to trigger single sign-out ( see spec ).结束会话端点可用于触发单点注销( 请参阅规范)。

To use the end session endpoint a client application will redirect the user's browser to the end session URL.要使用结束会话端点,客户端应用程序会将用户的浏览器重定向到结束会话 URL。 All applications that the user has logged into via the browser during the user's session can participate in the sign-out.用户在会话期间通过浏览器登录的所有应用程序都可以参与注销。

You can utilize this endpoint to redirect end user back to login page using post_logout_redirect_uri paramter.您可以利用此端点使用post_logout_redirect_uri参数将最终用户重定向回登录页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用身份服务器时如何注销? - How do I log out when using identity server? 在Identity Server 4中,是否可以注销一个用户在所有应用程序中注销的应用程序日志? - In Identity Server 4, is it possible to make logging out of one application log that user out in all applications? 为什么我的asp.net身份-user会自动注销 - Why my asp.net identity -user will log out automatically 身份服务器4和用户权限 - Identity server 4 and user permissions 用户未通过身份验证服务器 4 - User is not authenticated identity server 4 检测空闲状态并注销用户(WinForms) - Detecting Idle status and Logging user out (WinForms) 用户注销后如何使 AspNetCore.Identity.Application Cookie 无效 - How to Invalidate AspNetCore.Identity.Application Cookie after user log out ASP.NET身份,立即将另一个用户添加到角色(他们不必再次注销) - ASP.NET Identity, add another user to role instantly (they don't have to log out and in again) 当用户注销或计算机空闲时,是否可以在计算机上运行桌面自动化控制台应用程序? - Is there any way to run a desktop automation console application on a machine when the user is logged out or the machine is in idle.? 如何在注销后终止在服务器上运行的所有用户线程? - How to terminate all user threads running on server after log out?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM