MVC AuthenticationManager.SignOut() 未注销

MVC AuthenticationManager.SignOut() is not signing out

我的项目基于 Visual Studio 2013 年的 MVC 5 项目模板(个人用户帐户选项)。我一直依赖用户的默认登录和注销方法。但我不确定我做了什么,在某些时候,用户无法再注销,但他们可以以其他用户身份登录。

这是帐户控制器的默认注销方法

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        AuthenticationManager.SignOut();
        return RedirectToAction("Index", "Home");
    }
    private IAuthenticationManager AuthenticationManager
    {
        get
        {
            return HttpContext.GetOwinContext().Authentication;
        }
    }

这是显示用户用户名的默认 _LoginPartial.cshtml 视图。

    @using Microsoft.AspNet.Identity
    @if (Request.IsAuthenticated)
    {
        using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
        {
            @Html.AntiForgeryToken()

            <ul class="nav navbar-nav navbar-right">
                <li>
                    @Html.ActionLink("Hello " + User.Identity.GetUserName() + "!", "Index", "Manage", routeValues: null, htmlAttributes: new { title = "Manage" })
                </li>
                <li><a    href="javascript:document.getElementById('logoutForm').submit()">Log off</a>            </li>
            </ul>
        }
    }
    else
    {
        <ul class="nav navbar-nav navbar-right">
            <li>@Html.ActionLink("Register", "Register", "Account", routeValues: null, htmlAttributes: new { id = "registerLink" })</li>
            <li>@Html.ActionLink("Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" })</li>
        </ul>
    }

当用户注销时,它会将用户定向到登录页面,但仍会显示用户的用户名,这意味着他们尚未注销。并且浏览器上的 url 显示 http://localhost/Account/Login?ReturnUrl=%2FAccount%2FLogOff

它不会将用户带回到主页的索引页面。所以我的猜测是在语句 AuthenticationManager.SignOut(); 处发生了一些事情。我很困惑,因为我没有对帐户控制器进行任何更改。

如有任何线索,我们将不胜感激。

只需在 SignOut() 之后添加这行代码:

 HttpContext.User = new GenericPrincipal(new GenericIdentity(string.Empty), null);

另请查看: Page.User.Identity.IsAuthenticated still true after FormsAuthentication.SignOut()

我认为我的问题不在 SignOut()。如果您认为您的问题出在 SignOut()(并使用 Owin 身份验证),请查看

对于我来说是一个愚蠢的错误! 我忘了我在控制器中添加了 [Authorize(Role = "admins")],因为我只希望管理员使用默认模板附带的注册方法。结果是除了管理员没有人可以登出!

这是我的:

[Authorize(Roles = "admin")]
public class AccountController : Controller
{
    public ActionResult LogOff()
    {
    }
    public ActionResult Register()
    {
    }
}

我所做的只是将注册方法移至新的控制器,如下所示:

[Authorize]
public class AccountController : Controller
{
    public ActionResult LogOff()
    {
    }
}

[Authorize(Roles = "admin")]
public class AdminController : Controller
{
    public ActionResult Register()
    {
    }
}

现在所有人都可以登出,只有管理员可以注册用户。 (默认的 AuthenticationManager.SignOut() 工作正常。)

我遇到了同样的问题。 在 CodePlex 上检查此问题:

http://web.archive.org/web/20160403071605/https://aspnetidentity.codeplex.com/workitem/2347

尝试将 AuthenticationManager.SignOut() 替换为 AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie);

希望对你有所帮助。 :-)

替换

AuthenticationManager.Signout(); 

AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie); 

根据 Sergio 回答中的问题

我遇到了同样的问题..

下面是 Microsoft 提供的标准 ASP.Net MVC 注销程序,它可以正常工作,除了用户在注销和登录后会出错,这是因为身份验证令牌。一旦您发布它,它就很容易修改。但是没人说。

// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);

    return RedirectToAction("Index", "Home");
}

如您所见,AccountController

中的标准注销方式

那个 html 代码,用我的小技巧 -> id="logoffbtn"

 @using (Html.BeginForm("LogOff", "Account"))
 {
 @Html.AntiForgeryToken()
  <button class="btn btn-default btn-flat" id="logoffbtn" 
  type="submit">Logout</button>
 }

因此,使用标准方式正确注销的解决方案是在主 java 脚本文件中的某处添加小技巧:

$(document).ready(function()
{
    try
    {
        $('#logoffbtn').click(function ()
        {
            // alert('Sign new href executed.');
            console.log("Session token start");
            sessionStorage.removeItem('accessToken');
            console.log("Session token done");
        });
    } catch (e)
    {
        console.log("Session token err");
    }
});

那么接下来会发生什么..基本上按下注销按钮后,您将清除访问令牌,现在注销将开始正常工作。

希望对您有所帮助。

P.S。我已经尝试了很多方法,只有这个对我来说是一个 hack。