We are using OIOSAML.NET/dk.Nita for NemLog-in (Danish National Identity Provider) as authentication mechanism for editors. Claims from the federation are mapped to Sitecore users on login, and that part works great.

We are using Sitecore 8.1 update 3.

However, when logging out the user is only logged out from Sitecore when pressing "Logout" in the Sitecore Shell. I have therefore added a pipeline component in the Logout pipeline, where I change the redirect URL by injecting SheerResponse.SetLocation(urlString) into the Pipeline before GotoLogin (and aborting the pipeline). This works great for some pages, like the Content Editor.

public class LogoutFlowAdmin : ILogoutFlowAdmin
{
    private readonly ISecurityContext _securityContext;

    public LogoutFlowAdmin(ISecurityContext securityContext)
    {
        _securityContext = securityContext;
    }

    public void Process(LogoutArgs args)
    {
        args.AbortPipeline();
        Tracer.Info("Intercepting call to Sitecore logout. Redirecting to Single Logout instead");

        var urlString = _securityContext.GetLogoutUrl();
        SheerResponse.SetLocation(urlString); // only works for non-SPEAK
    }
}

However, since some pages use the SPEAK logout pipeline, I also need to inject my code here. This part does not include GotoLogin, so I assume the flow is somewhat different.

When I debug logout from SPEAK, I can see that my code is hit every time, but adding JavaScript using SheerResponse has no effect. Also I have tried a standard redirect (which of course causes an error when invoked in an Ajax handler), changing the RedirectUrl property of the LogoutArgs, but nothing seems to work for SPEAK logout.

One option would be to change the JavaScript that invokes the Ajax handler (Sitecore AuthenticationController) so the line below with window.location is hardcoded to point to the custom Logout handler, but I would rather not go into that direction.

define(["sitecore", "jquery"], function (sc, $) {
sc.Factories.createBaseComponent({
name: "AccountInformation",
base: "ControlBase",
selector: ".sc-accountInformation",
logout: function (target, event) {
  event.preventDefault();

  // Disable cache to make sure that URL is always "followed"
  // and the logout function gets executed on the server
  var ajaxSettings = {
    type: "POST",
    url: "/sitecore/shell/api/sitecore/Authentication/Logout?sc_database=master",
    data: {},
    cache: false
  };

  var token = sc.Helpers.antiForgery.getAntiForgeryToken();
  ajaxSettings.data[token.formKey] = token.value;

  $.ajax(ajaxSettings).done(function (data) {
    window.location = JSON.parse(data).Redirect; // possible to hack here
  });
}
});
});

Does anyone have a way to change the URL the editor is redirected to after logout? Preferably in a manner that would be supported by Sitecore, and is sufficiently stable?

Update: I have been in contact with Sitecore support, that has informed that this is indeed a bug. It is fixed in 8.2. I still need a workaround, until we can upgrade, so any ideas are welcome :)

Update: Quick fix I have implemented a temporary workaround in sitecore\shell\client\Business Component Library\Layouts\Renderings\Authentications\AccountInformation\AccountInformation.js where the line with window.location is hardcoded to redirect to the Single Logout Page, as hinted in the code above.

Thank you all for your answers and comments :)

  • 2
    I believe that your javascript solution is most likely the best solution. Which I can definitely sympathize with you on not wanting to change that piece up too much. The downside to SPEAK UI in Sitecore is that it is heavily dependent on Javascript that is not exactly easy to modify. I have had to make a lot of changes to SPEAKUI for specific client needs. Editing the javascript side is not only the best way, but depending on want you're doing, it could be the only way. – Pete Navarra Oct 23 '16 at 19:40
  • Yes, that will definitely be a last resort though. – Sune Rievers Oct 24 '16 at 7:31
up vote 4 down vote accepted

EDIT: Update based on comments

If you check the definition of LogoutArgs used in the processor, there is a property called RedirectUrl that is of type: Sitecore.Text.UrlString - if you set this property in your processor, that should then be processed by the JavaScript section:

$.ajax(ajaxSettings).done(function (data) {
  window.location = JSON.parse(data).Redirect; // possible to hack here
});

The processor would be:

public class LogoutFlowAdmin : ILogoutFlowAdmin
{
    private readonly ISecurityContext _securityContext;

    public LogoutFlowAdmin(ISecurityContext securityContext)
    {
        _securityContext = securityContext;
    }

    public void Process(LogoutArgs args)
    {
        Tracer.Info("Intercepting call to Sitecore logout. Redirecting to Single Logout instead");

        var urlString = _securityContext.GetLogoutUrl();
        args.RedirectUrl = new UrlString(urlString);
    }
}

EDIT Removed the args.AbortPipeline() so that the pipeline continues and completes the redirect. See comments.

  • 1
    I have tried that, but unfortunately that would only cause a redirect in the AuthenticationController, that is invoked via JavaScript. So instead of returning a proper JSON response to the client, it will get a 301/302 response, and an empty body, which will result in nothing happening on logout (besides the local Sitecore logout in the controller of course). – Sune Rievers Oct 23 '16 at 17:24
  • 3
    Updated answer based on your comments – Richard Seal Oct 23 '16 at 20:15
  • I'm pretty sure I tried that one too, will do it again to make sure. If you decompile the GotoLogin, you can see that the RedirectUrl is used here, and default Sitecore login page is used if empty. Since GotoLogin is not used here (at least not in the Logout pipeline), I assume it has no effect. But I will give it a shot, thanks. – Sune Rievers Oct 24 '16 at 6:31
  • 1
    I'm accepting this as answer, as this is the way it SHOULD work. I have implemented a temporary JavaScript-based workaround, until we can upgrade to Sitecore 8.2. Thank you for your input :) – Sune Rievers Oct 25 '16 at 9:15
  • 1
    BTW; you should remove the args.AbortPipeline() - otherwise the redirect at GotoLogin is never executed. I have edited your answer thusly. – Sune Rievers Oct 26 '16 at 6:25

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.