In one of my previous posts, I mentioned about a way to authenticate user for a web application inside an iFrame in XPiNC page.

Now I found another solution for this. When a user clicks a link inside a Notes Client application, we may authenticate him on the web server application (either XPages or 'legacy' (!) web application)...

This is very important. Because for over 5 years I were searching for such a solution.

Normally, if you are using hybrid application scheme (that is your users are accessing both notes apps and web apps), they need to login to Domino Web server each time. Some companies have problems with password syncronization between Notes password and Internet password and this results in a serious headache!

I know what you think now. By the version 8.5.x, we have SSO with Active directory (SPNEGO). This is a solution. But here are two problems: You need to upgrade your server, configure SPNEGO and only Internet Explorer and certain Firefox versions will be able to use SPNEGO. In addition, some companies have multiple AD domains which makes SPNEGO implementation very difficult.

What may be the purpose of such a tool? One use may be your home page for Lotus Notes users. You may have a portal-like application, listing different applications that user may access. Some applications listed here may be web applications. You may have additional interfaces using XPages for your Notes applications (e.g. reporting) etc.

Before I explain the solution, I want to thank Tim Tripcony, because I am using his suggestion... In addition, I am assuming you have read the post above and skipping some technical details about SSO and LTPAToken concepts.

We first develop a redirector agent for general purposes. We may use a web agent (lotusscript) for this. I used an XPage for simplicity. It basically takes two parameters. 'token' parameter takes the hashed LTPAToken string and 'url' parameter is used for target url. Let's see what it does:

<?xml version="1.0" encoding="UTF-8"?> 
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

      <xp:this.beforePageLoad><![CDATA[#{javascript:try {

response=facesContext.getExternalContext().getResponse();
token=paramValues.get("token").toString();
rUrl=paramValues.get("url").toString();

response.setHeader("Set-Cookie", "LtpaToken=" + token + "; domain=.developi.info; path=/");
facesContext.getExternalContext().redirect(rUrl)

} catch(e) {
      _dump(e);
}
}]]></xp:this.beforePageLoad>

</xp:view>


Here, be careful about the domain parameter at the cookie setting. We may lookup this from the server but there is no need to create a lookup cost, so type in manually...

Now, suppose we have an application and we need to send the user to a web application on the same server without login. I generated a form element and an agent to accomplish this. First, let me explain the agent.

We need to create a session token for this implementation. We will use "session.getSessionToken()" method for this. Unfortunately it is not provided in Lotusscript classes. So we will be using a Java agent for this. The code is here:

public void NotesMain() { 

      try {
              Session session = getSession();
              AgentContext agentContext = session.getAgentContext();
       
              Database db=session.getCurrentDatabase();

              Document doc=agentContext.getDocumentContext();
       
              String token=session.getSessionToken(db.getServer());
       
              try {
                      String token=session.getSessionToken(db.getServer());
                      doc.replaceItemValue("token", token);
              } catch(Exception e) {
                      e.printStackTrace();
                      doc.replaceItemValue("ErrorLog", e.toString());
              }          
       
      } catch(Exception e) {
              e.printStackTrace();
      }
}


We need to pass the token we created back to the caller. So we are using a NotesDocument here. If anything goes wrong, we will return an error message back.

Now let's look at how we are using:

        Dim session As New NotesSession 
      Dim ws As New NotesUIWorkspace        
      Dim dbcurrent As NotesDatabase
      Dim agent As NotesAgent
      Dim doc As NotesDocument
     
      Set dbcurrent=session.currentDatabase
      Set agent=dbcurrent.getAgent("TestAuth")
      Set doc=New NotesDocument(dbcurrent)
     
      Call agent.RunWithDocumentContext(doc)
     
      webServer="https://mobile1.developi.info"
      redirector="/test/redirect.nsf/redirect.xsp"
      target="/names.nsf"
     
      targetUrl=webServer+redirector+"?token="+doc.token(0)+"&url="+target
     
      If doc.ErrorLog(0)="" Then
              Call ws.urlopen(targetUrl)                
      Else
              Msgbox doc.ErrorLog(0)        
      End If


