Adding SingleSign-On to your IBM Cognos 8

16
© Copyright IBM Corporation 2010 Trademarks IBM Cognos Proven Practices: Adding Single Sign- On to your IBM Cognos 8 Custom Java Authentication Provider Page 1 of 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.

description

Adding SingleSign-On to your IBM Cognos 8

Transcript of Adding SingleSign-On to your IBM Cognos 8

© Copyright IBM Corporation 2010 TrademarksIBM Cognos Proven Practices: Adding Single Sign-On to your IBM Cognos 8 Custom Java AuthenticationProvider

Page 1 of 16

IBM Cognos Proven Practices: Adding SingleSign-On to your IBM Cognos 8 Custom JavaAuthentication ProviderNature of Document: Technique; Product(s): IBM Cognos 8;Area of Interest: Security; Version: 1.0

Cognos Proven Practices TeamCognos Proven Practices TeamIBM

Skill Level: Advanced

Date: 28 Jul 2010

This document describes how one can implement SSO to his Custom JavaAuthentication Provider by explaining the required concepts. This documentssupplements SDK documentation.

View more content in this series

IntroductionPurposeThe Custom Java Authentication Provider Developer Guide which is part of thestandard IBM Cognos 8 SDK documentation delivers the main concepts requiredto code a Custom Java Authentication Provider (CJAP). It even describes whatauthentication can be based on and how to request additional information fromthe entry point. However, the description is overly brief and lacks an example ofactually leveraging those techniques to add support for Single Sign-On (SSO) to afull Custom Java Authentication Provider. This however may be required to deliver acomprehensive solution to the client.

In this document the background of the authentication process is provided alongwith descriptive information on how to use the provided SDK to handle SSO. As anexample SSO support will be added to the "JDBCSample" CJAP delivered as part ofthe SDK samples.

ApplicabilityThe concepts and backgrounds published in this document apply to all versions ofIBM Cognos 8.

developerWorks® ibm.com/developerWorks/

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

Page 2 of 16

The code examples in this document were developed and tested using IBM Cognos8.4.1. While the author cannot guarantee that the code examples will work withoutadjustment 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 thecode work in other versions of the product.

Exclusions and ExceptionsThe document will not cover designing and coding Custom Java AuthenticationProviders (CJAP) in general. The only aspect covered herein will be adding supportfor Single Sign-on (SSO) to a full authentication provider.

The use of the example code (JDBCSample) requires that the IBM Cognos 8 SDK isinstalled and licensed.

It is expected that the reader is familiar with the CJAP SDK and Java programming.

Authentication in IBM Cognos 8This chapter is going to provide a comprehensive description of the concepts andcomponents involved with the authentication process in IBM Cognos 8.

Requests and SessionsUsers (browsers) or code (an SDK application) send requests to IBM Cognos 8 byestablishing a HTTP session with a Cognos entry point (EP). Valid entry points areeither 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 overallfunctionality provided by the Cognos system is implemented by a set of independentservices communicating externally and amongst each others using the SOAPprotocol. For this reason each request sent to an IBM Cognos 8 entry point will haveto be routed to some target service which can handle it. Each of the services makingup IBM Cognos 8 handles different types of requests and routing is one of the mainconcepts of the IBM Cognos 8 architecture.

Routing is handled by the IBM Cognos 8 Dispatcher Service. Regardless whether arequest was sent to a Dispatcher directly or via a Gateway (each Gateway will relayit's request to a single Dispatcher denoted in it's configuration), it will be handledby an instance of Dispatcher Service on the accessed Dispatcher. The DispatcherService will create a new sessionID if this is the first request received in that veryHTTP session. Next a requestID will be assigned to the request and both sessionIDand requestID are added to the request. All subsequent requests in the same HTTPsession can be identified now because they share the same sessionID.

As services are logically independent from each other practically all of them willrequire authentication before they will handle a request to prevent unintended

ibm.com/developerWorks/ developerWorks®

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

