Skip to Content

Though I have been working on UI5 for sometime, I had never explored Logoff functionality. I always thought that it would be as simple as calling an API and redirecting to a logoff page. Once I started, there were so many hurdles and I got to learn a great deal about cookies and authentication. I am sharing this experience in implementing a “Logoff” functionality for a UI5 application. My aim of writing this blog is to share the learning as well as to explore if there are better approaches. Source: Numerous posts on stackoverflow.com

Set Up: UI5 application hosted in a Basis 740 SP5 system as NW Gateway server. 

Loging off a user involves two steps

1. Invalidating the SSO cookies.

2. Deleting the Authentication cache stored by the browsers

Step 1. Invalidating the SSO cookies.

I learned that SAP provides a logoff service which can clear the SSO cookie in the browser. This is a service stored under ‘public’ node. When called as a GET request, this service returns set-cookie headers as response headers with an expiration date in the past. Browser, on receiving the set-cookie, sets these values with the current SSO cookies, thus invalidating them. If you are using a different server to host your UI application, check the documentation to find a similar logoff service.

Step 2. Deleting the Authentication cache stored by the browsers

This step differs from browser to browser. Always abused IE 🙂 does a better job by providing a javascript API to this task. For other browsers, you need to make a call to the server with dummy credentials so that browser receives a “401-Unauthorized” which forces the browser to delete the stored authorization headers. Again ever useful jQuery provides a call back function to handle 401 error so that user is not shown an awkward authorization credentials pop-up.

Below is the code I arrived at. I have only tested on latest versions of Mozilla, Chrome and IE. Also only Basic Authentication scenarios has been tested. Let me know your ideas and suggestions to improve this.


function logoff(){
       $.ajax({
           type: "GET",
           url: "/sap/public/bc/icf/logoff",  //Clear SSO cookies: SAP Provided service to do that
        }).done(function(data){ //Now clear the authentication header stored in the browser
                            if (!document.execCommand("ClearAuthenticationCache")) {
                                 //"ClearAuthenticationCache" will work only for IE. Below code for other browsers
                                 $.ajax({
                                               type: "GET",
                                               url: "/sap/opu/odata/SOME/SERVICE", //any URL to a Gateway service
                                               username: 'dummy', //dummy credentials: when request fails, will clear the authentication header
                                               password: 'dummy',
                                               statusCode: { 401: function() {
                                                         //This empty handler function will prevent authentication pop-up in chrome/firefox
                                               } },
                                               error: function() {
                                                    //alert('reached error of wrong username password')
                                               }
                                });
                            }
        })
}
To report this post you need to login first.

13 Comments

