You are on page 1of 16

IBM Cognos Proven Practices: Adding Single Sign-On to your IBM Cognos 8 Custom Java Authentication Provider

Nature of Document: Technique; Product(s): IBM Cognos 8; Area of Interest: Security; Version: 1.0
Cognos Proven Practices Team Cognos Proven Practices Team IBM Skill Level: Advanced Date: 28 Jul 2010

This document describes how one can implement SSO to his Custom Java Authentication Provider by explaining the required concepts. This documents supplements SDK documentation. View more content in this series

Introduction
Purpose The Custom Java Authentication Provider Developer Guide which is part of the standard IBM Cognos 8 SDK documentation delivers the main concepts required to code a Custom Java Authentication Provider (CJAP). It even describes what authentication can be based on and how to request additional information from the entry point. However, the description is overly brief and lacks an example of actually leveraging those techniques to add support for Single Sign-On (SSO) to a full Custom Java Authentication Provider. This however may be required to deliver a comprehensive solution to the client. In this document the background of the authentication process is provided along with descriptive information on how to use the provided SDK to handle SSO. As an example SSO support will be added to the "JDBCSample" CJAP delivered as part of the SDK samples. Applicability The concepts and backgrounds published in this document apply to all versions of IBM Cognos 8.
Copyright IBM Corporation 2010 IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Trademarks Page 1 of 16

developerWorks

ibm.com/developerWorks/

The code examples in this document were developed and tested using IBM Cognos 8.4.1. While the author cannot guarantee that the code examples will work without adjustment he's not aware of any other technical prerequisites than recompile the (adjusted) source code of the JDBCSample with a proper JRE version to make the code work in other versions of the product. Exclusions and Exceptions The document will not cover designing and coding Custom Java Authentication Providers (CJAP) in general. The only aspect covered herein will be adding support for Single Sign-on (SSO) to a full authentication provider. The use of the example code (JDBCSample) requires that the IBM Cognos 8 SDK is installed and licensed. It is expected that the reader is familiar with the CJAP SDK and Java programming.

Authentication in IBM Cognos 8


This chapter is going to provide a comprehensive description of the concepts and components involved with the authentication process in IBM Cognos 8. Requests and Sessions Users (browsers) or code (an SDK application) send requests to IBM Cognos 8 by establishing a HTTP session with a Cognos entry point (EP). Valid entry points are either an IBM Cognos 8 Dispatcher accessed directly or, adhering to best practices, an IBM Cognos 8 Gateway deployed to a web server. Since IBM Cognos 8 is based on a service oriented architecture (SOA) the overall functionality provided by the Cognos system is implemented by a set of independent services communicating externally and amongst each others using the SOAP protocol. For this reason each request sent to an IBM Cognos 8 entry point will have to be routed to some target service which can handle it. Each of the services making up IBM Cognos 8 handles different types of requests and routing is one of the main concepts of the IBM Cognos 8 architecture. Routing is handled by the IBM Cognos 8 Dispatcher Service. Regardless whether a request was sent to a Dispatcher directly or via a Gateway (each Gateway will relay it's request to a single Dispatcher denoted in it's configuration), it will be handled by an instance of Dispatcher Service on the accessed Dispatcher. The Dispatcher Service will create a new sessionID if this is the first request received in that very HTTP session. Next a requestID will be assigned to the request and both sessionID and requestID are added to the request. All subsequent requests in the same HTTP session can be identified now because they share the same sessionID. As services are logically independent from each other practically all of them will require authentication before they will handle a request to prevent unintended
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 2 of 16

ibm.com/developerWorks/

developerWorks

