Recently, I´ve been discussing with Anthony MULLER about the possibility of scripting WEBI docs from within the WEBI doc itself through the use of HTML + Javascript.

I´ve been posting some samples about it. The biggest problem with this scripts was that the fact that it needed an aditional authentication or hard code the login and password.

This presents a double problem : security and creating an aditional session for the user.

Since then I´ve been strugling with the possibility of getting the logon token  from the user already logged in. I think that I finally got a solution or the  problem recovering the serialized session from the webi doc.

This is done by this a script inserted in a blank cell of a webi report which “Read As” property of the cell is set to HTML

There are, in fact, two scripts. One when the WEBI doc is opened through BI Launch PAD , and the other when it´s opened via OpenDocument.Following are both

Script 1 – When the DOC is opened through BI LaunchPad

<script>

    var serialToken = new XMLHttpRequest();

    var url =self.top.location.href;

    serialToken.open(‘get’, url, false);

    serialToken.setRequestHeader(‘X-PINGARUNER’, ‘pingpong’);

    serialToken.setRequestHeader(‘Content-Type’, ‘text/html’);

    serialToken.setRequestHeader(‘Accept’, ‘text/html’);

    serialToken.send();

    texto=serialToken.responseText;

    texto=texto.substr(texto.indexOf(‘serializedSession’)+20,texto.length);

    texto=texto.substr(0,texto.indexOf(‘cms’)-3);

    texto=texto.trim();

    seria=texto.substr(0,texto.length-2);

    seria=seria.trim()

    var logon = new XMLHttpRequest();  var url = ‘http://<server>:<port>/biprws/logon/token’;

    var action = ‘logon/long’;

    var response;

    logon.open(‘POST’, url, false);

    logon.setRequestHeader(‘X-PINGARUNER’, ‘pingpong’);

    logon.setRequestHeader(‘Content-Type’, ‘application/xml’);

    logon.setRequestHeader(‘Accept’, ‘application/xml’);

    seria= seria.replace(/&/g,”&amp;”);

    console.log(seria)

    var bodie='<attrs xmlns=”http://www.sap.com/rws/bip“> <attr name=”tokenType” type=”string” possibilities=”token,serializedSession”>serializedSession</attr> <attr name=”logonToken” type=”string”>’+seria+'</attr></attrs>’

    logon.send(bodie);

    token= logon.responseXML.getElementsByTagName(‘attr’)[0].innerHTML;

    token=token.replace(/&amp;/g,”&”);

</script>

The logon token is stored in the variable token.

How it works :

The first HttpRequest calls a .jsp which is responsible for acessing the system and retrieving the document acessed. It will return a HTML page which contains the hard coded serializedSession. The following lines up to the next HttpRequest have the function of parsing the token from the HTML page returned.

The second HttpRequest make a call to the Rest API to get the logon token from the serialized session.

Script 2 – When using OpenDocument

<script>

debugger;

var wini = self.top.document

var txt = wini.childNodes[wini.childNodes.length-1].getElementsByTagName(‘script’)[wini.childNodes[wini.childNodes.length–1].getElementsByTagName(‘script’).length-1].innerHTML;

texto=txt.substr(txt.indexOf(‘serializedSession’)+20,txt.length);

texto=texto.substr(0,texto.indexOf(‘cms’)-3);

texto=texto.trim();

seria=texto.substr(0,texto.length-2);

seria=seria.trim()

var logon = new XMLHttpRequest();  var url = ‘http://<server>:<port>/biprws/logon/token’;

    var action = ‘logon/long’;

    var response;

    logon.open(‘POST’, url, false);

    logon.setRequestHeader(‘X-PINGARUNER’, ‘pingpong’);

    logon.setRequestHeader(‘Content-Type’, ‘application/xml’);

    logon.setRequestHeader(‘Accept’, ‘application/xml’);

    seria= seria.replace(/&/g,”&amp;”);

    console.log(seria)

    var bodie='<attrs xmlns=”http://www.sap.com/rws/bip“> <attr name=”tokenType” type=”string” possibilities=”token,serializedSession”>serializedSession</attr> <attr name=”logonToken” type=”string”>’+seria+'</attr></attrs>’

    logon.send(bodie);

    token= logon.responseXML.getElementsByTagName(‘attr’)[0].innerHTML;

    token=token.replace(/&amp;/g,”&”);

</script>

</script>

