How to enable front-channel or back-channel logout in identityserver4

identityserver4

I'm looking at how to disconnect the user currently logged on the mvc client (e.g. http://localhost:5001), when that user performs logout on identity server's deployment (e.g. http://localhost:5000)

I understand there's an implementation of OAuth2 in identityserver4 that does just that (https://openid.net/specs/openid-connect-backchannel-1_0.html and https://openid.net/specs/openid-connect-frontchannel-1_0.html)

Luckily for me, Brock Allen just pushed a change in the samples less than a day ago: https://github.com/IdentityServer/IdentityServer4.Samples/issues/197

However the sample is either incomplete at this point, or I'm missing something.

on my server, I'm setting the value of FrontChannelLogoutUrl to http://localhost:5001/frontchannello, and I added that piece of code to my mvc client (basically stolen from the sample):

[HttpGet("frontChannello")]public IActionResult FrontChannelLogout(string sid){    if (User.Identity.IsAuthenticated)    {        var currentSid = User.FindFirst("sid")?.Value ?? "";        if (string.Equals(currentSid, sid, StringComparison.Ordinal))        {            //await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);            return new SignOutResult(new[] { "Cookies", "oidc" });        }    }    return NoContent();}

That code never gets called.

So my question is: should I use backchannel or frontchannel; and, how to implement it

Best Solution

The Identity server 4 documentation describes well how front-channel logout should be implemented. Look for the Quickstart 8_AspnetIdentity as it provides most of the code required for the implementation.

Some highlights of the code required in the identity server :

In the AccountController.cs, the Logout function builds a LoggedOutViewModel and returns a LoggedOut view.

[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Logout(LogoutInputModel model){   // build a model so the logged out page knows what to display   var vm = await BuildLoggedOutViewModelAsync(model.LogoutId);   ...   return View("LoggedOut", vm);}

The SignOutIframeUrl iframe is served in the LoggedOut.cshtml.

@model LoggedOutViewModel<div class="page-header logged-out">   <small>You are now logged out</small>   ...   @if (Model.SignOutIframeUrl != null)   {       <iframe width="0" height="0" class="signout" src="@Model.SignOutIframeUrl"></iframe>   }</div>

What remains to be done is defining the FrontChannelLogoutUri for your each of your clients. That's normally done in the identity server's config.cs

 public static IEnumerable<Client> GetClients() {        return new List<Client>        {            // resource owner password grant client            new Client            {                ClientId = "js",                ClientName = "JavaScript Client",                AllowedGrantTypes = GrantTypes.Code,                RequirePkce = true,                RequireClientSecret = false,                RedirectUris =           { "http://localhost:5003/callback.html" },                PostLogoutRedirectUris = { "http://localhost:5003/index.html" },                FrontChannelLogoutUri = "http://localhost:5003/frontChannello"