Developing TAI’s for Websphere Application Server

Trust Association Interceptors (or TAI’s) for Websphere Application Server is quickly becoming my new favorite technology. They just might be best thing since sliced bread and the reason why why you want to embrace Websphere Application Server. And so quickly.

I have discussed TAI’s and why they’re important in an earlier blog post.

One thing to know however is when developing them you need to have the necessary stuff in place. For TAI’s these are the JAR required on the class path and they are:

  • <WASHOME>runtimescom.ibm.ws.webservices.thinclient_6.1.0.jar
  • <WASHOME>libbootstrap.jar
  • <WASHOME>libcom.ibm.ws.runtime.jar
  • <WASHOME>libj2ee.jar

After that it’s a matter of creating a new class and implementing the com.ibm.wsspi.security.tai.TrustAssociationInterceptor interface which only contains two methods:

  • public boolean isTargetInterceptor (HttpServletRequest req)
    “The isTargetInterceptor method determines whether the request originated with the proxy server that is associated with the interceptor. The implementation code must examine the incoming request object and determine if the proxy server that forwards the request is a valid proxy server for this interceptor. The result of this method determines whether the interceptor processes the request.”
  • public TAIResult negotiateValidateandEstablishTrust (HttpServletRequest req, HttpServletResponse res)
    “The negotiateValidateandEstablishTrust method determines whether to trust the proxy server from which the request originated. The implementation code must authenticate the proxy server. The authentication mechanism is proxy-server specific. For example, in the product implementation for the WebSEAL server, this method retrieves the basic authentication information from the HTTP header and validates the information against the user registry that WebSphere Application Serve uses. If the credentials are not valid, the code creates the WebTrustAssociationException exception, which indicates that the proxy server is not trusted and the request is denied. If the credentials are valid, the code returns a TAIResult result, which indicates the status of the request processing with the client identity (Subject and principal name) to use for authorizing the Web resource.”

In short isTargetInterceptor is called to determine if a given request matches a given TAI and if it returns true negotiateValidateandEstablishTrust is called to determine if this TAI could authenticate the user and that the username (“Subject”) is. Very easy.

It’s important to note that “authenticate” could mean whatever you decide it means. That is you could actually do some work to authenticate the request but you could just as well simply decide that the user is authenticated and that the username is “John Doe123”. Whether the authentication is done based on “real authentication”, based on a cookie being set or something else is entirely up to you. That’s why it’s so powerful.

Once deemed authenticated by negotiateValidateandEstablishTrust a valid LtpaToken/LtpaToken2 is generated and the user is granted access into the Kingdom.

Infocenter:
Trust association interceptor support for Subject creation

Do you care for TAI? You really should!!

Websphere Application Server is a beast. A big beast. But it’s a beast that good (even great?!) on a lot of levels and it’s definitely not as bad as you might think and it comes with a lot of goodness and loads of functionality. One of the real cool things about Websphere Application Server is the ability you have to extend the core application server (which is something that is hard – becoming easier but still hard – with Lotus Domino). The extendibility I want to mention today is Trust Association Interceptors – or TAI for short.

A Trust Association Interceptor is an exciting piece of technology that has been part of Websphere Application Server for quite a while and a technology that is becoming my new best friend. It’s objective is to sit between an incoming request and the application server runtime and let you manage the authentication state of incoming requests. Think DSAPI filters to manage authentication if you will except that TAI’s are written in Java and much easier to write, test, debug and deploy.

If you have a reverse proxy such as WebSEAL the way you make it work with Websphere Application server today is by installing a TAI into the application server. It’s also the way that SPNEGO support is added. As with many Java technologies you could just as well write your own – and it’s dead easy. It’s even well documented in the IBM Infocenter. So why would you want to do so? Well imagine if you’re installing IBM Connections and have an existing SSO solution you want to reuse to authentication. Writing a TAI lets you do that with a minimal hazzle.

I’ll post about how you actually go ahead and write a Trust Association Interceptor later.

When the default isn’t enough – creating a new Lotus Connections Files policy