Page 3 of 16

access. Authentication in this context means, that the session the request is part of isauthenticated and hence the request originates from an authenticated sender.

For IBM Cognos 8 authentication functionality is centrally offered by the ContentManager (CM) Service. Consequently all other IBM Cognos 8 services will employthe CM Service to verify session authentication or trigger authentication for yetunauthenticated sessions.

As soon as a request is handled by an instance of Dispatcher Service that servicewill first of all check the authentication status for the given session. If the session wasnot authenticated yet the Dispatcher Service will employ the CM Service to run theauthentication process and pass off the request to it. The CM Service will pass on therequest to the Cognos Access Manager (CAM) component, a sub component of CMwhich handles authentication, authorization and administration (AAA) and encryption(CRP). It’s the AAA sub-component of CAM which will then employ authenticationproviders configured for IBM Cognos 8 to access authentication sources, to readinformation about a user from it and eventually authenticate the request and hencethe session.

Figure 1 schematics of authentication

If the authentication is successful the authentication information is persisted inContent Store and a reference is added to the session so subsequent requests won’tget passed to CAM as all services can deduct some reference to the authenticationinformation from the session directly now and have CM Service verify it whereapplicable.

developerWorks® ibm.com/developerWorks/

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

Page 4 of 16

After some configurable amount of idle time a session will time out and theDispatcher Service will request CAM to authenticate the session again.

Authentication providers

IBM Cognos 8 authentication providers are software modules implemented in Java orC++ which interface with the Cognos Access Manager (CAM) component. There aretwo types of authentication providers, as documented in the Custom AuthenticationProvider Developer Guide.

A full authentication provider implements functions to authenticate providedcredentials against some authentication source which stores and manages entries oftype user, group and/or role. In addition it provides support for searching entries andis respecting hierarchical structures of the authentication source. An authenticationprovider has to support at least one method of authentication, possibly multiple and itcan support single sign-on support as well.

A trusted sign-on provider (TSP) though offers very limited functionality for a singlepurpose. In single sign-on scenarios it reads in a token from the session possiblyplaced in the session by some higher-level authentication layer which identifies auser. The assumption is that this token is not consumable by any other IBM Cognos 8authentication provider directly. The TSP transforms the information in the token intosomething a full authentication provider can consume and passes the authenticationprocess on to a second, full authentication provider. It does NOT authenticatethe user, it simply relays and transforms information and thus does not result in anamespace entry to appear in Cognos Connection’s Directory tool.

Below table depicts which authentication providers are provided by IBM Cognos 8 outof the box. Not every provider is available on every platform though. On Linux andHP-UX Itanium the LDAP provider is the only one available.

In addition to those out of the box providers customers can implement their ownauthentication providers using the Custom Authentication Provider SDK (part of theIBM Cognos 8 SDK) which is provided for Java only. Authentication providers codedbased on this SDK are called a Custom Java Authentication Provider (CJAP) andcan either be of type full or TSP. As a matter of fact there is already a CJAP includedwith the product for single sign-on to Portal Servers, the Shared Secret provider.

ibm.com/developerWorks/ developerWorks®

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

Page 5 of 16

Windows UNIX Linux, HP-UX Itanium

ActiveDirectory

yes no no

NTLM yes no no

SAP yes yes no

Series 7 yes yes no

LDAP yes yes yes

CASiteminder(TSP)

yes yes no

SharedSecret(CJAP,TSP)

yes yes yes

All providers, except CJAPs which use proprietary configuration methods, getconfigured through a namespace configuration (resource) which is created inCognos Configuration. In there, properties specific for that provider instance canbe configured. Upon start of IBM Cognos 8 Content Manager the configuration isscanned for namespace configurations and the respective providers get initializedbased on the settings configured.

As of IBM Cognos 8 all out of the box providers support the Test functionality whichis available by right-clicking on a namespace configuration element in CognosConfiguration’s explorer tree. What this does is initializing the provider with theconfigured settings to a certain extent. The test however may not be conclusive to allthe functionality the provider supports, it's meant to catch obvious configuration errorsand connectivity issues only.

