Can not override path "/Util/Logout" in cms 12

Vote:
 

INFO: I do not use EPiServer.CMS.UI.AspNetIdentity, but Azure AD SSO.

In Optimizely we have an Logout link inside /episerver/cms. It point to /Util/Logout. I want my users to logout using this feature. Now they get an 500 error page if they use it. InvalidOperationException: Unable to resolve service for type 'EPiServer.Shell.Security.UISignInManager' while attempting to activate 'EPiServer.Cms.Shell.UI.Controllers.Internal.AccountController'.

I feel like I have two options. Either to hijack the request to /Util/Logout and run my own logout logic or to change the url. Both solutions should be possible, but I can't get it to work.

In cms 11 it was possible to hijack the request like this

 app.Map(LogoutUrl, map =>
            {
                map.Run(ctx =>
                {
                    ServiceLocator.Current.GetInstance<IAuthenticationService>().SignOut();

                    ctx.Authentication.SignOut();
                    ctx.Response.Write("You are logged out.");
                    return Task.FromResult(0);
                });
            });

I tried to do this in cms 12 but with no luck:

 // TODO not working. This approach worked in aspnet, but not in aspnetcore.
            app.Map("/Util/Logout", map =>
            {
                map.Run(ctx =>
                {
                    ctx.SignOutAsync();
                    ctx.Response.WriteAsync("You are logged out.");
                    return Task.FromResult(0);
                });
            });

A different approach is to change the url, to point to an url I control. 

The logout link is generated inside a [MenuProvider] inside EPiServer.Cms.Shell.UI.Internal.CmsMenuProvider. On line 3 below it seams that it should be possible to change the url by setting the CookieAuthenticationOptions.LogoutPath.

 private void AddLogoutMenuItem(List<MenuItem> menuItems)
    {
      string url = this._cookieAuthenticationOptions?.LogoutPath.Value ?? this._uiPathResolver.CombineWithUtil("Logout");
      if (this._httpContextAccessor.HttpContext != null)
      {
        IAntiforgery service1 = this._httpContextAccessor.HttpContext.RequestServices.GetService<IAntiforgery>();
        IOptions<AntiforgeryOptions> service2 = this._httpContextAccessor.HttpContext.RequestServices.GetService<IOptions<AntiforgeryOptions>>();
        if (service1 != null && service2.Value != null)
          url = url + "?" + service2.Value.HeaderName + "=" + service1.GetAndStoreTokens(this._httpContextAccessor.HttpContext).RequestToken;
      }
      UrlMenuItem urlMenuItem1 = new UrlMenuItem(this._localizationService.GetString("/shell/cms/menu/logout"), "/global/user/logout", url);
      urlMenuItem1.SortIndex = 1010;
      UrlMenuItem urlMenuItem2 = urlMenuItem1;
      menuItems.Add((MenuItem) urlMenuItem2);
    }

I tried this in my Startup.cs

.AddCookie(options =>
            {
                options.ForwardChallenge = SamlAuthenticationDefaults.AuthenticationScheme;
                options.Cookie.SameSite = SameSiteMode.None;
                options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
                options.LogoutPath = "/test/Logout";                
            })

But with no luck. When / how should I set the LogoutPath to make this work? 

#276753
Edited, Mar 20, 2022 20:19
Vote:
 

Configuring the CookieAuthenticationOptions.LogoutPath should do it. Do you mind posting your whole configuration in startup.cs? Maybe something else is configuring the options.

#276793
Mar 21, 2022 9:12
Vote:
 

Found this soltuion, using MapWhen (this will stop execution of other midlewares) instead of only Map.


            app.MapWhen(ctx => ctx.Request.Path.StartsWithSegments("/Util/Logout"), appBuilder =>
            {
                appBuilder.Run(async appBuilder =>
                {
                    await appBuilder.SignOutAsync();
                    appBuilder.Response.Redirect("/", false);                    
                });
            });
#276795
Edited, Mar 21, 2022 11:10
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.