如何取消对当前用户ASP.net MVC身份的身份验证 [英] How to unauthenticate current user ASP.net mvc Identity

查看:69
本文介绍了如何取消对当前用户ASP.net MVC身份的身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户访问我的网站时,他们会获得登录页面.成功登录后,他们可以注销,其他用户可以登录.但是,如果用户在登录时单击后退按钮,它将进入登录页面.此时,新用户无法再登录.我收到一个防伪令牌错误.

When a user goes to my site they get the login page. Once they successfully login they can logoff and a different user can login. However, if the user clicks the back button while logged in it goes to the login page. At this point a new user can no longer login. I receive an anti-forgery token error.

我尝试注销任何进入登录页面的用户.我尝试了其他注销方法.我什至尝试Session.Abandon();

I have tried to logoff any user that goes to the login page. I have tried different ways to logoff. I even tried to Session.Abandon();

帐户控制器:

// GET: /Account/Login
    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        EnsureLoggedOut();            
        ViewBag.ReturnUrl = returnUrl;
        // Store the originating URL so we can attach it to a form field
        var viewModel = new LoginViewModel { ReturnUrl = returnUrl };

        return View(viewModel);
    }

    // POST: /Account/Login
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        ApplicationUser user = new ApplicationUser();
        try
        {
            user = DBcontext.Users.Where(u => u.Email.Equals(model.Email)).Single(); // where db is ApplicationDbContext instance

        }
        catch (InvalidOperationException)
        {
            // the user is not exist
            return View("The user does not exist.");
        }

        var result = await SignInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, shouldLockout: false);

        SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
        switch (result)
        {
            case SignInStatus.Success:
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresVerification:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
            case SignInStatus.Failure:
            default:
                ModelState.AddModelError("", "Invalid login attempt.");
                return View(model);
        }
    }

    // POST: /Account/LogOff
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    { Session.Abandon();
        AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        return RedirectToAction("Index", "Home");
    }

    private ActionResult RedirectToLocal(string returnUrl)
    {
        if (Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);
        }
        return RedirectToAction("Index", "Home");
    }                

}

登录视图:

@model LoginViewModel
@{ViewBag.PageId = "extr-page";
ViewBag.PageClass = "animated fadeInDown";}

@section topright{<span id="extr-page-header-space"> <span class="hidden-mobile">Need an account?</span> <a href="@Url.Action("register", "account")" class="btn btn-danger">Create account</a> </span>
}

<div id="content" class="container">
<div class="row">
    @{ Html.RenderPartial("_LoginText"); }
    <div class="col-xs-12 col-sm-12 col-md-5 col-lg-4">
        <div class="well no-padding">
            <form action="@Url.Action("Login", "Account")" method="POST" id="login-form" class="smart-form client-form">
                <header>
                    Sign In
                </header>
                @Html.HiddenFor(m => m.ReturnUrl)
                @Html.AntiForgeryToken()
                @Html.ValidationBootstrap()
                <fieldset>
                    <section>
                        <label class="label">E-mail</label>
                        <label class="input">
                            <i class="icon-append fa fa-user"></i>
                            <input type="Email" name="Email" value="demo@email.com">
                            <b class="tooltip tooltip-top-right"><i class="fa fa-user txt-color-teal"></i> Please enter email address/username</b>
                        </label>
                    </section>

                    <section>
                        <label class="label">Password</label>
                        <label class="input">
                            <i class="icon-append fa fa-lock"></i>
                            <input type="Password" name="Password" value="demo">
                            <b class="tooltip tooltip-top-right"><i class="fa fa-lock txt-color-teal"></i> Enter your password</b>
                        </label>
                        <div class="note">
                            <a href="@Url.Action("forgotpassword", "Account")"><i class="fa fa-frown-o"></i> Forgot password?</a>
                        </div>
                    </section>

                    <section>
                        <label class="checkbox">
                            <input type="checkbox" name="RememberMe" value="true" checked="checked">
                            <input type="hidden" name="RememberMe" value="false" />
                            <i></i>Stay signed in
                        </label>
                    </section>
                </fieldset>
                <footer>
                    <button type="submit" class="btn btn-primary">
                        Sign in
                    </button>
                </footer>
            </form>
        </div>
        @{ Html.RenderPartial("_SocialMedia"); }
    </div>
</div>

