cancel
Showing results for 
Search instead for 
Did you mean: 

Trusted Auth token - expiration?

Former Member
0 Kudos

Hello,

We have some issues with tokens obtained via the API for Trusted Authentication that seem to become invalid after some time, and we are not sure why.

In order to take our own product out of the equation, I have written a sandbox program that does the same thing as our integration to BO and gives the same error message. It simply logs in and uses the API to generate a token:

    ISessionMgr sesMgr;

    try {

      sesMgr = CrystalEnterprise.getSessionMgr();

      ITrustedPrincipal principal = sesMgr.createTrustedPrincipal("John.Doe", "123.456.78.90:6400", "SHARED-SECRET");

      IEnterpriseSession enterpriseSession = sesMgr.logon(principal);

      String serializedSession = enterpriseSession.getSerializedSession();

      String defaultToken = enterpriseSession.getLogonTokenMgr().getDefaultToken();

      System.out.println("Token = " + defaultToken);

    } catch (SDKException e) {

      e.printStackTrace();

    }

We can then take the token that is printed out on stdout

TEST-DTK-APP01.foobar.com:6400@17850JG0srJO5za4YoitK17849Ju6r1efEF52BRylA

and use it to construct an openDocument URL like this one:

http://123.456.78.90:8080/OpenDocument/opendoc/openDocument.jsp?sType=wid&token=TEST-DTK-APP01.fooba...

This URL opens up nicely when you paste it into a browser and shows the report without asking the user for credentials. But if we try the exact same URL after 30 minutes, the user is asked for credentials.

I guess it is fair that the tokens expire after a while, but my question is, what decides the validity periods of these tokens? And another question: it seems that the token does not expire when I use it via an API and not a browser. For example, I tried to run this loop that uses the token to make a query to the CMS every 5 minutes for 150 minutes:

      for (int i = 0; i < 30 ; i++) {

        try {

          Thread.sleep(5 * 60 * 1000);

          IEnterpriseSession session2 = sesMgr.logonWithToken(defaultToken);

          IInfoStore infoStore = (IInfoStore) session2.getService("InfoStore");

          String query = "select SI_NAME, SI_ID from CI_INFOOBJECTS "

                   + "where SI_KIND = 'Webi' and SI_INSTANCE=0";

          IInfoObjects infoObjects = (IInfoObjects) infoStore.query(query);

          System.out.println("i = " + i + ", result is: " + infoObjects.toString());

        } catch(InterruptedException ex) {

          System.out.println("Interrupted...");

        }

      }

Since the token became invalid after 30 minutes in the browser, I would have expected this to fail at some point too. But it did not - my log from this program kept showing the list of available reports in the system. Maybe that is because I use the token to create a new session each time?

Thanks,

/Noah

Accepted Solutions (1)

Accepted Solutions (1)

DellSC
Active Contributor
0 Kudos

I'm pretty sure the token expires after 30 minutes of inactivity - since your test program is regularly running a query every 5 minutes, there is never 30 minutes where it's inactive, so it doesn't timeout.

Also, instead of using .getDefaultToken(), I would use something like .createLogonToken("",1440, 10).  The first parameter is then machine name - I usually leave it blank, the second is the number of minutes that the token is value, and the third is the number of times the token can be used to log in before it becomes invalid.

-Dell


Former Member
0 Kudos

Thanks a lot for getting back to me.

There are some tests I need to run to verify and clarify, so I might come back with more questions.

But do you know if the 30 minutes are configurable in BO? I could of course have a parameter in my integration and use that in the createLogonToken(...) method you mention. But I would prefer to change it on the BO side if possible.

Thanks again,

/Noah

DellSC
Active Contributor
0 Kudos

There is no way that I know of to change it on the BO side.

-Dell

Former Member
0 Kudos

Interestingly, this program returns data after 45 minutes, and my the URL stops working after about half an hour, even though I run it every five minutes

  public static void main(String[] args) {

    ISessionMgr sesMgr;

    try {

      sesMgr = CrystalEnterprise.getSessionMgr();

      ITrustedPrincipal principal = sesMgr.createTrustedPrincipal("John.Doe", "123.456.78.90:6400", "SHAREDSECRET");

      IEnterpriseSession enterpriseSession = sesMgr.logon(principal);

      String defaultToken = enterpriseSession.getLogonTokenMgr().getDefaultToken();

      System.out.println("["+ dateString() +"]: Token = " + defaultToken);

      IEnterpriseSession session2 = sesMgr.logonWithToken(defaultToken);

      IInfoStore infoStore = (IInfoStore) session2.getService("InfoStore");

      String query = "select SI_NAME, SI_ID from CI_INFOOBJECTS "

               + "where SI_KIND = 'Webi' and SI_INSTANCE=0";

      IInfoObjects infoObjects = (IInfoObjects) infoStore.query(query);

      System.out.println("["+dateString()+"]: First run, result is: " + infoObjects.toString());

     

      System.out.println("Sleeping for 45 minutes...");

     

      int i = 0;

     

      if (1 == 1) {

        {

          try {

              Thread.sleep(45 * 60 * 1000); // sleep 45 minutes...

              session2 = sesMgr.logonWithToken(defaultToken);

            infoStore = (IInfoStore) session2.getService("InfoStore");

            infoObjects = (IInfoObjects) infoStore.query(query);

            System.out.println("["+dateString()+"]: i = " + i + ", result is: " + infoObjects.toString());

          } catch(InterruptedException ex) {

            System.out.println("["+dateString()+"]: Interrupted...");

          }

        }

      }

    } catch (SDKException e) {

      e.printStackTrace();

    }

  }

The other function you mention (createLogonToken()) seems promising.

Former Member
0 Kudos

OK, thanks for that answer.

Former Member
0 Kudos

Hi Noah,

The methods getDefaultToken() is dependent on enterprise session which created it. If the enterprise session is logged off or timed out the token becomes invalidated automatically.

Where as the token created using the method

createLogonToken(java.lang.String clientComputerName,  int validMinutes,  int validNumOfLogons)

is independent of the enterprise session which created the token.

The token is valid for the validMinutes/validNumofLogons(whichever comes first) set in above method or the token being released using the releaseToken() method.

Thanks,

Prithvi

Former Member
0 Kudos

Thanks, Prithvi

Is the timeout of the enterprise session simply defined by <session-timeout> in the <session-config> section of web.xml?

/Noah

Former Member
0 Kudos

You can refer to the below blog for session management understanding

As you are considering a third party application, you would need to consider the timeout settings of your application along with other parameters mentioned in the above blog.

Thanks,

Prithvi

Former Member
0 Kudos

Thanks a lot for that, it was helpful.

We are currently testing our integration with the createLogonToken() call instead of the getDefaultToken() method, and it looks promising. I will mark this question as answered after Easter pending further results.

One side-question. In the session bible you mention, it is stated that InfoView pings the CMS every two or three minutes to keep the enterpriseSession valid. If we wanted to do something similar in our integration, what is the best way to do such a ping in the Java API? I could not find a dedicated 'ping(servername)' method, so I am assuming any call that actually contacts the CMS will do (like getServiceNames())?

Answers (0)