The authentication process in general

When CAM receives a request to authenticate the first decision about the typeof authentication is made based on configuration. If the system is configured toallow anonymous access, then sessions will become authenticated using a specialanonymous user as there are no real anonymous sessions in IBM Cognos 8. Aninternal authentication provider is used to implement this functionality which isneither visible nor configurable. Some hard coded dummy user credentials, neithercontaining username nor password will be used and hence no login is required.

For named (=non anonymous) access CAM will use the configured authenticationproviders to authenticate the request and hence it is passed to one of the configuredproviders. Which one is determined based on availability (which providers didinitialize correctly) and some parameter which contains the namespaceID of thenamespace to use.

developerWorks® ibm.com/developerWorks/

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

Page 6 of 16

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 authenticateto and credentials this may not hold true for all use cases.

For this the architecture implements a concept of returning qualified responses to thesender which triggers him to send another new request with additional informationattached. That way an authentication provider can request additional informationfrom either the sender (user or SDK program) or even the entry point (Gateway orDispatcher) the request came in through. Typical applications of those call-backs areprompting the user to enter his credentials, have the user choose one out of severalconfigured authentication providers or have the entry point retrieve some trustedvariable value from it's environment which is typical for SSO.

Each request sent to CAM is treated independently but a sequence of requests mayconstitute the logon process for a given session. This is what's described in threescenarios 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 willactually try to authenticate the request. Before continuing to the next step of theauthentication 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 authenticationprovider.

• Trusted credentials (TCs)Credentials of this type have been created for an IBM Cognos 8 user by someauthentication provider in the past and were stored (encrypted) in ContentStore. 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) likeusername (and password). Only the credential path is passed in requeststhough, TCs never leave the Content Store.When receiving a TC an authentication provider will not verifytheir origin or consistency explicitly but implicitly only. The functiongetTrustedCredentialValue() capsulates the retrieval of the actual credentialvalue 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 inthe authentication source after they have been stored in Content Manager. Inthat case they must be renewed through Cognos Connection by the user theybelong to himself.

• CredentialsCredentials also known as SDK Credentials are sent by SDK programs whenauthenticating to IBM Cognos 8. Technically they will be strings, likely user

ibm.com/developerWorks/ developerWorks®

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

Page 7 of 16

name and - possibly but not mandatory - a password. The credentials will bepassed in the request in clear text unless SSL is used.An authentication provider will verify them against the authentication source.

• Form fields - Username and PasswordIf running Basic Authentication, that means a user is prompted to enterusername and password, the HTML code will submit the credentials entered intwo predefined FORM fields. They will be visible in the request to the entry pointbut as soon as the request is parsed by a Gateway it will obscure the passwordin the request passed to CAM. If the entry point is a Dispatcher that functionalityis not supported.

• (Trusted) Environment variables,cookies or generic SSO tokensAuthentication providers may allow reading user identity information from anenvironment variable or some binary token.The values of those variables or tokens are never read from the request directlybut rather get provided by the entry point component through the call-backsmentioned before. It evolves that support for these call-backs requires code inthe entry point layer components as well.The only binary SSO token currently supported (on Windows Gatewaysonly) is a Microsoft Windows Kerberos token. The respective code forenvironment 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 ordifferent ones all together.

Persisting authentication information in the sessions

When serving a request the authentication provider will reach out to it’sauthentication source and read information from it to verify the passed identityinformation. If authentication succeeds, the provider will issue a visa for thenamespace the user/client was authenticated against.

A Visa maintains the user’s security context, that is the logon data (whatever wasused to authenticate to IBM Cognos 8), and his identity (the groups and roles he’sa member of). The visa will be used to derive credentials (saved logon data fromprevious authentication to pass to other services) which will be used wheneveranother IBM Cognos 8 service requests authentication or for example whenscheduling reports or to authenticate to a data source. The visa will be added to aCAM in-memory table which will hold all active visas. All the visas for a single sessionand hence a user/client, one for each namespace to which authentication has beensuccessfully completed, make up a Passport. They share the same primary key inthat table the Passport ID. Only this Passport ID is exposed external to CAM as areference. It’s that Passport ID which is returned to CM and the user/client.

