MVC AuthenticationManager.SignOut()未注销

时间:2015-03-17 03:27:23

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

我的项目基于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

没有将用户带回Home的Index页面。所以我的猜测是在语句AuthenticationManager.SignOut();中发生了一些事情。我很困惑,因为我没有改变账户控制器。

任何领导都会非常感激。

5 个答案:

答案 0 :(得分:9)

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

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

尝试用{替换AuthenticationManager.SignOut() AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie);

我希望我帮助你。 : - )

答案 1 :(得分:4)

只需在SignOut()之后添加以下代码:

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

同时检查一下: Page.User.Identity.IsAuthenticated still true after FormsAuthentication.SignOut()

答案 2 :(得分:2)

我认为我的问题不在SignOut()。如果您认为问题位于SignOut()(并使用Owin身份验证),请查看Sergio's link

我的情况是一个愚蠢的错误! 我忘了我将[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()工作正常。)

答案 3 :(得分:2)

替换

AuthenticationManager.Signout(); 

AuthenticationManager.Signout(DefaultAuthenticationTypes.ApplicationCookie); 

根据塞尔吉奥的回答中的问题

答案 4 :(得分:0)

我也遇到了同样的问题。

下面是由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。