使用Asp.Net 5 Identity 3.0注销后未删除Cookie

时间:2016-01-21 09:50:26

标签: c# asp.net asp.net-mvc cookies asp.net-identity

我有一个带有自定义角色和用户存储的Asp.Net MVC应用程序(版本6.0.0-rc1-final)。经过一些struggling我终于可以创建一个有效的登录机制。但是我现在有麻烦来创建一个干净的注销。我的控制器当前的注销代码是什么样的:

public async Task<ActionResult> Logout()
{
    if (User.Identity.IsAuthenticated)
    {
    await SignInManager.SignOutAsync();

    }

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

此代码存在的问题是,未删除一个Cookie: .AspNet.Microsoft.AspNet.Identity.Application

只要我不手动删除cookie,应用程序就处于脏状态并抛出空指针异常,因为 User.Identity 为空。

我找到了描述类似场景的question on stackoverflow。但是那里的解决方案对我来说并不合适,因为我使用的MVC 6已经不再有System.Web了。

我也有一个样本解决方案,它可以正常工作。在此解决方案中,永远不会创建所提到的cookie。也许正确的解决方案不是在注销后删除cookie,而是为了防止以某种方式创建cookie。

4 个答案:

答案 0 :(得分:1)

我可以在注销后通过在注销操作后手动删除cookie来修复应用程序的脏状态:

public async Task<ActionResult> Logout()
{
    if (User.Identity.IsAuthenticated)
    {
        await SignInManager.SignOutAsync();
    }

    foreach (var key in HttpContext.Request.Cookies.Keys)
    {
        HttpContext.Response.Cookies.Append(key, "", new CookieOptions() { Expires = DateTime.Now.AddDays(-1) });
    }
    return RedirectToAction("Index", "App");
}

由于cookie无法直接从服务器中删除,我只是用已经过期的日期覆盖现有的cookie。

答案 1 :(得分:1)

问题是您的RedirectToAction会将重定向覆盖到SignOutAsync发出的Identity Server结束网址。

(微软的HaoK对同一问题的解释同样为here。)

修改:解决方案是在AuthenticationProperties对象中发送带有最终SignOutAsync的重定向网址:

// in some controller/handler, notice the "bare" Task return value
public async Task LogoutAction()
{
    // SomeOtherPage is where we redirect to after signout
    await MyCustomSignOut("/SomeOtherPage");
}

// probably in some utility service
public async Task MyCustomSignOut(string redirectUri)
{
    // inject IHttpContextAccessor to get "context"
    await context.SignOutAsync("Cookies");
    var prop = new AuthenticationProperties()
    {
        RedirectUri = redirectUri
    });
    // after signout this will redirect to your provided target
    await context.SignOutAsync("oidc", prop);
}

答案 2 :(得分:0)

除了已经提到的所有内容之外,还要确保在schemeSignInAsync的调用中没有省略SignOutAsync参数,并且您将相同的值传递给两者。例如:

HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);

HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

因此,在此示例中,方案为CookieAuthenticationDefaults.AuthenticationScheme。在我的情况下,我忘记将其传递给SignOutAsync,而事实上显而易见的是,我花了更长的时间才愿意让我跟踪。

答案 3 :(得分:0)

另一个可能导致身份服务器cookie留在客户端上的陷阱是注销失败。注销失败的一个典型原因是客户端的PostLogoutRedirectUris配置错误。

从客户端看不到注销失败,endsession调用返回200 OK,以及logout调用。

但是,您的身份服务器日志上会显示注销失败的踪迹。