Konrad Viltersten
Konrad Viltersten

Reputation: 39098

Can't remove cookies using C#

I have two cookies in my browser put there by the IDS4 during sign-in. I need to remove them. Failing to get rid of them by signing out (for whatever reason that may be, despite the docs), I decided to apply a pramatic work-around and remove them manually. It seems those a hard cookie. Two of them...

enter image description here

I attempted to get rid of them like this - targetting all the available schemas as suggested.

await HttpContext.SignOutAsync("Identity.Application");
await HttpContext.SignOutAsync("Identity.External");
await HttpContext.SignOutAsync("Identity.TwoFactorRememberMe");
await HttpContext.SignOutAsync("Identity.TwoFactorUserId");
await HttpContext.SignOutAsync("idsrv");
await HttpContext.SignOutAsync("idsrv.external");

I tried to kill them by explicit hit as proposed here. Apparently, though, that's not how the cookie crumbles.

Response.Cookies.Delete(".AspNetCore.Identity.Application");
Response.Cookies.Delete("idsrv.session");

Nothing of that erases them. They do disappear when I restart the browser, of course, but I need them gone without that measure (also, if I'm to restart the browser, I don't need to log the user out as they will be gone anyway).

I've seen suggestions to call HttpContext.Current but that the same as just simply HttpContext in my controller (according to this). There is talk about Session.Abandon but I don't see that field in my context. There seems to be some issues with this specific matter but I can't tell if those still remain unsolved by the IDS4 team.

edit

public async Task<IActionResult> LogOut([FromQuery] string logoutId)
{
  LogoutRequest context = await InteractionService.GetLogoutContextAsync(logoutId);

  bool? isLoggedIn = User?.Identity.IsAuthenticated;
  isLoggedIn |= User.IsAuthenticated();

  await HttpContext.SignOutAsync();
  await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
  await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

  //Response.Cookies.Delete("idsrv.session");

  var output = new
  {
    authenticated = isLoggedIn,
    clientId = context.ClientId,
    sessionId = context.SessionId,
    redirect = context.PostLogoutRedirectUri,
    sub = context.SubjectId
  };

  return Ok(output);
  // return SignOut();
}

Upvotes: 1

Views: 5805

Answers (2)

Tore Nestenius
Tore Nestenius

Reputation: 19921

When you do the signout, you should not return anything from the action method, as the SignOutAsync generates its own "response". This is how I do it:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task Logout()
{
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
    await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);

    //Important, this method should never return anything.
}

Upvotes: 1

Ran Turner
Ran Turner

Reputation: 18026

Have you tried setting the expire time for the cookie?

Response.Cookies.Append("idsrv.session", "", new CookieOptions() {
    Expires = DateTime.Now.AddDays(-1)
});

When the browser will receive the response from the server, it will identify that the cookie with the name you provided (idsrv.session in this example) has been expired and as a result from this, it will delete the cookie.

Another this that might help is setting the Secure option as true :

"In order to delete a SameSite=None cookie, the replacement cookie with the expiry date in the past also needs to have the Secure flag set. If that is not the case, the cookie won't be deleted (as in: the replacement cookie won't be accepted by Chrome)" -https://www.thinktecture.com/en/identity/samesite/how-to-delete-samesite-cookies/

Response.Cookies.Delete("CookieName", new CookieOptions()
{
   Secure = true,
});

Upvotes: 1

Related Questions