access. Authentication in this context means, that the session the request is part of is authenticated and hence the request originates from an authenticated sender. For IBM Cognos 8 authentication functionality is centrally offered by the Content Manager (CM) Service. Consequently all other IBM Cognos 8 services will employ the CM Service to verify session authentication or trigger authentication for yet unauthenticated sessions. As soon as a request is handled by an instance of Dispatcher Service that service will first of all check the authentication status for the given session. If the session was not authenticated yet the Dispatcher Service will employ the CM Service to run the authentication process and pass off the request to it. The CM Service will pass on the request to the Cognos Access Manager (CAM) component, a sub component of CM which handles authentication, authorization and administration (AAA) and encryption (CRP). Its the AAA sub-component of CAM which will then employ authentication providers configured for IBM Cognos 8 to access authentication sources, to read information about a user from it and eventually authenticate the request and hence the session. Figure 1 schematics of authentication

If the authentication is successful the authentication information is persisted in Content Store and a reference is added to the session so subsequent requests wont get passed to CAM as all services can deduct some reference to the authentication information from the session directly now and have CM Service verify it where applicable.

IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider

Page 3 of 16

developerWorks

ibm.com/developerWorks/

After some configurable amount of idle time a session will time out and the Dispatcher Service will request CAM to authenticate the session again. Authentication providers IBM Cognos 8 authentication providers are software modules implemented in Java or C++ which interface with the Cognos Access Manager (CAM) component. There are two types of authentication providers, as documented in the Custom Authentication Provider Developer Guide. A full authentication provider implements functions to authenticate provided credentials against some authentication source which stores and manages entries of type user, group and/or role. In addition it provides support for searching entries and is respecting hierarchical structures of the authentication source. An authentication provider has to support at least one method of authentication, possibly multiple and it can support single sign-on support as well. A trusted sign-on provider (TSP) though offers very limited functionality for a single purpose. In single sign-on scenarios it reads in a token from the session possibly placed in the session by some higher-level authentication layer which identifies a user. The assumption is that this token is not consumable by any other IBM Cognos 8 authentication provider directly. The TSP transforms the information in the token into something a full authentication provider can consume and passes the authentication process on to a second, full authentication provider. It does NOT authenticate the user, it simply relays and transforms information and thus does not result in a namespace entry to appear in Cognos Connections Directory tool. Below table depicts which authentication providers are provided by IBM Cognos 8 out of the box. Not every provider is available on every platform though. On Linux and HP-UX Itanium the LDAP provider is the only one available. In addition to those out of the box providers customers can implement their own authentication providers using the Custom Authentication Provider SDK (part of the IBM Cognos 8 SDK) which is provided for Java only. Authentication providers coded based on this SDK are called a Custom Java Authentication Provider (CJAP) and can either be of type full or TSP. As a matter of fact there is already a CJAP included with the product for single sign-on to Portal Servers, the Shared Secret provider.

IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider

Page 4 of 16

ibm.com/developerWorks/

developerWorks

Windows Active Directory NTLM SAP Series 7 LDAP CA Siteminder (TSP) Shared Secret (CJAP,TSP) yes yes yes yes yes yes

UNIX no no yes yes yes yes

Linux, HPUX Itanium no no no no yes no

yes

yes

yes

All providers, except CJAPs which use proprietary configuration methods, get configured through a namespace configuration (resource) which is created in Cognos Configuration. In there, properties specific for that provider instance can be configured. Upon start of IBM Cognos 8 Content Manager the configuration is scanned for namespace configurations and the respective providers get initialized based on the settings configured. As of IBM Cognos 8 all out of the box providers support the Test functionality which is available by right-clicking on a namespace configuration element in Cognos Configurations explorer tree. What this does is initializing the provider with the configured settings to a certain extent. The test however may not be conclusive to all the functionality the provider supports, it's meant to catch obvious configuration errors and connectivity issues only. The authentication process in general When CAM receives a request to authenticate the first decision about the type of authentication is made based on configuration. If the system is configured to allow anonymous access, then sessions will become authenticated using a special anonymous user as there are no real anonymous sessions in IBM Cognos 8. An internal authentication provider is used to implement this functionality which is neither visible nor configurable. Some hard coded dummy user credentials, neither containing username nor password will be used and hence no login is required. For named (=non anonymous) access CAM will use the configured authentication providers to authenticate the request and hence it is passed to one of the configured providers. Which one is determined based on availability (which providers did initialize correctly) and some parameter which contains the namespaceID of the namespace to use.

IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider

Page 5 of 16

developerWorks

ibm.com/developerWorks/

While it is easiest to expect that a single request contains all the logon data (information required for authentication) at once, like the namespace to authenticate to and credentials this may not hold true for all use cases. For this the architecture implements a concept of returning qualified responses to the sender which triggers him to send another new request with additional information attached. That way an authentication provider can request additional information from either the sender (user or SDK program) or even the entry point (Gateway or Dispatcher) the request came in through. Typical applications of those call-backs are prompting the user to enter his credentials, have the user choose one out of several configured authentication providers or have the entry point retrieve some trusted variable value from it's environment which is typical for SSO. Each request sent to CAM is treated independently but a sequence of requests may constitute the logon process for a given session. This is what's described in three scenarios in the Custom Authentication Provider Developer Guide in chapter 2, Authentication Requests: flow scenarios. Only once a single request contains all the required logon data the provider will actually try to authenticate the request. Before continuing to the next step of the authentication let's look at the types of logon data a provider can/will accept/require. Logon Data There are four possible ways to pass logon data in a request to the authentication provider. Trusted credentials (TCs) Credentials of this type have been created for an IBM Cognos 8 user by some authentication provider in the past and were stored (encrypted) in Content Store. For example a schedule will have a reference to TCs (a credential path) stored along with it. Technically they can be a binary token or string(s) like username (and password). Only the credential path is passed in requests though, TCs never leave the Content Store. When receiving a TC an authentication provider will not verify their origin or consistency explicitly but implicitly only. The function getTrustedCredentialValue() capsulates the retrieval of the actual credential value form Content Store and decrypting it thus verifying integrity and origin. The provider simply has to run authentication against the authentication source. TCs may expire though, if for example the password has been changed in the authentication source after they have been stored in Content Manager. In that case they must be renewed through Cognos Connection by the user they belong to himself. Credentials Credentials also known as SDK Credentials are sent by SDK programs when authenticating to IBM Cognos 8. Technically they will be strings, likely user
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 6 of 16

ibm.com/developerWorks/

developerWorks

name and - possibly but not mandatory - a password. The credentials will be passed in the request in clear text unless SSL is used. An authentication provider will verify them against the authentication source. Form fields - Username and Password If running Basic Authentication, that means a user is prompted to enter username and password, the HTML code will submit the credentials entered in two predefined FORM fields. They will be visible in the request to the entry point but as soon as the request is parsed by a Gateway it will obscure the password in the request passed to CAM. If the entry point is a Dispatcher that functionality is not supported. (Trusted) Environment variables,cookies or generic SSO tokens Authentication providers may allow reading user identity information from an environment variable or some binary token. The values of those variables or tokens are never read from the request directly but rather get provided by the entry point component through the call-backs mentioned before. It evolves that support for these call-backs requires code in the entry point layer components as well. The only binary SSO token currently supported (on Windows Gateways only) is a Microsoft Windows Kerberos token. The respective code for environment variables (supported on any platform for Gateway and Dispatcher) accepts generic variables though, both trusted (eg. REMOTE_USER, USER_PRINCIPAL) and arbitrary variables (HTTP_REFERRER, HTTP_xxxx). All full authentication providers delivered with the product support those four ways. Custom Java Authentication Providers may choose to support only some of those or different ones all together. Persisting authentication information in the sessions When serving a request the authentication provider will reach out to its authentication source and read information from it to verify the passed identity information. If authentication succeeds, the provider will issue a visa for the namespace the user/client was authenticated against. A Visa maintains the users security context, that is the logon data (whatever was used to authenticate to IBM Cognos 8), and his identity (the groups and roles hes a member of). The visa will be used to derive credentials (saved logon data from previous authentication to pass to other services) which will be used whenever another IBM Cognos 8 service requests authentication or for example when scheduling reports or to authenticate to a data source. The visa will be added to a CAM in-memory table which will hold all active visas. All the visas for a single session and hence a user/client, one for each namespace to which authentication has been successfully completed, make up a Passport. They share the same primary key in that table the Passport ID. Only this Passport ID is exposed external to CAM as a reference. Its that Passport ID which is returned to CM and the user/client.
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 7 of 16