developerWorks® ibm.com/developerWorks/

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

Page 8 of 16

In case of a browser client the Passport ID is stored in a session cookie in thebrowser memory, for SDK it’s the application’s duty to manage the Passport ID for theduration of the session.

Request additional information (The authentication dance)

If a request doesn’t contain enough information to complete the authenticationtransaction right now the authentication provider will use the call-back functionalitymentioned earlier. This feature allows an authentication provider to request additionalinformation from either the user or the system.

The means of requesting information is called an "exception" as it uses a similarconcept like Java exceptions. The caller , in this case the sender of the request, isresponsible for handling exceptions.

There are three types of exceptions which an IBM Cognos 8 Authentication Providercan return

• UserRecoverable Exceptions (camAuthUserRecoverable, error -36)Signals to the sender, that the end user/client needs to provide (additional) datawhich should be attached to a new request. This for example could mean theuser 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 systemmust acquire without further interaction of the user/client. The additionalinformation has to be attached to a new request to be sent to CAM. This couldmean retrieving the value of a system/environment variable at the Gateway forexample.

• Unrecoverable Exceptions (camAuthUnRecoverable, error -38)Signals an error which cannot be remedied by any further action. This usuallyindicates some internal problem with the provider and renders authenticationimpossible, no further request must be send in this authentication transaction.

Each exception will carry its own specific set of additional information to indicate tothe sender the root cause of the rejection or to indicate the next possible action.

It’s the sender’s duty to react to those exceptions in a suitable way, like re-sendingthe request with additional data attached or to employ other services like presentationservice to drive action. This could mean there are several rounds of back and forthbetween the Authentication Provider and the Entry Point/Client/User before therequest 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 submittingcredentials for authentication to do a "run-as") is called "the authentication dance".

ibm.com/developerWorks/ developerWorks®

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

Page 9 of 16

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 aspart of the exception. The generated page will contain HTML forms to prompt theuser for the required information and submit it back to Cognos or, in case of SDKclients, name the additional variables which must be passed by the client.

In case of additional information required from the system (the environment), theprocess is a bit more complex though.

The SystemRecoverable Exception will contain an encrypted data field whichcontains the name of the environment variable the Authentication Provider isrequesting. 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 asit's too easy to spoof or inject, it simply doesn't trust the value. To obtain the valuefrom a trusted source, like the Entry Point, it requests this variable from the EntryPoint. The sender, in this case the Entry Point will try to read the variable form it'slocal environment and provide the deducted value or NULL if not available/found tothe provider as part of it's response. This response is the original request to which theEntry Point now added the information deducted from it's environment in the sameencrypted field. To the provider this is yet another new request for authenticationhowever 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 receivedfrom a previous authentication layer like for example an authentication proxy. Theuser will not get prompted for credentials by Cognos again. An IBM Cognos 8authentication provider will investigate some (for some providers configurable) HTTPvariable or cookie which holds logon data suitable for SSO. The authentication dancewill 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 coded1. This provider will consumesome token and deduct logon data consumable by an Authentication Providerfrom it. The TSP is not a full provider, it does not attach to an authentication sourcelike LDAP, it's merely a proxy to make some SSO token accessible. In the nextstep the logon data is passed to a full IBM Cognos 8 authentication provider usingthe REMOTE_USER standard header which most out of the box AuthenticationProviders support for SSO. Opposed to SSO though, the full provider will not employthe authentication dance in this case, but rather trust the logon data passed inREMOTE_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 3rd party authentication sources for this. In single sign-on or trusted

developerWorks® ibm.com/developerWorks/

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

Page 10 of 16

