使旧会话Cookie无效 - ASP.Net标识

时间:2015-12-01 12:42:50

标签: asp.net-mvc asp.net-identity owin asp.net-identity-2

外部公司已经对我正在开发的ASP.NET MVC 5应用程序进行了一些渗透测试。

他们提出的问题描述如下

  

与会话管理链接的cookie称为AspNet.ApplicationCookie。手动输入时,应用程序会对用户进行身份验证。即使用户从应用程序注销,cookie仍然有效。这意味着,旧会话cookie可以在无限时间范围内用于有效身份验证。在插入旧值的那一刻,应用程序接受它并用新生成的cookie替换它。因此,如果攻击者获得对现有cookie之一的访问权限,则将创建有效会话,其访问权限与过去相同。

我们正在使用ASP.NEt Identity 2.2

这是我们在帐户控制器上的退出操作

 [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        AuthenticationManager.SignOut();
        return RedirectToAction("Login", "Account");
    }
在startup.auth.cs中

 app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            ExpireTimeSpan = TimeSpan.FromHours(24.0),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator
             .OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                 validateInterval: TimeSpan.FromMinutes(1.0),
                 regenerateIdentityCallback: (manager, user) =>
                     user.GenerateUserIdentityAsync(manager),
                 getUserIdCallback: (id) => (Int32.Parse(id.GetUserId())))

            }
        });

我原本以为该框架会照顾旧的会话cookie的无效,但浏览Owin.Security源代码却没有。

如何在注销时使会话cookie失效?

编辑Jamie Dunstan的建议我添加了AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);,但后来没有任何区别。我仍然可以退出应用程序,在Fiddler中克隆先前经过身份验证的请求,并让应用程序接受它。

编辑:我更新的Logoff方法

 [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> LogOff()
    {
        var user = await UserManager.FindByNameAsync(User.Identity.Name);

        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        await UserManager.UpdateSecurityStampAsync(user.Id);

        return RedirectToAction("Login", "Account");
    }

3 个答案:

答案 0 :(得分:6)

确保使用Jamie正确建议的AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie);

能够再次使用相同的cookie登录是设计的。 Identity不会创建内部会话来跟踪所有已登录的用户,如果OWIN获得了击中所有框的cookie(即上一个会话中的副本),它将允许您登录。<​​/ p>

如果您在更新安全标记后仍然可以登录,则很可能OWIN无法获得ApplicationUserManager。确保此行位于app.UseCookieAuthentication

之上
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

或者如果你正在使用DI从DI中取ApplicationUserManager

app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());

同时将validateInterval: TimeSpan.FromMinutes(30)降低到更低的值 - 我通常会在几分钟内解决。这是Identity将auth-cookie中的值与数据库中的值进行比较的频率。完成比较后,Identity会重新生成cookie以更新时间戳。

答案 1 :(得分:0)

Trailmax的答案很明显,我想我会补充一点,如果有人在使用ASP.NET Boilerplate的同时尝试这样做,以下是我用来做这项工作的内容:

app.CreatePerOwinContext(() => IocManager.Instance.Resolve<UserManager>());

我最初有:

app.CreatePerOwinContext(() => IocManager.Instance.ResolveAsDisposable<UserManager>());

并且没有工作。

答案 2 :(得分:0)

你走对了。确实,最简单的方法是更新用户 SecurityStamp 但 通常执行它不会导致成功,因为实际凭据没有更改并且它在 db 中保持不变。 解决办法,试试这个:

*args