You must be Logged on to comment or reply to a post.

  1. John Patterson

    Hi Krishna

     

    I have had to do something similar before, the requirement was to trigger a clean up when the user closed the browser or redirected

     

    jQuery(window).bind(“unload”, this.exit);

     

    when the application loads bind the exit function to the unload event, the exit function did a few things including clearing the user context.

     

    with the unload event you have a very small amount of time to do your processing, often it  wont wait round for an async callback, so i use a synchronous call instead

     

    something like

    var oResponse = jQuery.sap.sjax({ url: sLogoffURL });

    if (oResponse.success) { …

    }

     

    jsp

    (0) 
  2. Martin Cook

    For the solution we used a different approach, we did a page re-direct to a logout page and then cleared the cache using the below code

    <script type=”text/javascript”>

       try

       {

           document.execCommand( “ClearAuthenticationCache”,”false” );

       }

       catch(e)

       {

       }

    </script>

    This worked on Mozilla, Chrome, Safari and IE.

     

    Martin

    (0) 
    1. Krishna Kishor Kammaje Post author

      Martin, Someone has to clear the SSO cookies. How did you achieve that?

      What I saw was, even if I has missed one of the steps (SSO cookie and authentication cache), the application would login using the missed step.

      (0) 
  3. Martin Cook

    Sorry did not expand on the set-up for the logout page, we running the application as BSP so we define the logout page with the below ABAP

     

     

    <%
      CLASS cl_bsp_login_application DEFINITION LOAD.
      DATA: lv_url TYPE string,
      lv_params type string,
      lv_path type string.

      CONCATENATE ‘/sap/public/bsp/sap/public/bc/bsp/Logout.htm?IV_LANGUAGE=’ IV_LANGUAGE into lv_path.

      lv_url = CL_BSP_LOGIN_APPLICATION=>GET_SESSIONEXIT_URL( ).
      lv_url = cl_http_utility=>escape_html( lv_url ).
      lv_params = CL_BSP_LOGIN_APPLICATION=>SET_LOGOFF_URL_PARAM( url = lv_path ).
      CONCATENATE CL_BSP_LOGIN_APPLICATION=>CO_BSP_APPLICATION lv_params

      INTO lv_params SEPARATED BY ‘=’.

      lv_params = cl_http_utility=>escape_html( lv_params ).

    %>

     

     

    Then do the re-direct with the below HTML

     

     

          var url = “<%= lv_url%>”;

          url += “&<%= lv_params%>”;

          self.location.href=url;

     

    So yes you correct the ClearAuthenticationCache is our fail safe for IE.

     

    Sorry for the not providing the complete picture.

     

    Martin

     

    (0) 
  4. Thushar Alva

    Hi Krishna,

    I tried to logout in my application using your code, I could logout from the desktop but I was not able logout in the mobile browser.when i clicked logout it shows authorization credential popup.

    (0) 
  5. Khabir Ahmad Raja

    Thank you Karishna for such an excellent solution. Here I have enhanced your code so that the browser redirect itself to some useful web page or login page again after logoff.

     

    1. function logoff(){ 
    2.        $.ajax({ 
    3.            type: “GET”
    4.            url: “/sap/public/bc/icf/logoff”//Clear SSO cookies: SAP Provided service to do that 
    5.         }).done(function(data){ //Now clear the authentication header stored in the browser 
    6.                             if (!document.execCommand(“ClearAuthenticationCache”)) { 
    7.                                  //”ClearAuthenticationCache” will work only for IE. Below code for other browsers 
    8.                                  $.ajax({ 
    9.                                                type: “GET”
    10.                                                url: “/sap/opu/odata/SOME/SERVICE”, //any URL to a Gateway service 
    11.                                                username: ‘dummy’, //dummy credentials: when request fails, will clear the authentication header 
    12.                                                password: ‘dummy’
    13.                                                statusCode: { 401: function() { 
    14.                                                          //This empty handler function will prevent authentication pop-up in chrome/firefox 
    15.                                                } }, 
    16.                                                error: function() { 
    17.                                                     //alert(‘reached error of wrong username password’) 
    18.                                                } 
    19.                                 }); 
    20.                             }
    21.                             window.location.reload(true);     // Reloads page at same location
    22.         }) 
    (0) 
  6. Lulu Mo

    Thank you Krishna, it works for me.

     

    shell.attachLogoutButtonPress(function() {

      $.ajax({ 
               type: “GET”, 
               url: “/sap/public/bc/icf/logoff”,  //Clear SSO cookies: SAP Provided service to do that 
            }).done(function(data){ //Now clear the authentication header stored in the browser 

                    if (!document.execCommand(“ClearAuthenticationCache”)) { 

                         //”ClearAuthenticationCache” will work only for IE. Below code for other browsers 

                         $.ajax({ 

                                       type: “GET”, 

                                       url: “/sap/opu/odata/SOME/SERVICE”, //any URL to a Gateway service 

                                       username: ‘dummy’, //dummy credentials: when request fails, will clear the authentication header 

                                       password: ‘dummy’, 

                                       statusCode: { 401: function() {

                                   //This empty handler function will prevent authentication pop-up in chrome/firefox 
                                   window.open(“http://www.sap.com“,”_self”);                                            

                                       } }, 

                                       error: function() { 

                                            //alert(‘reached error of wrong username password’) 

                                       } 

                        }); 

                      } 

            }) 
    });
    (0) 
    1. Firoz Ashraf

      Hi Lulu,

      I have enabled the “logoff” through the following coding in my index.html file

       

      var oAppHeader = new sap.ui.commons.ApplicationHeader(“appHeader”);

            oAppHeader.setDisplayLogoff(true);

       

      Now where do I need to write the code as mentioned by you?

      In the main controller? or somewhere else?

       

      Regards,

      Firoz.

      (0) 
      1. Firoz Ashraf

        Got it !!

         

        The code has to be placed as shown below:

         

        var oAppHeader = new sap.ui.commons.ApplicationHeader(“appHeader”).attachLogoff(function(){

         

        /////////////LOG OFF FUNCTION CODE STARTS HERE/////////////

         

        });

         

        Thanks.

        (0) 

Leave a Reply