如何在asp.net核心中处理cookie过期

时间:2016-08-11 07:39:33

标签: asp.net-mvc asp.net-core asp.net-identity asp.net-core-mvc

我想知道如何正确处理Cookie过期的事实?是否可以执行自定义操作?

我想要实现的是,当cookie过期时,从当前cookie中取出一些信息,通过此信息重定向到动作参数。有可能吗?

3 个答案:

答案 0 :(得分:2)

在设置cokies auth中间件时,您似乎需要自己的OnValidatePrincipal事件处理程序:

  

OnValidatePrincipal 事件可用于拦截和覆盖cookie身份验证

app.UseCookieAuthentication(options =>
{
    options.Events = new CookieAuthenticationEvents
    {
        OnValidatePrincipal = <your event handler>
    };
});

Documentation包含此类句柄的示例:

public static class LastChangedValidator
{
    public static async Task ValidateAsync(CookieValidatePrincipalContext context)
    {
        // Pull database from registered DI services.
        var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
        var userPrincipal = context.Principal;

        // Look for the last changed claim.
        string lastChanged;
        lastChanged = (from c in userPrincipal.Claims
                       where c.Type == "LastUpdated"
                       select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
        {
            context.RejectPrincipal();
            await context.HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");
        }
    }
}

答案 1 :(得分:1)

没有一种好方法可以实现这一目标。如果cookie过期,则不会将其发送到服务器以提取任何信息。使用ASP.Net Core Identity,您无法控制它。这让你使用Cookie中间件。

这为用户提供了cookie过期时的正常重定向:

public void ConfigureServices(IServiceCollection services)
{       
    services.Configure<CookieAuthenticationOptions>(options =>
    {
        options.LoginPath = new PathString("/Home/Index");
    });
}

实现您正在寻找的内容的最佳方法是将Cookie过期时间设置为比真实用户会话过期晚很多,然后执行会话过期服务器端并在此时重定向用户。虽然它不理想,但是当cookie过期时你没有其他选择。

public void ConfigureServices(IServiceCollection services)
{
    app.UseCookieAuthentication(new CookieAuthenticationOptions()
    {
        AuthenticationScheme = "MyCookieMiddlewareInstance",
        // Redirect when cookie expired or not present
        LoginPath = new PathString("/Account/Unauthorized/"),
        AutomaticAuthenticate = true,
        // never expire cookie
        ExpireTimeSpan = TimeSpan.MaxValue,
        Events = new CookieAuthenticationEvents()
        {
            // in custom function set the session expiration
            // via the DB and reset it everytime this is called
            // if the session is still active
            // otherwise, you can redirect if it's invalid
            OnValidatePrincipal = <custom function here>
        }
    });
}

答案 2 :(得分:0)

您的案例似乎没有事件,但您可以使用OnRedirectToLogin更改重定向uri。这是一个例子:

OnRedirectToLogin = async (context) =>
{
      var binding = context.HttpContext.Features.Get<ITlsTokenBindingFeature>()?.GetProvidedTokenBindingId();
      var tlsTokenBinding = binding == null ? null : Convert.ToBase64String(binding);
      var cookie = context.Options.CookieManager.GetRequestCookie(context.HttpContext, context.Options.CookieName);
      if (cookie != null)
      {
            var ticket = context.Options.TicketDataFormat.Unprotect(cookie, tlsTokenBinding);

            var expiresUtc = ticket.Properties.ExpiresUtc;
            var currentUtc = context.Options.SystemClock.UtcNow;
            if (expiresUtc != null && expiresUtc.Value < currentUtc)
            {
                  context.RedirectUri += "&p1=yourparameter";
            }
       }
       context.HttpContext.Response.Redirect(context.RedirectUri);

}