As posted earlier today I had to change the default maximum library size of in Lotus Connections Files to accommodate a particular user. Of course 1 GB (double of the default) wasn’t enough so I created a new policy for that particular user and assigned it. I was very easy as well. Below are the wsadmin commands.

wsadmin<FilesPolicyService.add("2GB Policy", 2097152000)
A policy was added with the new id 584f818a-106c-4343-
8f40-63ceb0ac5c5f .

wsadmin<FilesLibraryService.assignPolicy(
   "1a60c8d1-fc59-41bc-9d89-c266a9709230",
   "584f818a-106c-4343-8f40-63ceb0ac5c5f")
The policy with the id 584f818a-106c-4343-8f40-
63ceb0ac5c5f is now assigned to the library with the id
1a60c8d1-fc59-41bc-9d89-c266a9709230.

Lotus Connections and extending Files Library Sizes

Funny thing at a Lotus Connections customer today. A user was complaining that he wasn’t able to upload a new version of a file into his Files due to size restrictions. After poking around I found out that the user had uploaded 492 mb of data into Files. After poking some more I found out that a maximum library size is enforced based on policy. By default all users are assigned a policy that allows for 524 mb of data hence why he was unable to upload any more data.

To solve it I changed the default policy to allow for 1 gb of data per user (after asking management). This is done using the administrative service API for Lotus Connections which is quite extensive. Below are my steps with the key values in bold.

The steps are as follows:

  1. Initialize the wsadmin environment
  2. Get access to the Files administrative services
  3. Find the user id using FilesMemberService.getByEmail(email) (user id is f631a9d9-07c4-4dcc-b820-1fdaefc4895c)
  4. Find the users library id using FilesLibraryService.getPersonalByOwnerId(id) usig the just found user id (library id is 1a60c8d1-fc59-41bc-9d89-c266a9709230). This also shows the user is controlled by the default policy (policy id 00000000-0000-0000-0000-000000000000) and that he is using 93% of the allotted space)
  5. Edit the default policy using FilesPolicyService.edit(id, name, size) to set a new size of twice the original size)
  6. Refetch information about the users library using FilesLibraryService.getPersonalByOwnerId(id) to see that the new library size has been applied

D:IBMWASprofilesAppSrv01bin>wsadmin -username wasadmin
-password <password> -lang jython
WASX7209I: Connected to process "server1" on node SDKFU016Node01
using SOAP connector;  The type of process is: UnManagedProcess
WASX7031I: For help, enter: "print Help.help()"

wsadmin>execfile("filesAdmin.py")
Files Administration initialized.

wsadmin>FilesMemberService.getByEmail("jdoe@example.com")
{isOprhan=false, email=jdoe@example.com,
directoryLastUpdate=2011-01-04 17:07:57.167,
id=f631a9d9-07c4-4dcc-b820-1fdaefc4895c, name=John Doe,
createDate=2010-02-19 13:04:36.404, communityLastUpdate=2011-01-04
17:12:25.084, lastVisit=2011-01-04 17:07:57.167,
directoryGroupLastUpdate=2011-01-04 17:12:25.084}

wsadmin>FilesLibraryService.
   getPersonalByOwnerId("f631a9d9-07c4-4dcc-b820-1fdaefc4895c")
{lastUpdate=2010-02-19 13:04:36.467, externalInstanceId=null,
id=1a60c8d1-fc59-41bc-9d89-c266a9709230, type=personal,
ownerUserId=f631a9d9-07c4-4dcc-b820-1fdaefc4895c, title=John Doe,
label=24924863-F97C-C455-C125-74C9004077E4, externalContainerId=null,
policyId=00000000-0000-0000-0000-000000000000, createDate=2010-02-19
13:04:36.467, summary=, percentUsed=0.9382985649108887,
maximumSize=524288000, size=491938678}

wsadmin>FilesPolicyService
   .edit("00000000-0000-0000-0000-000000000000",
   "Default Policy", 1048576000)
The policy with the id 00000000-0000-0000-0000-000000000000 was
   updated successfully.

