无法注销身份的MVC 5应用程序

6

我正在创建一个新的(空模板)ASP.NET MVC 5应用程序,但我无法注销此应用程序。 我的注销操作:

public ActionResult LogOff()
{
    if (User.Identity.IsAuthenticated)
    {
        //break here
    }
    try
    {
        AuthenticationManager.SignOut();
        if (User.Identity.IsAuthenticated || Request.IsAuthenticated)
        {
            //break here;
        }
    }
    return RedirectToAction("Login", "Account");
}

启动类:

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login")
        });
        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    }
}

Application Context:

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
 {
    public ApplicationDbContext()
        : base("DefaultConnection", false)
    {
    }
 } 

连接字符串:

<connectionStrings>
<add name="DefaultConnection" connectionString="Server=.;Database=DataTest;Trusted_Connection=True;" providerName="System.Data.SqlClient" />
</connectionStrings>

执行LogOff()操作没有问题,并将我重定向到“Login”操作,但我仍然登录着。 这是什么问题?

7个回答

4

试试这个:

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

这是一篇文章的原因是什么? - Halter
抱歉,为什么要使用[HttpPost]?我应该更具体地说明。 - Halter
@Halter - 改变状态的操作不应该是获取操作。这会让某些人很容易被恶作剧签出,因为有人添加了一个指向/Logoff的<img>标签,例如。 - Erik Funkenbusch

2
app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                LogoutPath = new PathString("/Account/SignOut"),
                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>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });      

请在Startup.Auth.cs中设置"LogoutPath"为您想要的任何路由。


1
大部分代码看起来不错。我猜想你的操作方法可能有问题。通常在这里只需要做一个事情,就是。
public ActionResult LogOff()
{
    AuthenticationManager.SignOut();

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

我不知道if块对于你的退出流程是否至关重要,但这两行代码是你唯一需要做的事情。如果它是至关重要的,你应该通过调试器检查SignOut方法是否被触发。

是的,我知道,我只是放了其他代码来检查用户是否仍然已验证。问题是,应用程序似乎从cookie或其他东西获取数据,然后在执行此操作后我仍然登录。 - gog
2
另外,请记住,如果您使用的是Chrome浏览器,它可能不会将您注销:https://dev59.com/hWAg5IYBdhLWcg3wZ6TY#23633068 - George Stocker
在此方法执行后(使用启动类中选择的设置),应删除 cookie。如果 cookie 仍然存在,请使用浏览器的开发者工具进行检查。就 Chrome 而言,我经常用它进行开发,并且在使用 Identity 时还没有出现问题。 - Horizon_Net
@George 我也遇到了同样的问题,当我在IE上测试时,问题消失了。Chrome没有让我退出登录。 - Igorski88

0
这对我有用: 在您的RouteConfig.cs中创建一个路由,如下所示:
 routes.MapRoute(
       "userlogout",
       "Account/Logout",
       new { controller = "Account", action = "LogOff" }
       );

你可以在AccountController.cs中保留默认的注销代码,或者添加其他人建议的附加项(如session.abandon();等)。 但是,以下代码应该也可以正常工作:

[HttpPost] 
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    AuthenticationManager.SignOut();

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

0

关于 ASP .Net MVC 注销不起作用的问题:

我在生产环境下使用 IIS 托管的应用程序中发现了一个问题,在 Chrome 浏览器中无法正常工作。

尽管在 Visual Studio Dev 主机的所有浏览器中都可以正常工作,但在 IE 上的生产模式下却出现了问题。

我在 Startup.Auth.CS 中遇到了问题,请确保没有针对以下内容存在重复配置:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.UseCookieAuthentication((new CookieAuthenticationOptions(.....))

0
在这种情况下,您也可以执行以下操作: 从LogOff操作中删除[HttpPost]并替换为[HttpGet]。 您只需要传递AntiForgeryToken。但问题是这是否是一种非常安全的方式。更多信息请参见:在HTTP GET中使用MVC3的AntiForgeryToken以避免Javascript CSRF漏洞
[HttpGet] 
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
     AuthenticationManager.SignOut();
     return RedirectToAction("Login", "Account");
}

0

这对我来说似乎很有效。

public ActionResult Logoff()
{
    HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
    HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Response.Cache.SetNoStore();

    Session.Clear();
    Session.Abandon();
    Session.RemoveAll();
    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接