sign-on though, IBM Cognos 8 never verifies the credentials of a user but simplyrelies on a look-up and assumes the user has been authenticated by propercredentials before. For the look-up however, IBM Cognos 8 must have access to anauthentication source where exactly one user will be found if searched based on theinformation passed in the header/cookie. However, it doesn’t need to be exact sameauthentication source.

For example, if the user has been authenticated by some authentication proxy basedon LDAP, the proxy passing some value in REMOTE_USER, for IBM Cognos 8 therecan be some authentication provider configured for Series7 leveraging OSSignonand hence allowing a user to be looked up based on the information passed. Ideallythough, one would use an LDAP authentication provider pointing to the same LDAPin this case to ensure the correct user is looked up as any mapping incurs thepotential for errors.

1 For CA Siteminder such a provider is delivered out of the box, for otherauthentication proxies it could potentially be developed using the IBM Cognos8Authentication Provider SDK.

Implementing SSO for Custom Java AuthenticationProvidersThe previous chapter explained the concepts and components involved withauthentication in IBM Cognos. Based on this we can now discuss implementing SSOin a CJAP.

In this document we are focussing on a full authentication provider. To support SSO

the provider must implement support for the 4th type of logon data ,the environmentvariables as mentioned in Section 2.3.1 - Logon Data. It is irrelevant which othertypes of logon data the provider is supporting in addition to the environmentvariables, however if the provider shall allow for scheduling the Trusted credentialsare required. If users should be able to type in credentials the FORM based methodmust be implemented as well and finally, the SDK Credential is required if SDKapplications and tools like trigger.sh or diagnostic tools from the /bin/utilities foldershhould be used.

For the course of this document the technique will be demonstrated based on thecode of the "JDBCSample" delivered as part of the IBM Cognos 8 SDK. We will addsupport 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 completeauthentication sequence from identifying the type of logon data, run theauthentication with the authentication source and eventually issue a visa and add itto a passport. For this document we will only discuss the first step of identifying the

ibm.com/developerWorks/ developerWorks®

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

Page 11 of 16

type of logon data, the rest is specific to the authentication source being supportedand 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 nestedIF statements which will check for Trusted Credentials, Credentials, Forms andfinally for SSO. While there is no specific sequence required it has some advantagesto stick to this rundown to keep the code simple. Only if no explicit logon data isprovided the code should try handling SSO.

Each type of logon data has a matching function of the IBiBusHeader2 class to beused to retrieve it from the request which is passed to the logon() function.

There is getTrustedCredentialValue() which can be called with parameters user nameor password to read the corresponding values from the trusted credential. For SDKcredentials a similar function called getCredentialValue() exists which works alongthe same lines. Simply call it using user name or password parameters to retrieve thevalues from an SDK Credential.

For FORM based authentication, that is the lgin page, where a user typed in username and password two FORM variables CAMUsername and CAMPassword areused. A call to GetFormFieldValue() using those names for parameter will retrieve theform fields form the request. It's is possible to pass those fields as part of a GET URLas 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. Thatis, it won't trigger the authentication dance and simply take on the value aspassed in the request. While this may be sufficient in some scenarios it incurs agreat risk of fraud. It is very easy to inject HTTP headers to a request and hencejust anybody could add a REMOTE_USER header with any desired value to therequest. The use of this function for SSO is hence DEPRECATED.

• GetTrustedEnvVarValue()This function can be used to trigger the authentication dance as described insection 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 waspopulated with values which the web server would store as CGI environmentvariables locally. The authentication dance will make the entry point read thatvariable value from the environment at the entry point and send it back to theprovider. Because the variable is retrieved form a Cognos component (the entrypoint) the provider will trust the deducted value as it's transmitted signed andencrypted so it's sufficiently secure.

Obviously we would want to use the getTrustedEnvVarValue() function. Section 2.3.3mentioned, that to trigger the authentication dance an exception would have to be

developerWorks® ibm.com/developerWorks/

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

Page 12 of 16