wsadmin>FilesLibraryService
   .getPersonalByOwnerId("f631a9d9-07c4-4dcc-b820-1fdaefc4895c")
{lastUpdate=2010-02-19 13:04:36.467, externalInstanceId=null,
id=1a60c8d1-fc59-41bc-9d89-c266a9709230, type=personal,
ownerUserId=f631a9d9-07c4-4dcc-b820-1fdaefc4895c, title=John Doe,
label=24924863-F97C-C455-C125-74C9004077E4, externalContainerId=null,
policyId=00000000-0000-0000-0000-000000000000, createDate=2010-02-19
13:04:36.467, summary=, percentUsed=0.46914928245544435,
maximumSize=1048576000, size=491938678}

wsadmin>

Maintaining a Lotus Connections environment? Well then you MUST see this!

Today a new article on Lotus Connections was posted on developerWorks and it shows you how to install an administration interface for Lotus Connections into Websphere ISC (Integrated Solutions Console). The interface provides easier access to Lotus Connections configuration files and looks like a real killer plugin for ISC. I have got to try and install it tomorrow and see for myself as this is something that has been sorely lacking.

The article is called Introducing the IBM Lotus Connections administration web interface and below is a snippet from the article introduction.

“The administration console utilizes a series of Jython and Jacl script files to allow administrators to work with Lotus Connections. These files provide automated ways to access the Lotus Connections MBeans that change back-end settings in databases and configuration files that service a deployment. Working with these Jython and Jacl script files requires some programming and scripting knowledge; the ability to import packages in the terminal, assign and use variables, and other basic programming concepts, all in the Jython or Jacl languages, are required. These languages, while not inherently hard languages to use, are relatively specialized and might be unfamiliar to the average Lotus Connections administrator. Removing control of Lotus Connections from the administration console and putting it into a web-based solution alleviate the need for specialized skills, providing a cost of ownership reduction to Lotus Connections customers.”

Websphere Terminology for newcomers

Found this very good document describing the terminology from Websphere Application Server for people new to the platform. So if you’re unsure of the exact difference between a cell, node, profile and a cluster I suggest you peruse this document. I also recommend printing the graphics on page 4 and keeping it nearby.

Overview of IBM WebSphere Application Terminology for IBM
Lotus Connections Administrators

Solving a Lotus Connections 2.5 login performance issue

During the last week I have been diagnosing a login performance issue at a Lotus Connections 2.5 customer. The issue manifested itself by it taking around a minute for some users to login. It was only an issue for the initial login hence it was caused by something that the Websphere server cached on subsequent login attempts.

After diagnosing and making sure the install was at the latest fixpack and fixlevel from Fix Central, I finally found out what was going on. By using the Websphere Application Server trace functionality it became apparent that it was the Waltz / Directory Service Extension (DSX) component of Lotus Connections that was causing the problem. The issue was that Waltz took a very long time to resolve the groups the user belonged to and hence login took forever.

Waltz is using the federated repository LDAP setup from Websphere so for starters I found a workaround. The workaround was to disable group support in the Integrated Solutions Console (ISC) by setting a custom group search filter (e.g. objectClass=dummy). This works but also means you’re turning of group support completely.

A better solution which also works is to modify the Waltz setup in the directory.services.xml file in the LotusConnections-config directory. By default the top section looked like this:

<!-- *************************** -->
<!--   Waltz Profile Provider    -->
<!-- *************************** -->
<profileProvider
   class="com.ibm.connections.directory.
      services.provider.WaltzServiceProvider" />

Reading through the file and using the schema as a guideline I could add an option to disable the group expansion i Waltz by embedding a property-tag beneath the profileProvider-tag as shown below.

<!-- *************************** -->
<!--   Waltz Profile Provider    -->
<!-- *************************** -->
<profileProvider
   class="com.ibm.connections.directory.
      services.provider.WaltzServiceProvider">
   <property name="com.ibm.connections.directory.
      services.ldap.group.membership.service.enabled">false</property>
</profileProvider>

Lotus Connections seems to be working just fine despite this option being set though I’m not completely sure of all side effects. I’ll post more if/when I learn more.

Websphere Application Server Security – make sure file based auth continues if federated repository is unavailable

