代码之家  ›  专栏  ›  技术社区  ›  Jeff Keslinke

令牌到期时强制登录页面

  •  1
  • Jeff Keslinke  · 技术社区  · 8 年前

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

    以下是相关代码

    IdentityServer启动。反恐精英:

    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();
    

    配置。GetGlients():

    // WebForms Client
    new Client
    {
        ...
        AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
        AllowAccessTokensViaBrowser = true,
        AuthorizationCodeLifetime = 60,
        AccessTokenLifetime = 60,
        IdentityTokenLifetime = 60,
        RefreshTokenExpiration = TokenExpiration.Absolute,
        AbsoluteRefreshTokenLifetime = 60,
        SlidingRefreshTokenLifetime = 60
    },
    

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

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

    1 回复  |  直到 8 年前
        1
  •  2
  •   Gavin Sutherland    8 年前

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

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

    此外,在WebForms客户端中 OpenIdConnectAuthenticationOptions 您可能需要设置 UseTokenLifetime 属性到 true .