首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使旧会话Cookie - ASP.Net标识无效

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

Stack Overflow用户
提问于 2015-12-01 12:42:49
回答 3查看 14.1K关注 0票数 31

一家外部公司在我正在开发的ASP.NET MVC 5应用程序上做了一些渗透测试。

他们提出的一个问题如下所述

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

我们使用的是ASP.NEt标识2.2

下面是我们对帐户控制器的注销操作

代码语言:javascript
复制
 [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        AuthenticationManager.SignOut();
        return RedirectToAction("Login", "Account");
    }

在startup.auth.cs中

代码语言:javascript
复制
 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无效?

根据杰米·邓斯坦的建议进行编辑,我添加了AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);,但是没有什么区别,我仍然可以退出应用程序,在Fiddler中克隆以前经过验证的请求,并让应用程序接受它。

编辑:我更新的注销方法

代码语言:javascript
复制
 [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");
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-12-01 18:09:18

确保按照杰米的建议正确地使用AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie);

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

如果您仍然可以在更新安全性标记后登录,那么很可能OWIN无法获得ApplicationUserManager。确保这一行刚好在app.UseCookieAuthentication的上方

代码语言:javascript
复制
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

或者,如果您正在使用DI,请从DI中获取ApplicationUserManager

代码语言:javascript
复制
app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());

另外,将validateInterval: TimeSpan.FromMinutes(30)降低到较低的值--我通常只需要几分钟就好了。这是标识将auth中的值与数据库中的值进行比较的频率。当比较完成后,标识将重新生成cookie以更新时间戳。

票数 10
EN

Stack Overflow用户

发布于 2016-10-27 18:27:19

Trailmax的回答是点对点,我想我想补充一点,如果有人在使用ASP.NET样板的同时也尝试这样做,下面是我用来做这件事的地方:

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

我本来有:

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

而且不起作用了。

票数 0
EN

Stack Overflow用户

发布于 2020-12-29 16:48:40

你走对了路。实际上,最简单的方法是更新用户SecurityStamp,但通常执行它不会导致成功,因为实际上凭证没有更改,而且在db中仍然是一样的。解决方案,尝试如下:

代码语言:javascript
复制
private string NewSecurityStamp()
        {
            return Guid.NewGuid().ToString();
        }

private async Task RegenerateSecurityStamp(string userId)
    {
        var user = await _userManager.FindByIdAsync(userId);
            if (user != null)
            {
                user.SecurityStamp = NewSecurityStamp();
                await _userStore.UpdateAsync(user);
            }
    }

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> LogOff()
    {
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        await RegenerateSecurityStamp(User.Identity.GetUserId());
        return RedirectToAction("Login", "Account");
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34020730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档