Identityserver4 令牌到期时强制登录页面

Identityserver4 令牌到期时强制登录页面,identityserver4,asp.net-identity-2,Identityserver4,Asp.net Identity 2,我正试图强制使用ASP.Net标识的Identity Server 4(V2.1.1)在一段时间后重定向到登录页面。我已将每个令牌生存期/超时时间设置为1分钟,即使考虑到5分钟的偏差,Identity Server也会自动对用户进行重新身份验证(即不需要登录页面) 这是相关的代码 IdentityServer Startup.cs: services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFramewor

我正试图强制使用ASP.Net标识的Identity Server 4(V2.1.1)在一段时间后重定向到登录页面。我已将每个令牌生存期/超时时间设置为1分钟,即使考虑到5分钟的偏差,Identity Server也会自动对用户进行重新身份验证(即不需要登录页面)

这是相关的代码

IdentityServer Startup.cs:

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

services.AddIdentityServer(options =>
                                   {
                                       options.Authentication.CookieLifetime = TimeSpan.FromSeconds(60);
                                       options.Authentication.CookieSlidingExpiration = false;
                                   })
        .AddSigningCredential(certificate)
        .AddInMemoryClients(Clients.GetClients())
        .AddInMemoryApiResources(Resources.GetApiResources())
        .AddInMemoryIdentityResources(Resources.GetIdentityResources())
        .AddAspNetIdentity<ApplicationUser>()
        .AddJwtBearerClientAuthentication();
Web窗体客户端中间件层:

public void AuthSetup(IAppBuilder app)
{
    // Use Cookies to Store JWT Token for Web Browsers
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
        ExpireTimeSpan = TimeSpan.FromMinutes(1),
        SlidingExpiration = true
    });

    JwtSecurityTokenHandler.InboundClaimTypeMap.Clear();

    // Authenticate to Auth Server
    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        AuthenticationType = "oidc",
        SignInAsAuthenticationType = "Cookies",
        Authority = "http://localhost:5002/",
        ClientId = "client",
        RedirectUri = "http://localhost:8888/",
        PostLogoutRedirectUri = "http://localhost:8888/",
        ResponseType = "code id_token token",
        Scope = "openid profile AuthApi",
        UseTokenLifetime = false,
        Notifications = new OpenIdConnectAuthenticationNotifications
        {
            SecurityTokenValidated = async n =>
            {
                var claimsToExclude = new[] { "aud", "iss", "nbf", "exp", "nonce", "iat", "at_hash", "c_hash", "idp", "amr" };

                var claimsToKeep = n.AuthenticationTicket.Identity.Claims.Where(x => false == claimsToExclude.Contains(x.Type)).ToList();
                claimsToKeep.Add(new Claim("id_token", n.ProtocolMessage.IdToken));

                if (n.ProtocolMessage.AccessToken != null)
                {
                    // Add access_token so we don't need to request it when calling APIs
                    claimsToKeep.Add(new Claim("access_token", n.ProtocolMessage.AccessToken));

                    var userInfoClient = new UserInfoClient(new Uri(n.Options.Authority + "connect/userinfo").ToString());
                    var userInfoResponse = await userInfoClient.GetAsync(n.ProtocolMessage.AccessToken);
                    var userInfoClaims = userInfoResponse.Claims
                        .Where(x => x.Type != "sub") // filter sub since we're already getting it from id_token
                        .Select(x => new Claim(x.Type, x.Value));
                    claimsToKeep.AddRange(userInfoClaims);
                }

                var ci = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType, "name", "role");
                ci.AddClaims(claimsToKeep);

                n.AuthenticationTicket = new AuthenticationTicket(ci, n.AuthenticationTicket.Properties);
            },
            RedirectToIdentityProvider = n =>
            {
                if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
                    n.ProtocolMessage.IdTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token")?.Value;

                return Task.FromResult(0);
            }
        }
    });

    app.UseStageMarker(PipelineStage.Authenticate);
}

我还缺少什么其他设置来强制服务器要求用户在令牌过期后登录?

Identity server创建自己的身份验证cookie“idsrv”,默认情况下该cookie具有。在10小时内,它将自动重新验证您的身份。要更改此默认值,您可以在配置Identity Server时更改
CookieLifetime
属性,例如:

services.AddIdentityServer(options =>
            {
                options.Authentication.CookieLifetime = TimeSpan.FromSeconds(60);
            })
        .AddSigningCredential(certificate)
        .AddInMemoryClients(Clients.GetClients())
        .AddInMemoryApiResources(Resources.GetApiResources())
        .AddInMemoryIdentityResources(Resources.GetIdentityResources())
        .AddAspNetIdentity<ApplicationUser>()
        .AddJwtBearerClientAuthentication();
services.AddIdentityServer(选项=>
{
options.Authentication.CookieLifetime=TimeSpan.FromSeconds(60);
})
.AddSigningCredential(证书)
.AddInMemoryClients(Clients.GetClients())
.AddInMemoryApiResources(Resources.GetApiResources())
.AddInMemoryIdentityResources(Resources.GetIdentityResources())
.AddAsNetIdentity()
.AddJwtBearerClientAuthentication();

而且,在您的WebForms客户端
OpenIdConnectAuthenticationOptions
中,您可能希望将
UseTokenLifetime
属性设置为
true

我进行了这两项更改,并设置了CookieSlidingExpiration=false,它仍在创建一个新的令牌,而不强制重新登录。如果您不使用ASP.Net Identity withIdentityServer4的2.1.1版。我将这个答案标记为未来用户的答案,因为它是一个答案。谢谢你,加文!Gavin,这与调用
SignInAsync
内部
ExternalLoginCallback
@VictoriaLoberra时设置
AuthenticationProperties.ExpiresUtc
相同吗。我不确定是否诚实,因为我没有太多地使用外部提供者。表示它“获取或设置身份验证票证过期的时间”。听起来似乎有道理。ASP.Net Identity 2.1.1和Identity Server 4的组合是什么导致此解决方案不起作用的?我遇到了完全相同的问题,正在寻找修复/解决方法。。。
services.AddIdentityServer(options =>
            {
                options.Authentication.CookieLifetime = TimeSpan.FromSeconds(60);
            })
        .AddSigningCredential(certificate)
        .AddInMemoryClients(Clients.GetClients())
        .AddInMemoryApiResources(Resources.GetApiResources())
        .AddInMemoryIdentityResources(Resources.GetIdentityResources())
        .AddAspNetIdentity<ApplicationUser>()
        .AddJwtBearerClientAuthentication();