returned to the entry point. This is something which must be handled in the providercode explicitly. The getTrustedEnvVarValue() function will return either NULL or astring. If it returns NULL this indicates that there's yet no trusted value retrieved. Thisimplies that the provider code now has to raise a SystemRecoverable Exception andrequest the desired variable. From the point of the provider handling this request iscomplete 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 entrypoint 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 basedauthentication by throwing a UserRecoverableException asking to type in credentialsor bail out with an UnrecoverableException. If the string is not empty it will contain thevalue of the variable requested.

So it's the provider itself which must throw the SystemRecoverable Exception and aspart of that provide the name of the variable it's requesting. All the rest of the involvedfunctionality like encrypting the values, signing of the proprietary headers used totransfer the data back and forth between the provider and the entry point are shieldedfrom the developer.

Below is a snippet of code form the JDBCSample sample application source codewhich is part of the Logon() function. It uses three IF statements in sequence tocheck for the different type of logon data. Only if one of either username or passwordis populated the code will proceed to verify the logon data or even issue a visa. Ifneither username nor password get assigned values retrieved from logon data thecode will throw a UserRecoverable exception which will lead to displaying a logonscreen if a browser is the client.

To this snippet we want to add support for the 4th type of logon data, the trustedenvironment 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.",

ibm.com/developerWorks/ developerWorks®

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

Page 13 of 16

"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 forcredentials from the form fields. However, that would imply that whatever happens inthat IF block has to populate username and password to pass the final test whethersomething has been retrieved in the last IF statement. SSO typically doesn’t providepasswords, it's the purpose of SSO to avoid having to provide the password multipletimes and it's a security risk to pass around passwords in clear text anyway. So it'ssafe to assume that our SSO won't provide a password. That implies we'd have tochange the final if statement considerably to allow for user name only, but only in thecase of SSO.

Well, that's not entirely correct. If SSO is supported it could be used to generatetrusted credentials as well. What that means is, that if a user authenticated to IBMCognos 8 by SSO the logon data will have been some user name only. So if theprovider is called to generate a TrustedCredential to store with a schedule it cangenerate this credential based on a user name only. Now when that schedule isexecuted later, it will be those TrustedCredentials, consisting of a user name onlywhich are presented to the provider. Hence, once the provider does support SSO ithas 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, torequire full credentials.

With that being stated it becomes reasonable to change part of the logic of that codesnippet 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 typeindividually. To get past the last IF statement we simply populate the password withthe 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 credentialsusername = theAuthRequest.getTrustedCredentialValue("username");password = theAuthRequest.getTrustedCredentialValue("password");// since pw can be empty we scan for either username or passwordif (username != null){// we found some value for username in TC, now lets see about pw if (password == null) password=username;

developerWorks® ibm.com/developerWorks/

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

Page 14 of 16

// 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 retrieveREMOTE_USER. If that variable has a value in the entry points environment it will betransferred to username and password.

All that's left to do is to process the credentials and verify them with theauthentication source. Mind that in case of username=password it's either SSO ora trusted credential. In both cases the provider would work along the concept of aTrusted Signon where it doesn't verify credentials but only runs a look-up.

ibm.com/developerWorks/ developerWorks®

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

Page 15 of 16

This technique can be adopted to use any HTTP header variable. Cookies cannotbe used as the entry point doesn't support them. Using cookies should be handledin a TSP really which then passes on to a full authentication provider which usesREMOTE_USER based SSO as demonstrated here.

The above code snippet won't actually make the JDBCSample work. The samplecode relies on passing user name and password to the JDBC driver and only ifthose credentials are successfully used to establish a DB connection the visa will beissued. However if one creates a user which has his user name as a password thatwould work. The JDBCSample was chosen for this document only because it's theonly example of a full authentication provider. The important take away is the conceptof calling GetTrustedEnvVarValue() twice depending on it's return code.

developerWorks® ibm.com/developerWorks/

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

Page 16 of 16

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/)