HttpContext.Authentication.SignOutAsync不会删除身份验证cookie

时间:2016-12-13 13:13:18

标签: authentication cookies asp.net-core-1.0

根据ASP.NET Core documentation,方法HttpContext.Authentication.SignOutAsync()也必须删除身份验证cookie。

  

退出

     

要退出当前用户,并删除他们的Cookie (italics mine - A.C.),请在控制器内调用以下内容

     

await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");

但事实并非如此!其他一切似乎都没问题,尤其是auth scheme,因为用户正确登录了cookie .AspNetCore。已创建。

任何想法为什么cookie在用户唱出后仍然存在?

8 个答案:

答案 0 :(得分:5)

您没有发布足够的代码来告诉我,但我怀疑在您致电SignOutAsync之后您有某种类型的重定向(例如,RedirectToAction)会将重定向覆盖到OIDC endsession SignOutAsync尝试发布的网址。

(微软的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 the HttpContextAccessor 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);
}

答案 1 :(得分:5)

我最近有同样的问题。就我而言,浏览器创建了多个cookie。一个名为“ .AspNetCore.Antiforgery”的名称,另一个带有我在startup.cs中为cookie设置的自定义名称的名称。

为我解决了错误的是JTvermose's answer的第一部分,进行了一些更改。我将以下代码添加到我的注销方法中。像魅力一样工作。

    if (HttpContext.Request.Cookies.Count> 0) 
        {
            var siteCookies = HttpContext.Request.Cookies.Where(c => c.Key.Contains(".AspNetCore.") || c.Key.Contains("Microsoft.Authentication"));
            foreach (var cookie in siteCookies)
            {
                Response.Cookies.Delete(cookie.Key);
            }
        }

                await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);
        HttpContext.Session.Clear();
        return RedirectToPage("/Index");

答案 2 :(得分:2)

我遇到了同样的问题。 SignOutAsync不能正常工作。

我发现了这个:

Response.Cookies.Delete(".AspNetCore.<nameofcookie>");

答案 3 :(得分:2)

我使用控制器中的Logout()方法中的以下代码段删除了我的网站Cookie,从而解决了这个问题。我发现我的网站会创建多个cookie。

// Delete the authentication cookie(s) we created when user signed in
            if (HttpContext.Request.Cookies[".MyCookie"] != null)
            {
                var siteCookies = HttpContext.Request.Cookies.Where(c => c.Key.StartsWith(".MyCookie"));
                foreach (var cookie in siteCookies)
                {
                    Response.Cookies.Delete(cookie.Key);
                }
            }

在Startup.cs中:

app.UseCookieAuthentication(new CookieAuthenticationOptions()
            {
                AuthenticationScheme = "Cookies",
                LoginPath = new PathString("/Account/Login/"),
                AccessDeniedPath = new PathString("/Home/Index/"),
                AutomaticAuthenticate = true,
                AutomaticChallenge = true,
                CookieName = ".MyCookie"
            });

请注意,由于我在Google上使用OpenIdConnect,因此我不使用await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");

答案 4 :(得分:0)

这是删除cookie的代码(如果没有其他帮助,请使用暴力):

await this.HttpContext.Authentication.SignOutAsync(<AuthenticationScheme>);

// ...

var cookie = this.Request.Cookies[<CookieName>];
if (cookie != null)
{
    var options = new CookieOptions { Expires = DateTime.Now.AddDays(-1) };
    this.Response.Cookies.Append(cookieName, cookie, options);
}

糟糕,糟糕,糟糕!看起来像一个非常难看的补丁!但是有效...... :(

任何 其他 解决方案?

答案 5 :(得分:0)

解决了第一行的问题。

await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
// await _SignInManager.SignOutAsync();
// HttpContext.Response.Cookies.Delete(".AspNetCore.Cookies");

答案 6 :(得分:0)

也许您的情况是使用ASP .NET Core身份验证,例如我的情况

因此,可以尝试使用ASP NET Identity中的API,而不是使用 HttpContext.Authentication.SignOutAsync() HttpContext.SignOutAsync()

SignInManager.SignOutAsync()

HttpContext的API并未清除名称以“ .AspNetCore”开头的cookie。

(要使用SignInManager,您需要通过asp net core的DI来引入SignInMbanager)

答案 7 :(得分:0)

在我的情况下,McGuireV10的答案无效,因为Expanded( child: FutureBuilder<bool>( future: getData(), builder: (BuildContext context, AsyncSnapshot<bool> snapshot) { if (!snapshot.hasData) { return const SizedBox(); } else { return MultiProvider( providers: [ ChangeNotifierProvider( create: (context) => Properties()), ChangeNotifierProvider( create: (context) => Cities()), ], // child: HomeGrid(_showOnlyFavorites), child: HomeGrid(), ); } }, ), ), 没有重定向到我给定的redirectUri。

我通过在SignOutAsync调用之后添加await context.SignOutAsync("oidc", prop);来解决此问题。