While looking for another tidbit of information on Google I found this very interesting setting in a WAS FAQ (Q & A: Frequently asked questions about WebSphere Application Server security). That fact that access to the Integrated Solutions Console (ISC) would stop if a LDAP directory was unavailable even though the ISC admin account was local has been bothering me for a while. It was nice to see that this fact which has been irritating me for a while (when it isn’t set) is solvable.

7. When using a federated repository, is there a way to ensure that my file-based registry will continue to function when a LDAP server is down?

Yes, there is a configuration option that enables the authentication to continue if one or more other registries are down, as long as the ID is found in one of the registries that are still up and functional. The federated repository configuration command to permit this is:

$AdminTask createIdMgrRealm
     -name ibmRealm -allowOperationIfReposDown true

More information can be found in the Information Center article: IdMgrRealmConfig command group for the AdminTask object.

Installing Lotus Connections 2.5 on Windows 2008 Server

The last two weeks I have had the honor of installing Lotus Connections 2.5 on Windows 2008 Server 64 bit with Microsoft SQL Server 2005. Twice. And what a change from my normal Windows 2003 Server. In this blog post I’ll outline some of the issues I ran into and what I had to pay special attention to.

First off Tivoli Directory Integrator 6.1.1 (the component that move data from LDAP to the Profiles SQL database) isn’t supported and doesn’t run on Windows 2008 Server. The TDI scripts provided with Lotus Connections 2.5 doesn’t work with TDI 7 which leaves you at a dead stop. Only solution as of now is to find a Windows 2003 Server or other Windows platform to run TDI. Hopefully Lotus Connections NEXT will use TDI 7.

Next issue I had to address was that Websphere Applicaton Server (WAS) 6.1 should be at fixlevel 19 before you create any profiles on a Windows 2008 Server. This meant that the profile couldn’t be created as part of the WAS installer. This wasn’t too big of an issue as it’s a best practice not create the profile during setup anyway. A benefit of doing it this way is that it allows you to create the profile in another location than between your WAS binary directory.

So all was well and good? Not really as the GUI tool to manage profiles isn’t supported on Windows 2008 Server either. There is however a manageprofiles command to manage profiles which may be used. The command looks rather convoluted but it goes something like this (I ran it was admin):

manageprofiles.bat -create -profileName AppSrv01
   -profilePath d:WASProfilesAppSrv01
   -templatePath c:ibmwebsphereappserverprofileTemplatesdefault
   -nodeName LotusConnectionsNode01
   -cellName LotusConnectionsCell01
   -hostName lc.example.com
   -isDefault
   -winserviceCheck true
   -winserviceAccountType specifieduser
   -winserviceUserName username
   -winservicePassword password
   -winserviceStartupType manual

The last few arguments create the Windows service. I have had some success doing this but most times I leave the “winservice”-arguments out and use WASService.exe to create the service instead.

wasservice -add LotusConnections
   -serverName server1
   -profilePath d:wasprofilesappsrv01
   -startupType automatic

When I installed Lotus Connection I had to run install.bat as admin to avoid having the SQL connection check fail.

Generally in Windows 2008 Server I found that paying special attention to drive and folder security made my life a lot easier. That goes for both WAS and IBM HTTP Server IHS). Additionally on one IHS server I had to manually install GSKit to enable SSL as it wasn’t installed by the installer. I also had to put GSKit (C:IBMGSK7lib) on the PATH in Windows. To symptom was that IHS couldn’t access the SSL keystore.

I hope this will help someone.

Speed up WAS restart when configuring with Lotus Connections

When installing and configuring Lotus Connections or any other Websphere Application Server based application you’ll probably find it beneficial to speed up restarting WAS. I found that disabling auto-start of some of the Lotus Connections applications was an easy way to do this. I simply followed the steps in “Websphere Experience: Startup behavior of an application” to do it.

For the people not afraid of XML-files you might as well simply edit the deployment.xml file(s) in <profile path>configcells<cell name>applications<application name>.eardeployments<application name> and set enabled=”false” for the <targetMappings>-tags at the top. As always with editing files directly – proceed at your own risk… 🙂