Here '/test/redirect.nsf/redirect.xsp' is the xpages URI we created before. 'TestAuth' is the name of the Java agent.

This code can be placed inside a form for testing. You can modify this to use it on anywhere. For example a common method can be created inside a script library.

Now, before finishing, this code will not be running properly :) We should include some warnings...

First of all, no need to say that: You have to use it on multi-server SSO and your configuration should be working properly. This will work in 8.5.2. If you are using 8.5.1, 'RunWithDocumentContext' method does not exist. Alternatively you should use a real document (not an in-memory one) and pass it to the agent with NoteID. Remember you should delete the temporary document after you're done.

Another warning is about the bug. I cannot create a bug report yet but as I mentioned on the post above, there are important bugs in this 'getSessionToken' method.

1. If you are using Internet Site Documents, getSessionToken does not look up those. I have a workaround here, just duplicate your 'Web SSO Configuration' document and clear 'Organization' field on the second one. It seems crazy, but it works! It's important to duplicate it. Creating a second one from scratch will not work because it should contain the same keys...

2. This one is funnier. Your Web SSO configuration document should be named as LtpaToken... Yes you heard it. Using any other name will fail, because it looks up with this name :)

If you don't care these two bugs, you will end up with an error message: "Single Sign-On configuration is invalid" at the java agent.

One word for performance. This java agent is an expensive thing for Notes client. So if you are willing to use multiple times in a short period, you may use a caching algorithm. We don't want to make our users angry :)

Last word, during my tests, I saw 'Your session has expired' message. It was not so frequent, so I could not figure out why. That may be related with the token. Token should be properly encoded into the URL.

I don't know you, but this is a very important invention for me. I am so excited to share it. I hope it works...
Serdar Basegmez   |   May 11 2011 06:32:53 PM   |    Development  Security  System Administration  Tips  XPages    |  
  |   Next   |   Previous

Comments (18)

Gravatar Image
Serdar Basegmez    http://developi.com    08/22/2016 1:14:59 PM

Viktor,

Glad it worked for you.

I haven't tried for LtpaToken2 but to my knowledge, getSessionToken() will not provide a second token, even though you have the right setting in the web configuration document. I believe Websphere will accept the LtpaToken unless you have configured otherwise. If your setup only accepts LtpaToken2 for security, unfortunately, I have no solution for that.

I will look at it and let you know if I can find a solution.

Thanks.

Gravatar Image
Viktor Geiger    http://atnotes.de    08/22/2016 12:45:38 PM

Hi,

Great Solution I've implemented today in my "DEVELOPMENT" Environment with a Domino WEB SSO Configuration. You're a magician! :-)

Could you give me some ideas how to get a LTPATOKEN2 because I've configured DOMINO AND WEBSPHERE WEB SSO in compatible Mode for IBM Connections and IBM Sametime 9

Gravatar Image
Serdar Basegmez    http://lotusnotus.com    11/02/2012 7:03:26 PM

The problem with @URLOpen, it doesn't support form-based authentication, only basic authentication.

So you might create an web site rule overriding session-based authentication for the redirecting agent/Xagent so it can accept basic authentication.

{ Link }

Gravatar Image
Said       11/02/2012 6:38:08 PM

Hi,

I implemented your solution and it works very well on the development environment.

The only issue is that when I tried to put it into production, the security people did not accept anonymous access to the Domino server.

Currently we are seeking a solution, in which you must use a user defined to connect to the redirector.

I've tried using the following command: @ URLOpen (URL, 0, "UserName", "PasswordInternet")

But it does not work!

Could you help me on this?

Thanks

Gravatar Image
Naseer       06/25/2012 8:36:56 AM

hi, I was able to make it work, thanks, now I have one issue, when I click on the link for the first time it asks for login, when I click again on the same link it opens without asking for login.

thanks

Gravatar Image
Naseer       06/18/2012 1:43:01 PM

Hi Serdar,

Thanks for your reply. How can I use this in web Doc Link for XPages? This link is generated from XPages and send as doclink when the user click this link from Lotus Notes Client it should bypass the login and open the document using XPage.

Regards,

Naseer