developerWorks

ibm.com/developerWorks/

In case of a browser client the Passport ID is stored in a session cookie in the browser memory, for SDK its the applications duty to manage the Passport ID for the duration of the session. Request additional information (The authentication dance) If a request doesnt contain enough information to complete the authentication transaction right now the authentication provider will use the call-back functionality mentioned earlier. This feature allows an authentication provider to request additional information from either the user or the system. The means of requesting information is called an "exception" as it uses a similar concept like Java exceptions. The caller , in this case the sender of the request, is responsible for handling exceptions. There are three types of exceptions which an IBM Cognos 8 Authentication Provider can return UserRecoverable Exceptions (camAuthUserRecoverable, error -36) Signals to the sender, that the end user/client needs to provide (additional) data which should be attached to a new request. This for example could mean the user needs to select a namespace for authentication or enter credentials. SystemRecoverable Exceptions (camAuthSystemRecoverable, error -37) Signals to the Entry Point, that additional data is required which the system must acquire without further interaction of the user/client. The additional information has to be attached to a new request to be sent to CAM. This could mean retrieving the value of a system/environment variable at the Gateway for example. Unrecoverable Exceptions (camAuthUnRecoverable, error -38) Signals an error which cannot be remedied by any further action. This usually indicates some internal problem with the provider and renders authentication impossible, no further request must be send in this authentication transaction. Each exception will carry its own specific set of additional information to indicate to the sender the root cause of the rejection or to indicate the next possible action. Its the senders duty to react to those exceptions in a suitable way, like re-sending the request with additional data attached or to employ other services like presentation service to drive action. This could mean there are several rounds of back and forth between the Authentication Provider and the Entry Point/Client/User before the request if finally authenticated or failed ultimately. This back and forth between CAM and a caller, which could be an entry point (Gateway, Dispatcher) or some other component like SDS (Scheduling submitting credentials for authentication to do a "run-as") is called "the authentication dance".
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 8 of 16

ibm.com/developerWorks/

developerWorks

In case of additional information required from a user (UserRecoverable Exception) the system will generate a HTML page and return it to the client/user's browser as part of the exception. The generated page will contain HTML forms to prompt the user for the required information and submit it back to Cognos or, in case of SDK clients, name the additional variables which must be passed by the client. In case of additional information required from the system (the environment), the process is a bit more complex though. The SystemRecoverable Exception will contain an encrypted data field which contains the name of the environment variable the Authentication Provider is requesting. Although the variable may have been part of the original request (i.e. REMOTE_USER) the provider won't accept the value from the original request as it's too easy to spoof or inject, it simply doesn't trust the value. To obtain the value from a trusted source, like the Entry Point, it requests this variable from the Entry Point. The sender, in this case the Entry Point will try to read the variable form it's local environment and provide the deducted value or NULL if not available/found to the provider as part of it's response. This response is the original request to which the Entry Point now added the information deducted from it's environment in the same encrypted field. To the provider this is yet another new request for authentication however this time it will have additional information and possibly can succeed now. Single Sign-on vs Trusted Sign-on To achieve a seamless sign-on experience IBM Cognos 8 supports two concepts. Single Sign-On (SSO) implies that IBM Cognos 8 will take on some UserID received from a previous authentication layer like for example an authentication proxy. The user will not get prompted for credentials by Cognos again. An IBM Cognos 8 authentication provider will investigate some (for some providers configurable) HTTP variable or cookie which holds logon data suitable for SSO. The authentication dance will be employed to obtain the required information. For trusted sign-on (TSO) a special type of IBM Cognos 8 authentication provider, a so called Trusted Signon Provider (TSP) can be coded . This provider will consume some token and deduct logon data consumable by an Authentication Provider from it. The TSP is not a full provider, it does not attach to an authentication source like LDAP, it's merely a proxy to make some SSO token accessible. In the next step the logon data is passed to a full IBM Cognos 8 authentication provider using the REMOTE_USER standard header which most out of the box Authentication Providers support for SSO. Opposed to SSO though, the full provider will not employ the authentication dance in this case, but rather trust the logon data passed in REMOTE_USER because it originates from a trusted source, the TSP. For both cases, as always, IBM Cognos 8 will not authenticate the user itself but rely on 3 party authentication sources for this. In single sign-on or trusted
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 9 of 16 rd 1