Comments will be highly appreciated.

Regards,

Rogerio

OBS : Tahnks to Scott Renaud and Sing Phommavong

To report this post you need to login first.

11 Comments

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

  1. Sing Phommavong

    Hi Rogerio!  Seems awesome but I cannot get it to work in WebI.  I’m using 4.1 SP6 and copy/paste the code in a blank cell.

    Following 2 lines have been changed to reflect my environment.

    Saved the report and relaunch but get a blank.

    I’d like to test with logon/adsso but if I cannot even test it with logon/long, I’m not headed to far 🙂

    Any help on the instructions on how to implement the code in WebI would be appreciated.

    Thanks,

    Sing

    (0) 
    1. Rogerio Plank Post author

      Hi Sing,

      Thanks for your comments.

      In order to work it requires that you view/modify the document in HTML clientes.

      Besides , which browser you’re using?

      Can you check something for me? Press CTRL+12, choose console and give me  a printscreen.

      Regards,

      Rogerio

      (0) 
      1. Sing Phommavong

        Hi, I am using the up to date Chrome browser and I am working on the HTML client where I switch between Reading/Design mode.

        Capture.JPG

        Capture2.JPG

        Here is my version of the code…

        <script>

            var serialToken = new XMLHttpRequest();

            var url =self.top.location.href;

            serialToken.open(‘get’, url, false);

            serialToken.setRequestHeader(‘X-PINGARUNER’, ‘pingpong’);

            serialToken.setRequestHeader(‘Content-Type’, ‘text/html’);

            serialToken.setRequestHeader(‘Accept’, ‘text/html’);

            serialToken.send();

            texto=serialToken.responseText;

            texto=texto.substr(texto.indexOf(‘serializedSession’)+20,texto.length);

            texto=texto.substr(0,texto.indexOf(‘cms’)-3);

            texto=texto.trim();

            seria=texto.substr(0,texto.length-2);

            seria=seria.trim();

            var logon = new XMLHttpRequest(); 

            var url = ‘http://bi4cms:6405/biprws/logon/token‘;

            var action = ‘logon/long’;

            var response;

            logon.open(‘POST’, url, false);

            logon.setRequestHeader(‘X-PINGARUNER’, ‘pingpong’);

            logon.setRequestHeader(‘Content-Type’, ‘application/xml’);

            logon.setRequestHeader(‘Accept’, ‘application/xml’);

            seria= seria.replace(/&/g,”&amp;”);

            console.log(seria);

            var bodie='<attrs xmlns=”http://www.sap.com/rws/bip“> <attr name=”tokenType” type=”string” possibilities=”token,serializedSession”>serializedSession</attr> <attr name=”logonToken” type=”string”>’+seria+'</attr></attrs>’

            logon.send(bodie);

            token= logon.responseXML.getElementsByTagName(‘attr’)[0].innerHTML;

            token=token.replace(/&amp;/g,”&”);

        </script>

        (0) 
        1. Rogerio Plank Post author

          Okay,

          my suggestion is for you to try creating a HTML page using the <script> and loading it into the browser, to check how it´s behaving. It lloks like that your bodie var is being broken down in multiple lines at the execution. You can see that the console error is located just besides

          ‘<attrs xmlns=”http://www.sap.com/rws/bip“> as if there is an linefeed or carriage return, splitting the line.

          Regards,

          Rogerio

          (0) 
          1. Sing Phommavong

            Hi Rogerio.  I’m trying to make it work step by step now and realizing that just getting the serial Token from the WebI doc is giving me a 404…

            My code snippet is basic a possible and I added just something for the display.

            <script>

                var serialToken = new XMLHttpRequest();

                var url =self.top.location.href;

                serialToken.open(‘get’, url, false);

                serialToken.setRequestHeader(‘X-PINGARUNER’, ‘pingpong’);

                serialToken.setRequestHeader(‘Content-Type’, ‘text/html’);

                serialToken.setRequestHeader(‘Accept’, ‘text/html’);

                serialToken.send();

                texto=serialToken.responseText;

                document.write(texto);

            </script>

            Capture.JPG

            I have tried the following code from the other blog that you wrote and it just proves that my Restful Services are working and that the calls I am doing are working.  Username and Password are fictional.

            <script>

            var logon = new XMLHttpRequest();

                var url = ‘http://bi4cms:6405/biprws/logon/long‘;

                var action = ‘logon/long’;

                var body = ‘<?xml version=”1.0″?><attrs xmlns=”http://www.sap.com/rws/bip“><attr name=”userName” type=”string”>biadmin</attr><attr name=”password” type=”string”>123456</attr><attr name=”auth” type=”string” possibilities=”secEnterprise,secLDAP,secWinAD”>secWinAD</attr></attrs>’;

                var response;

                var logonToken;

                logon.open(‘POST’, url, false);

                logon.setRequestHeader(‘X-PINGARUNER’, ‘pingpong’);

                logon.setRequestHeader(‘Content-Type’, ‘application/xml’);

                logon.setRequestHeader(‘Accept’, ‘application/xml’);

                logon.send(body);

               logonToken = logon.getResponseHeader(‘X-SAP-LogonToken’);

               token=logonToken;

               logonToken= logonToken.substring(1,logonToken.length-1);

               logonToken=encodeURIComponent(logonToken).trim();

               document.write(logonToken);

            </script>

            Capture2.JPG

            I understand most of the code to retrieve the serial Token which is quite simple and I would like to display it just to make sure I get something before continuing with the code that would issue the real logon token but I don’t get why the URL to retrieve the WebI serial token is

                var url =self.top.location.href;


            I have tried out both with Chrome using logonNoSso.jsp and also IE 11 with SSO.


            Any pointers?  Thanks you so much for any help and all the quick replies.

            (0) 
            1. Rogerio Plank Post author

              Hi, sorry for the late response. From your printscreen o the error , on the POST call, I could see that there´s an error in the URL being called. Are you acessing the report from BI Launch PAD or by Opendocument ?

              Regards,

              Rogerio

              (0) 
  2. Scott Renaud

    Hi Rogerio,

    I’m currently trying to obtain the current serializedSession, your tactic is interesting but i’m having trouble, here’s what’s happening:

    When I call a Webi directly with its document link:
    https://<server>/BOE/OpenDocument/opendoc/openDocument.jsp?sIDType=CUID&iDocID=AUx3mRyAG_NEkmQYxS8jbFU

    The address automatically changes to:

    https://<server>/BOE/httOpenDocument/1508061404/OpenDocument/opendoc/openDocument.faces?logonSuccessful=true&shareId=9

    **Tracing with F12 I can see that this response has “serializedSession” in it

    Then the script in the cell executes and as per your code it will call:

    https://<server>/BOE/httOpenDocument/1508061404/OpenDocument/opendoc/openDocument.faces?logonSuccessful=true&shareId=9

    but this time the response is different and I don’t see “serializedSession” in the response so I don’t have access to it.

    Am I doing something wrong?

    What is the URL we should be calling, is it really “var url =self.top.location.href;”?

    Thanks a lot!

    Scott

    (0) 
    1. Rogerio Plank Post author

      Hi Scott, you´re right ! I´m calling self.top because it refers to main.do and calling it will give me the serializedToken in the response Text.

      If you can get the serialized token from the call to opneDocument.faces, I suggest you use it.

      I wil post the response Text from the call I do in order for you to check. Please, do a comparison of my response Text and yours.

      It´s on the attachment serializedToken.txt

      Best Regards,

      Rogerio

      (0) 
      1. Scott Renaud

        Hey Rogerio,

        That was it!

        I’m able to make a request directly to “https://<host>/BOE/portal/<sessionnumber>/InfoView/listing/main.do?service=%2Fcommon%2FappService.do&appKind=InfoView”  and I get a serializedSession in the response!

        The only caveat for me was that the <sessionnumber> in the URL should be the number generated at runtime. 

        To get it I was able to call window.location.pathname which gives me this path:
        /BOE/portal/1508061408/zenwebclient/web.do

        Extract the number above and then properly call the URL:
        https://<host>/BOE/portal/1508061408/InfoView/listing/main.do?service=%2Fcommon%2FappService.do&appKind=InfoView” and voila!


        Many thanks for posting this blog, no joke..about 3 weeks ago I was trying to figure out how to obtain the session ID from the platform without having to log in manually and couldn’t figure it out.

        Cheers!

        Scott

        (0) 
        1. Rogerio Plank Post author

          Hi Scott,

          Great news!!!

          Glad to know it worked out!!! I’ m working on JavaScript stuff at the Client side of Webi and have found out very interesting stufff…

          Regards,

          Rogerio

          (0) 

Leave a Reply