我一直希望当用户单击后退"按钮并且他/她进入登录页面时,前一个用户被注销.

I was hoping for when a user hits the back button and he/she goes to the login page the previous user gets logged off.

更新1: 明确地说,我不担心刚刚注销并单击后退"按钮的用户.相反,当用户成功登录后,我的网站中断,然后单击后退"按钮.会将它们带回登录"页面,但是由于前面提到的防伪"错误,因此没有用户名或密码.

Update 1: To be clear I am not worried about a user that just logged off and hits the back button. On the contrary, my site breaks when a user logs in successfully and then hits the back button. It takes them back to the Login page but no username or password works because of the aforementioned Anti-Forgery error.

更新2: 我在IE中测试了代码,没有问题.经过进一步研究,当我按下后退"按钮时,Chrome似乎正在保存身份验证Cookie.但是,当我正确注销时,cookie被破坏了.我以为登录页面加载时我正在调用LogOff方法,但它并未删除cookie.我将继续研究这个问题.也许有人对此有经验?

Update 2: I tested the code in IE and it had no problems. Upon further research it looks like Chrome is saving the authentication cookie when I hit the back button. However, when I properly logoff the cookie is destroyed. I thought when the login page loads I was calling the LogOff method but its not deleting the cookie. I will continue to research this problem. Maybe someone has experience with this?

更新3: 我确实注意到,当我击退btn时,该cookie并未被删除.当我正确注销时,cookie被删除.当我不使用下面的Shoe的方法缓存页面时,在击退后面的btn时,cookie确实会被删除.但是,我仍然收到防伪令牌错误.有趣的是,我有一部分标头显示在登录页面上.仅当用户通过身份验证时,才显示该标头.还应该有一个备用菜单来弹出身份验证.但事实并非如此.我想知道是否有导致这两个问题的异步问题.

Update 3: I did notice that the cookie was not deleted when I hit the back btn. When I properly logoff the cookie gets deleted. When I not cache the page utilizing Shoe's method below, the cookie does get deleted upon hitting the back btn. However, I still get the anti-forgery token error. What's interesting is that I have a part of the header that pops up on the login page. That header should only come up when a user is authenticated. There should also be an aside menu to pop up on authentication. But it doesn't. I'm wondering if I have an async problem that's causing both problems.

推荐答案

我通过做两件事的组合解决了这个问题.

I solved this by doing a combination of two things.

问题1: 我注意到当我击退btn并显示登录视图时,先前的用户cookie并未被破坏.这仅发生在chrome中,而不发生在IE中.这是通过我的Login Get上的[OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]属性解决的(感谢@Shoe).参见下面的代码.

Problem 1: I noticed that When I hit the back btn and the login view was displayed, the previous users cookie was not destroyed. This only occured in chrome but not in IE. This was solved with [OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)] attribute on my Login Get (Thanks @Shoe). See code below.

登录:

// GET: /Account/Login
    [AllowAnonymous]
    [OutputCache(NoStore = true, Duration = 0, Location = OutputCacheLocation.None)]
    public ActionResult Login(string returnUrl)
    {
        EnsureLoggedOut();

        // Store the originating URL so we can attach it to a form field
        var viewModel = new LoginViewModel { ReturnUrl = returnUrl };

        return View(viewModel);
    } 

问题2: 第二个问题是,一旦显示了登录视图,我就调用了一种方法来使用AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);Session.Abandon();登出用户.直到我因为不明白的原因按下刷新按钮,才对用户进行身份验证.直到我添加第二步来清除主体,以确保通过将HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);添加到我的SecureLoggedOut方法中来确保用户不保留任何身份验证.参见下面的代码.

Problem 2: The second problem was that once the login view was displayed, I called a method to signout the user with AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie); and Session.Abandon();. This was not unauthenticating the user until I hit the refresh button for a reason I don't understand. Not until I add a second step to clear the principal to ensure the user does not retain any authentication by adding HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null); to my EnsureLoggedOut method. See code below.

EnsureLoggedOut方法:

private void EnsureLoggedOut()
    {
        if (AuthenticationManager.User.Identity.IsAuthenticated)
        {
            //SignOut the current user
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie);
            Session.Abandon();

            // Second we clear the principal to ensure the user does not retain any authentication
            HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);
        }
    }

这篇关于如何取消对当前用户ASP.net MVC身份的身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