developerWorks

ibm.com/developerWorks/

sign-on though, IBM Cognos 8 never verifies the credentials of a user but simply relies on a look-up and assumes the user has been authenticated by proper credentials before. For the look-up however, IBM Cognos 8 must have access to an authentication source where exactly one user will be found if searched based on the information passed in the header/cookie. However, it doesnt need to be exact same authentication source. For example, if the user has been authenticated by some authentication proxy based on LDAP, the proxy passing some value in REMOTE_USER, for IBM Cognos 8 there can be some authentication provider configured for Series7 leveraging OSSignon and hence allowing a user to be looked up based on the information passed. Ideally though, one would use an LDAP authentication provider pointing to the same LDAP in this case to ensure the correct user is looked up as any mapping incurs the potential for errors. 1 For CA Siteminder such a provider is delivered out of the box, for other authentication proxies it could potentially be developed using the IBM Cognos8 Authentication Provider SDK.

Implementing SSO for Custom Java Authentication Providers


The previous chapter explained the concepts and components involved with authentication in IBM Cognos. Based on this we can now discuss implementing SSO in a CJAP. In this document we are focussing on a full authentication provider. To support SSO the provider must implement support for the 4 type of logon data ,the environment variables as mentioned in Section 2.3.1 - Logon Data. It is irrelevant which other types of logon data the provider is supporting in addition to the environment variables, however if the provider shall allow for scheduling the Trusted credentials are required. If users should be able to type in credentials the FORM based method must be implemented as well and finally, the SDK Credential is required if SDK applications and tools like trigger.sh or diagnostic tools from the /bin/utilities folder shhould be used. For the course of this document the technique will be demonstrated based on the code of the "JDBCSample" delivered as part of the IBM Cognos 8 SDK. We will add support for all types of logon data including SSO based on REMOTE_USER. When a request is passed to the provider this implies calling the authenticate() method of the provider. In this method the provider has to handle the complete authentication sequence from identifying the type of logon data, run the authentication with the authentication source and eventually issue a visa and add it to a passport. For this document we will only discuss the first step of identifying the
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 10 of 16 th

ibm.com/developerWorks/

developerWorks

type of logon data, the rest is specific to the authentication source being supported and hence off topic. Refer to the JDBC sample source code for details. A proven practice for handling the identification of logon data type is to use nested IF statements which will check for Trusted Credentials, Credentials, Forms and finally for SSO. While there is no specific sequence required it has some advantages to stick to this rundown to keep the code simple. Only if no explicit logon data is provided the code should try handling SSO. Each type of logon data has a matching function of the IBiBusHeader2 class to be used to retrieve it from the request which is passed to the logon() function. There is getTrustedCredentialValue() which can be called with parameters user name or password to read the corresponding values from the trusted credential. For SDK credentials a similar function called getCredentialValue() exists which works along the same lines. Simply call it using user name or password parameters to retrieve the values from an SDK Credential. For FORM based authentication, that is the lgin page, where a user typed in user name and password two FORM variables CAMUsername and CAMPassword are used. A call to GetFormFieldValue() using those names for parameter will retrieve the form fields form the request. It's is possible to pass those fields as part of a GET URL as well of course. Finally, for reading environment variables there do exist two functions getEnvVarValue() This function will read the value of a HTTP header from the request as-is. That is, it won't trigger the authentication dance and simply take on the value as passed in the request. While this may be sufficient in some scenarios it incurs a great risk of fraud. It is very easy to inject HTTP headers to a request and hence just anybody could add a REMOTE_USER header with any desired value to the request. The use of this function for SSO is hence DEPRECATED. GetTrustedEnvVarValue() This function can be used to trigger the authentication dance as described in section 2.3.3 for the variable specified in the parameter passed to this function. This assumes that the HTTP header in the request sent to the provider was populated with values which the web server would store as CGI environment variables locally. The authentication dance will make the entry point read that variable value from the environment at the entry point and send it back to the provider. Because the variable is retrieved form a Cognos component (the entry point) the provider will trust the deducted value as it's transmitted signed and encrypted so it's sufficiently secure. Obviously we would want to use the getTrustedEnvVarValue() function. Section 2.3.3 mentioned, that to trigger the authentication dance an exception would have to be
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 11 of 16

