This basically applies to any SSO application, not only B2C that wants to use Single sign-out so I would love to hear from anyone if you managed to find a solution :-)
I have multiple applications running under the same B2C and I have everything up and running but there is one issue that I am struggling with for the past week and I cannot get it to log out from the Back Office when Azure B2C sends the request to Umbraco using front channel log-out.
I have built the logout similar to the approach that Jeroen Breuer has in his member frontend example only that mine is for backend users, which means I am using the IBackOfficSignInManager instead.
[HttpGet]
public async Task<IActionResult> HandleLogout([Bind(Prefix = "logoutModel")] PostRedirectModel model)
{
try
{
// Trigger logout on the external login provider.
await this.HttpContext.SignOutAsync("Umbraco.BackOffice.OpenIdConnect");
// Trigger logout on this website.
await _signInManager.SignOutAsync();
}
catch
{
return new EmptyResult();
}
// Don't return RedirectToCurrentUmbracoPage.
// That will override the location header which is set by the external login provider logout.
// So by returning EmptyResult() this will still redirect to the external login provider to logout there.
return new EmptyResult();
}
This way I have a endpoint exposed. This endpoint also works when I access it through the browser so when I visit:
myumbracosite.com/umbraco/surface/externallogout/handlelogout
I am successfully logged out.
So I set up this endpoint inside of Azure B2C as the front channel logout url and when the logout event is triggered from B2C it also calls the HandleLogout method as you can see below.
The problem here is that B2C creates internally invisible iframe and then calls the endpoint, but because because we have no access to the Umbraco cookie UMB_UCONTEXT the logout actually never happens at least not on Umbraco side, for B2C I am officialy logged out.
I also tried the standard OpenID approach would be to have the "/signout-oidc" endpoint and configuring
//The CallbackPath represents the URL to which the browser should be redirected to and the default value is /signin-oidc.
options.CallbackPath = "/signin-oidc";
options.RemoteSignOutPath = "/signout-oidc";
but setting that as my front-end channel logout url also did not work.
So I did some further investigation of what Umbraco does internally which brought me to the point that Umbraco creates the UMB_UCONTEXT cookie when authenticated, now this is all good and this cookie get's deleted when calling from the browser
myumbracosite.com/umbraco/surface/externallogout/handlelogout
Because it is being called from the same host Umbraco is able to delete the cookie and do all the other tasks required to logout when calling:
await _signInManager.SignOutAsync();
But when implementing Single sign-out, the front-end channel logout uri will create an iframe, which Azure also does and all the calls go through (see image with calls above) but because the calls also internally try to delete the cookie it does not work since it is in an iframe.
I tried all possible approaches I can think of but I simply get not get any hold of how I can get Umbraco to eliminate the backend session when the logout it is being called externally from Azure B2C
I would really appreciate if anyone could help out or could give me some direction on how they managed to get Single signout up and running with Umbraco
After lots of experiments, I found out how to solve the issue.
Because I have seen that some other people also have had this issue I will post the solution to it here. It was rather simple but I had to find out how Umbraco actually sets this cookie to be able to come up with the solution it is all done in the ConfigureBackOfficeCookieOptions class inside the Umbraco source code.
I created a custom implementation of IConfigureNamedOptions
public class AuthenticationCookieOptions : IConfigureNamedOptions<CookieAuthenticationOptions> {
/// <inheritdoc />
public void Configure(string name, CookieAuthenticationOptions options)
{
if (name != Constants.Security.BackOfficeAuthenticationType)
{
return;
}
Configure(options);
}
/// <inheritdoc />
public void Configure(CookieAuthenticationOptions options)
{
options.Cookie.SameSite = SameSiteMode.None;
}
}
It will make sure that the authentication cookie is set using the SameSiteMode as None
Now when the identity provider has a front-channel logout set it will allow the identity provider to delete the authentication cookie, which was not possible with SameSiteMode set to Lax
Single Sign-out / SSO - Frontend channel logout - how to eliminate session from outside?
I have found this post which was posted a while back and explains almost the same experience I am having but I will explain a bit more detailed. https://our.umbraco.com/forum/using-umbraco-and-getting-started/110629-unable-to-get-single-sign-out-working-using-oidc
This basically applies to any SSO application, not only B2C that wants to use Single sign-out so I would love to hear from anyone if you managed to find a solution :-)
I have multiple applications running under the same B2C and I have everything up and running but there is one issue that I am struggling with for the past week and I cannot get it to log out from the Back Office when Azure B2C sends the request to Umbraco using front channel log-out.
I have built the logout similar to the approach that Jeroen Breuer has in his member frontend example only that mine is for backend users, which means I am using the IBackOfficSignInManager instead.
This way I have a endpoint exposed. This endpoint also works when I access it through the browser so when I visit: myumbracosite.com/umbraco/surface/externallogout/handlelogout
I am successfully logged out.
So I set up this endpoint inside of Azure B2C as the front channel logout url and when the logout event is triggered from B2C it also calls the HandleLogout method as you can see below.
The problem here is that B2C creates internally invisible iframe and then calls the endpoint, but because because we have no access to the Umbraco cookie UMB_UCONTEXT the logout actually never happens at least not on Umbraco side, for B2C I am officialy logged out.
I also tried the standard OpenID approach would be to have the "/signout-oidc" endpoint and configuring
but setting that as my front-end channel logout url also did not work.
So I did some further investigation of what Umbraco does internally which brought me to the point that Umbraco creates the UMB_UCONTEXT cookie when authenticated, now this is all good and this cookie get's deleted when calling from the browser myumbracosite.com/umbraco/surface/externallogout/handlelogout
Because it is being called from the same host Umbraco is able to delete the cookie and do all the other tasks required to logout when calling:
But when implementing Single sign-out, the front-end channel logout uri will create an iframe, which Azure also does and all the calls go through (see image with calls above) but because the calls also internally try to delete the cookie it does not work since it is in an iframe.
I tried all possible approaches I can think of but I simply get not get any hold of how I can get Umbraco to eliminate the backend session when the logout it is being called externally from Azure B2C
I would really appreciate if anyone could help out or could give me some direction on how they managed to get Single signout up and running with Umbraco
After lots of experiments, I found out how to solve the issue.
Because I have seen that some other people also have had this issue I will post the solution to it here. It was rather simple but I had to find out how Umbraco actually sets this cookie to be able to come up with the solution it is all done in the ConfigureBackOfficeCookieOptions class inside the Umbraco source code.
I created a custom implementation of IConfigureNamedOptions
It will make sure that the authentication cookie is set using the SameSiteMode as None
Then I added the options to be configured using:
Now when the identity provider has a front-channel logout set it will allow the identity provider to delete the authentication cookie, which was not possible with SameSiteMode set to Lax
is working on a reply...