Gravatar Image
Serdar Basegmez    http://lotusnotus.com/en    06/13/2012 6:46:08 PM

Naseer,

The trick is creating a shadow document on anywhere. For example, I'm using this in a CEO Blog system. When a blog entry has been posted, I'm creating a new document in another database with URL value of the blog entry. This document is using, say "ShadowBlogPost" form. This form has a QueryOpen event that automatically get a token and launches the URL with my redirect page as in the Lotusscript code I have provided above. Then I'm setting Continue=False to prevent 'actual' document opening.

Then I am sending all users a message containing a document link of this shadow document so when they click that link, auto-login process works.

I'm also checking that if the same form is opened from iNotes or Traveler. This time, I developed a WebQueryOpen agent to redirect the user the blog post.

So the user never sees the intermediate document.

Hope this helps...

Gravatar Image
Naseer       06/13/2012 4:36:49 PM

Serdar,

Can you please give me more details.

regards,

Naseer

Gravatar Image
Serdar Başeğmez    http://lotusnotus.com    06/13/2012 9:18:05 AM

I did this with a little trick. Prepare a shadow document containing the URL you want to open. At query open event you can launch the web URL from lotusscript and prevent the document open.

Gravatar Image
Naseer       06/13/2012 8:45:32 AM

Hi,

I would like to authenticate the user when they click on the web link in their email from their lotus notes client, the link should open in browser without asking for login details.

Regards,

Gravatar Image
Serdar Basegmez    http://www.developi.com    02/22/2012 12:32:47 AM

Neeraj,

You just prepare a link for

(protocol)://servername/names.nsf?logout

That will logout the user. If you wish, you may add a "&redirectto=XXX" parameter at the end of your link and you may redirect the user to a page after logout.

Gravatar Image
neeraj       02/16/2012 2:01:25 PM

Can any one help me to implement logout button in Xpages and it should delete that session

Gravatar Image
Cal       12/09/2011 1:27:23 AM

I have also been looking for a way to make this work for years now. UDAMAN! I haven't got it set up yet but if it works I owe you a pint. Cheers

Gravatar Image
Serdar Basegmez    http://www.developi.com    05/25/2011 6:16:56 PM

@Michel,

Logging as the user who logged in on the Notes client...

I have been asked about some questions.

This method is not going to log in as another user (Admin or any other). It is also possible. As in Jeroen's method, you may create your own LTPAToken in Lotusscript. But you have to encrypt it with the SSO Key. So it will be a great security breach.

In this method, there is a security risk. If somebody listen the trafic, s/he may extract the LTPA token and use it for a limited time. Even you use SSL, the token is transferring over URL which is not encrypted in SSL.

I will try to create a POST request to ensure the security. With this method, you should not use it outside your network...

Gravatar Image
Michel Bassem       05/25/2011 4:46:52 PM

Who do you get logged on as?

Gravatar Image
Serdar Basegmez    http://www.developi.com    05/12/2011 6:26:59 PM

Laura,

Java agent is a standart Java agent. Goto the Agents section in Designer and Create a new agent. In the naming dialog, select Java.

The domain is the part of FQDN address of your server that you include in SSO. For example, if your server is www.developi.com, SSO domain is '.developi.com'.

I will try to isolate my test database in a 'non-busy' time :)

I'll attach it on this page then...

Gravatar Image
Laura       05/12/2011 6:10:34 PM

Hi

Thanks for the info. As a developer fairly new to XPages, I'm struggling to replicate the steps you have described. i.e.,

- How do you create a java agent?

- Where can I find the domain in the XPage re-direct

Could you provide this in a working example? e.g., a local database with a from which links to an XPages via a re-direct?

That would be most helpful for my understanding and actually getting it working!

Thanks

Laura

Gravatar Image
Jeroen       05/12/2011 1:25:58 AM

If you are interested, I made LotusScript-only code that you provide with the key in your sso document and the username and it will happily give you the LTPA value. The entire thing is very well documented.

I use it to do autologin based on IP address and a few other neat tricks such as auto login when referred by another application that can provide a timestamped secret.

jmeijer at notice dot nu