developerWorks

ibm.com/developerWorks/

returned to the entry point. This is something which must be handled in the provider code explicitly. The getTrustedEnvVarValue() function will return either NULL or a string. If it returns NULL this indicates that there's yet no trusted value retrieved. This implies that the provider code now has to raise a SystemRecoverable Exception and request the desired variable. From the point of the provider handling this request is complete at this point. When a new request arrives and GetTrustedEnvVarValue() is called again it will return a string. If this string is empty (it's length = 0) the entry point could not retrieve a value for the desired variable which means it's not set. This implies the SSO failed and the provider should fall back to FORM based authentication by throwing a UserRecoverableException asking to type in credentials or bail out with an UnrecoverableException. If the string is not empty it will contain the value of the variable requested. So it's the provider itself which must throw the SystemRecoverable Exception and as part of that provide the name of the variable it's requesting. All the rest of the involved functionality like encrypting the values, signing of the proprietary headers used to transfer the data back and forth between the provider and the entry point are shielded from the developer. Below is a snippet of code form the JDBCSample sample application source code which is part of the Logon() function. It uses three IF statements in sequence to check for the different type of logon data. Only if one of either username or password is populated the code will proceed to verify the logon data or even issue a visa. If neither username nor password get assigned values retrieved from logon data the code will throw a UserRecoverable exception which will lead to displaying a logon screen if a browser is the client. To this snippet we want to add support for the 4 type of logon data, the trusted environment variable, in this example REMOTE_USER.
String[] username = null; String[] password = null; // 1 - Look for trusted credentials username = theAuthRequest.getTrustedCredentialValue("username"); password = theAuthRequest.getTrustedCredentialValue("password"); if (username == null && password == null) { // 2 - Look for credentials coming from SDK request username = theAuthRequest.getCredentialValue("username"); password = theAuthRequest.getCredentialValue("password"); } if (username == null && password == null) { // 3 - Look for credentials in formfield username = theAuthRequest.getFormFieldValue("CAMUsername"); password = theAuthRequest.getFormFieldValue("CAMPassword"); } if (username == null || password == null) { UserRecoverableException e = new UserRecoverableException( "Please type your credentials for authentication.",

th

IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider

Page 12 of 16

ibm.com/developerWorks/

developerWorks

"The provided credentials are invalid."); e .addDisplayObject(new TextDisplayObject("User ID:", "CAMUsername")); e.addDisplayObject(new TextNoEchoDisplayObject("Password:", "CAMPassword")); throw e; }

The straight forward approach would be to add a fourth IF block after looking for credentials from the form fields. However, that would imply that whatever happens in that IF block has to populate username and password to pass the final test whether something has been retrieved in the last IF statement. SSO typically doesnt provide passwords, it's the purpose of SSO to avoid having to provide the password multiple times and it's a security risk to pass around passwords in clear text anyway. So it's safe to assume that our SSO won't provide a password. That implies we'd have to change the final if statement considerably to allow for user name only, but only in the case of SSO. Well, that's not entirely correct. If SSO is supported it could be used to generate trusted credentials as well. What that means is, that if a user authenticated to IBM Cognos 8 by SSO the logon data will have been some user name only. So if the provider is called to generate a TrustedCredential to store with a schedule it can generate this credential based on a user name only. Now when that schedule is executed later, it will be those TrustedCredentials, consisting of a user name only which are presented to the provider. Hence, once the provider does support SSO it has to deal with (trusted) credentials which may contain a user name only, that is, even trusted credential based authentication must be allowed with a user name only. One could choose to extend this to the SDK credential based authentication as well, however SDK clients usually have enough functionality to provide full credentials, which is user name and password. As a recommendation it should be left as is, to require full credentials. With that being stated it becomes reasonable to change part of the logic of that code snippet and change the structure of the IF statements from sequence to nested. This will allow for decisions on the contents of the deducted logon data for each type individually. To get past the last IF statement we simply populate the password with the user name in case of SSO. Below is one example of a possible solution to this requirement.
String[] username = null; String[] password = null; // 1 - Look for trusted credentials username = theAuthRequest.getTrustedCredentialValue("username"); password = theAuthRequest.getTrustedCredentialValue("password"); // since pw can be empty we scan for either username or password if (username != null) {// we found some value for username in TC, now lets see about pw if (password == null) password=username;

IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider

Page 13 of 16

developerWorks

ibm.com/developerWorks/

// we simply set password= username in case we didn't get one from TC // possibly some log output here } else { // 2 - Look for credentials coming from SDK request username = theAuthRequest.getCredentialValue("username"); password = theAuthRequest.getCredentialValue("password"); if (username != null && password != null) { // we found Sdk credential, all good // possibly some log output here } else { // 3 - Look for credentials in form field username = theAuthRequest.getFormFieldValue("CAMUsername"); password = theAuthRequest.getFormFieldValue("CAMPassword"); // Note: using AND here implies that the provider will check for SSO // if a user typed in username and an empty password. Though // it introduces overhead, this can be neglected as it enforces // correct logic on the other hand. if (username != null && password != null) { // found credentials in form field, all good // possibly some log output here } else { // 4 - Look for REMOTE_USER header variable username = theAuthRequest.getTrustedEnvVarValue("REMOTE_USER"); if (username == null) { // null implies the provider has to start the dance so throw a SysRecov. // the SysRecov needs to have the name of the variable we look for in // the second parameter SystemRecoverableException e = new SystemRecoverableException( "Challenge for REMOTE_USER", "REMOTE_USER"); throw e; } // username is != NULL so we have to investigate if we got something back // from the dance if (username[0].length() == 0) {// this indicates the variable does not exist or is empty. Bail out by // erasing username and password. Final IF will cause UserRecoverable username=null; password=null; } else { // OK, we got something, so fake password, just to pass the // if clause further down. password = username; } } } }

With this logic, the provider will trigger the authentication dance and retrieve REMOTE_USER. If that variable has a value in the entry points environment it will be transferred to username and password. All that's left to do is to process the credentials and verify them with the authentication source. Mind that in case of username=password it's either SSO or a trusted credential. In both cases the provider would work along the concept of a Trusted Signon where it doesn't verify credentials but only runs a look-up.
IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider Page 14 of 16

ibm.com/developerWorks/

developerWorks

This technique can be adopted to use any HTTP header variable. Cookies cannot be used as the entry point doesn't support them. Using cookies should be handled in a TSP really which then passes on to a full authentication provider which uses REMOTE_USER based SSO as demonstrated here. The above code snippet won't actually make the JDBCSample work. The sample code relies on passing user name and password to the JDBC driver and only if those credentials are successfully used to establish a DB connection the visa will be issued. However if one creates a user which has his user name as a password that would work. The JDBCSample was chosen for this document only because it's the only example of a full authentication provider. The important take away is the concept of calling GetTrustedEnvVarValue() twice depending on it's return code.

IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider

Page 15 of 16

developerWorks

ibm.com/developerWorks/

About the author


Cognos Proven Practices Team Cognos Proven Practices Team Copyright IBM Corporation 2010 (www.ibm.com/legal/copytrade.shtml) Trademarks (www.ibm.com/developerworks/ibm/trademarks/)

IBM Cognos Proven Practices: Adding Single SignOn to your IBM Cognos 8 Custom Java Authentication Provider

Page 16 of 16

You might also like