Troubleshooting
Problem
This document contains troubleshooting information for OpenID Connect (OIDC) Trust Association Interceptor (TAI) problems in the WebSphere® Application Server. This can help address common issues with this component before calling IBM support and save you time.
Resolving The Problem
Component: Topic:
This topic contains error messages and common issues that require an OpenID Connect trace to determine the root cause of the problem. The instructions to obtain an OpenID Connect trace are in the 'Collecting data manually' section of the Collect data tab. If a trace string required for a specific problem is different than what is shown on the Collect data tab, the trace string will be noted in the steps to diagnose the problem. In the rest of this document, 'OpenID Connect' will be referred to as 'OIDC'.

This document uses the term Full Profile to refer to WebSphere Application Server v9.0 traditional, WebSphere Application Server v8.5 full profile, WebSphere Application Server v8.0 and earlier, WebSphere classic, traditional WebSphere, traditional WAS and tWAS.
How do I set up the OIDC TAI?
For information on how to set up your server to protect a resource using the OIDC TAI, see the following IBM Documentation articles:
OpenID Connect overview
Configuring an OpenID Connect Relying Party
OpenID Connect Relying Party custom properties
How can I ensure that I have the latest version of the OIDC TAI?
For information on how to obtain the latest OpenID Connect runtime, see the technote Obtaining WebSphere OpenID Connect (OIDC) latest version, or click 'Get the Latest OIDC TAI' tab above.
How can I see the version of the OIDC TAI from the jar?
From the (was_home)/plugins directory, run the following command:
java -cp ./com.ibm.ws.security.oidc.client.jar com.ibm.ws.security.oidc.util.Version com.ibm.ws.security.oidc.client.jar 1.02 |
If you are running a jar installed from an initial install or fix pack, you'll get a version number like 8.5.5 cf091605.01. If you are running a jar installed from an interim fix, you'll get a version number like 1.01.
If the com.ibm.ws.security.oidc.util.Version class is not found in your com.ibm.ws.security.oidc.client.jar, then you are running an out-dated version of the jar and you should update it by installing the latest interim fix. See Obtaining WebSphere OpenID Connect (OIDC) latest version.
How can I find what version of the OIDC TAI I am running in a trace?
To find the version of the OIDC TAI from a trace, search for getVersion:
[1/25/17 11:39:54:156 CST] 00000001 RelyingParty < getVersion returns [1.01] Exit |
Since this information is only emitted once when base security initializes the interceptors, you will only see this in traces that were gathered from application server startup.
How can I tell if a trace is from server startup?
IBM support requires that traces be gathered from server startup. If you want to make sure that your traces are gathered from server startup, check for the following string in your trace:
Search string
|
Full message
|
e-business | WSVR0001I: Server {0} open for e-business |
Where do I find the custom properties for the OIDC TAI?
Technote
To see a complete list of the custom properties that are supported in the latest published version of the OIDC TAI, see the technote WebSphere OpenID Connect, Full Profile Custom Properties.IBM Documentation
The custom properties for the OIDC TAI can be found in the IBM Documentation, see:
WebSphere OpenID Connect Relying Party custom properties for v8.5.5
If you want to see the custom properties for a version other than 8.5.5, use the Version drop-down at the top of the IBM Docs page.
Utility method
Since the OIDC TAI is frequently serviced outside the normal WebSphere Application Server fix pack schedule, the OIDC custom properties documented in the IBM Documentation are sometimes out of date. To alleviate this problem, a Usage command was added to the OIDC TAI jar in version 1.01.
From the (was_home)/plugins directory, run the following command:
java -cp ./com.ibm.ws.security.oidc.client.jar com.ibm.ws.security.oidc.util.Usage Component name: OpenID Connect Relying Party TAI TAI class name: com.ibm.ws.security.oidc.client.RelyingParty Version: 1.02 Custom properties: [[[ REQUIRED PARAMETERS, OP SPECIFIC], [, ]], [[ PROPERTY NAME, DEFAULT], [, DEFINITION]], [[ provider_<id>.clientId, ], [, Specifies the id used to identify the OpenID Connect RP instance to the OpenID connect Provider server. It must be unique among all the RP clients registered to the provider.]], [[ provider_<id>.identifier, ], [, Specifies a unique name for each OpenID connect provider identified by the <id> in the provider_<id> prefix. This identifier is used to build the redirect URL that is registered with the OP.]], [[ ... |
This output from this command is not beautiful, but it is serviceable. The custom properties that are displayed from this command are valid for the version of the jar from which they were displayed. Properties displayed from a version 1.02 jar are not necessarily valid for version 1.01.
How can I tell if trust association is enabled in a trace?
To find if trust association is enabled in an OIDC trace, search for the isTrustAssociationEnabled:
[1/25/17 11:36:29:375 CST] 00000001 TrustAssociat 3 isTrustAssociationEnabled returns [true] |
How do I find all the configured TAIs in a trace?
To find all the interceptors configured in an OIDC trace, search for the getInterceptors:
[1/25/17 11:36:29:375 CST] 00000001 TrustAssociat 3 getInterceptors returns [not null] [1/25/17 11:36:29:375 CST] 00000001 TrustAssociat 3 TAI class name[0]: com.ibm.ws.security.web.TAMTrustAssociationInterceptorPlus [1/25/17 11:36:29:375 CST] 00000001 TrustAssociat 3 TAI class name[1]: com.ibm.ws.security.spnego.TrustAssociationInterceptorImpl [1/25/17 11:36:29:375 CST] 00000001 TrustAssociat 3 TAI class name[2]: com.ibm.ws.security.oidc.client.RelyingParty |
How do I find my OIDC TAI configuration in a trace?
If you have a trace from application server startup, you can find the raw OIDC TAI custom properties by searching for the following string in an OIDC trace:
loadInterceptor |
If the OIDC TAI is configured and enabled, you'll find a trace block that looks like this; make sure you find the one that's loading com.ibm.ws.security.oidc.client.RelyingParty:
[1/25/17 11:39:54:016 CST] 00000001 TrustAssociat > loadInterceptor Entry com.ibm.ws.security.oidc.client.RelyingParty {provider_1.filter=request-url^=RP1|snoop, provider_1.clientId=oidcclient, provider_1.discoveryEndpointUrl=https://localhost:9444/oidc/endpoint/OP/.well-known/openid-configuration, provider_1.identifier=RP1, provider_1.clientSecret=password, provider_2.authorizeEndpointUrl=https://localhost:8020/oidc/endpoint/OP/authorize, provider_2.clientId=client01, provider_2.clientSecret=secret_01, provider_2.identifier=RP2, provider_2.filter=request-url^=RP2|mylogin, provider_2.introspectEndpointUrl=https://localhost:8020/oidc/endpoint/OP/introspect, provider_2.scope=BAD profile, provider_2.tokenEndpointUrl=https://localhost:8020/oidc/endpoint/OP/token, useStateCookies=false} |
If you want to see the resolved properties, search for the following string:
com.ibm.ws.security.oidc.client.OidcTAIConfig |
And find:
[8/5/20 19:02:36:280 EDT] 00000001 RelyingParty 3 com.ibm.ws.security.oidc.client.OidcTAIConfigultraLogout=[false], _anyRpConfigSupportsRevoke=[false], _anyRpConfigSupportsRevokeOnEviction=[false], _clientCredFlowConfig=[null], Partner: 1com.ibm.ws.security.oidc.client.RelyingPartyConfig(index=[0], providerId=[RP1], initializationComplete=[true], protectedContextPaths=[not null], excludedPathFilter=[not null], clientId=[oidcclient], clientSecret=[not null], clientBasicAuth=[Basic b2lkY2NsaWVudDpwYXNzd29yZA==], serverUrl=[null], signinCB=[null], signinCBEnc=[null], introspectEndpoint=[https://localhost:9444/oidc/endpoint/OP/introspect], userinfoEndpoint=[https://localhost:9444/oidc/endpoint/OP/userinfo], revokeEndpoint=[null], revokeAccessToken=[false], revokeTokensWhenEvicted=[false], authorizeEndpoint=[https://localhost:9444/oidc/endpoint/OP/authorize], authorizeEndpointHasParameter=[false], tokenEndpoint=[localhost:9444/oidc/endpoint/OP/token], loginErrorUrl=[null], loginErrorUrlHasParameter=[false], sendParamsTologinErrorUrl=[false], cbServletContext=[/oidcclient], endpointsInitialized=[false], RPCookieName=[OIDCSESSIONID_RP1], rpScope=[openid profile], rpCallbackHostAndPort=[null], responseType=[code], responseTypeEnum=[CODE], authRequestIsImplicit=[false], allowImplicitTokenAuthentication=[false], accessTokenRequired=[true], urlEncodeEnabled=[false], createHttpSession=[false], isRefreshEnabled=[true], postParameterCookieSize=[4093], sslOnly=[true], httpOnly=[true], trustStore=[null], verifyingAlias=[null], stateCookieName=[OIDCSTATE_RP1], urlCookieName=[OIDCREQURL_RP1], cbUri=[null], usePostForIntrospection=[true], tokenEndpointAuthMethodIsPost=[true], defaultRealmName=[null], useRealm=[null], verifyIssuerInIat=[false], overrideIdTokenExp=[false], sessionTimeoutMillis=[0], encodeNewline=[true], useDefaultIdentifierFirst=[false], includePortInDefaultRedirectUrl=[true], audiences=[not null], tokenReuse=[true], setLtpaCookie=[true], useJwtFromRequest=[no], useJwt=[NO], headerName=[null], allAudience=[false], acrValues=[null], nonceEnabled=[false], contentSecurityPolicy=[null], contentSecurityPolicyHasNonce=[false], discoveryEndpoint=[localhost:9444/oidc/endpoint/OP/.well-known/openid-configuration], endSessionEndpoint=[https://localhost:9444/oidc/endpoint/OP/end_session], useDiscovery=[true], grantType=[null], clientCredentialsFlow=[false], useJavaScript=[true], userinfoEndpointEnabled=[true], mapIdentityToRegistry=[false], introspectClientId=[null], introspectClientSecret=[null]) |
How can I tell if the OIDC TAI will process a request or not?
To see if the OIDC TAI is processing a request, search for an entry that looks like the following in an ODIC trace:
RelyingParty > isTargetInterceptor(req[not null]) Entry |
You'll find a trace block that looks something like this:
[7/13/20 10:57:59:245 CST] 0000008d TAIWrapper > isTargetInterceptor() Entry
[7/13/20 10:57:59:245 EDT] 000000b0 RelyingParty > OIDC: isTargetInterceptor(
[7/13/20 10:57:59:245 CST] 0000008d OidcTAIConfig > getRelyingPartyConfig Entry [7/13/20 10:57:59:245 CST] 0000008d OidcTAIConfig > isAcceptedByRegx Entry [7/13/20 10:57:59:245 CST] 0000008d OidcTAIConfig 3 Evaluating for request uri: [/snoop] [7/13/20 10:57:59:245 CST] 0000008d OidcTAIConfig 3 The url [/snoop] is being intercepted by OIDC RelyingParty [7/13/20 10:57:59:245 CST] 0000008d OidcTAIConfig < isAcceptedByRegx returns [true] Exit [7/13/20 10:57:59:245 CST] 0000008d RelyingParty 3 The URL: [ [7/13/20 10:57:59:245 CST] 0000008d RelyingParty < ==> OIDC: isTargetInterceptor returns [true] Exit [7/13/20 10:57:59:245 CST] 0000008d TAIWrapper < isTargetInterceptor(): Jazz Security Architecture OIDC TrustAssociationInterceptor returning true Exit |
In this case, the TAI config was:
[1/25/17 11:43:17:813 CST] 00000001 TrustAssociat 3 Trust Properties = {clientId=s_app_a, authorizeEndpointUrl=https://localhost:8020/oidc/endpoint/OP/authorize, introspectEndpointUrl=https://localhost:8020/oidc/endpoint/OP/introspect, callbackServletContext=/oidcclient, interceptedPathFilter=/oidctestapp.*,/snoop, useStateCookies=false, clientSecret=app_a_secret, tokenEndpointUrl=https://localhost:8020/oidc/endpoint/OP/token, scope=openid general} |
How can I tell if my application is protected?
An application must have web constraints in order for it to be protected by any TAI, or even a form login.
To find out if your application URI has web constraints, search the trace for either your URI or getConstraints. For example:
[1/10/20 11:29:18:001 EST] 0000009a WebConstraint > getConstraints: Entry /myLogin GET [1/10/20 11:29:18:001 EST] 0000009a WebConstraint 3 webConstraintsTable.length = 0 [1/10/20 11:29:18:001 EST] 0000009a WebResourceCo > isStandardHTTPMethod Entry GET [1/10/20 11:29:18:001 EST] 0000009a WebResourceCo < isStandardHTTPMethod Exit true [1/10/20 11:29:18:001 EST] 0000009a WebConstraint < getConstraints Exit [1/10/20 11:29:18:001 EST] 0000009a WebCollaborat 3 No WebConstraints for URI = /myLogin, method = GET |
Where is the entry point for the OIDC TAI?
The entry point for the OIDC TAI is negotiateValidateandEstablishTrust. Search for an Entry for this method on the RelyingParty class:
[1/25/17 11:40:21:797 CST] 0000008c TAIWrapper > negotiateAndValidateEstablishedTrust() Entry [1/25/17 11:40:21:797 CST] 0000008c RelyingParty > negotiateValidateandEstablishTrust(req[not null,res[not null]) Entry [1/25/17 11:40:21:797 CST] 0000008c OidcTAIConfig > getRelyingPartyConfig Entry [1/25/17 11:40:21:797 CST] 0000008c OidcTAIConfig > isAcceptedByRegx Entry [1/25/17 11:40:21:797 CST] 0000008c OidcTAIConfig 3 Evaluating for request uri: [/snoop] [1/25/17 11:40:21:797 CST] 0000008c OidcTAIConfig 3 The url [/snoop] is being intercepted by OIDC RelyingParty [1/25/17 11:40:21:797 CST] 0000008c OidcTAIConfig < isAcceptedByRegx returns [true] Exit [1/25/17 11:40:21:797 CST] 0000008c RelyingParty 3 RelyingParty processing the request for: [/snoop] |
What should I look for to see if this is the initial request from the browser?
[1/25/17 11:40:21:797 CST] 0000008c RelyingParty > initiateLogin(req[not null,res[not null], rpConfig[not null]) Entry [1/25/17 11:40:21:797 CST] 0000008c RelyingParty 3 ==> OIDC: INITIATING LOGIN |
What should I look for to see if this is the redirect from the OP?
[1/25/17 11:40:23:938 CST] 0000008c RelyingParty > handleSigninCallback(req[not null,res[not null], rpConfig[not null]) Entry [1/25/17 11:40:23:938 CST] 0000008c RelyingParty 3 ==> OIDC: PROCESS LOGIN RESPONSE FROM OP |
How can I see the POST/GET sent to the OP to obtain the JWT?
To see the request that is sent to the OP to obtain the JWT, search the trace for Request to URL
[1/25/17 11:40:23:938 CST] 0000008c RelyingPartyU 3 POST Request to URL: [1/25/17 11:40:23:938 CST] 0000008c RelyingPartyU 3 Content: grant_type=authorization_code&code=1mkLbwqnhWXLGmMMEsptPQBAwdq3uJ&redirect_uri=https%3A%2F%2Flocalhost%3A9443%2Foidcclient%2Fprovider1&client_id=app_a& |
How can I see the response from the OP?
To find the response from the OP, search the trace for getData:
[1/25/17 11:40:24:156 CST] 0000008c RelyingPartyU < getData returns [{"access_token":"xgPKFmHWrViGDaYtamd84BzJjruzZgnpHlTUrShO","token_type":"Bearer","expires_in":14,"scope":"openid general","refresh_token":"ogePSzIQ4OmEJUxvwkRHtl4So2lLA5motrBndc7VYp8Dkf1whJ","id_token":"eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo4MDIwL29pZGMvZW5kcG9pbnQvT1AiLCJpYXQiOjE0ODUzNjYwMjQsImdyb3VwSWRzIjpbImdyb3VwMSIsImdyb3VwMiJdLCJzdWIiOiJ0ZXN0dXNlciIsImV4cCI6MTQ4NTM2NjA1NCwiYXVkIjoiYXBwX2EiLCJyZWFsbU5hbWUiOiJCYXNpY1JlYWxtIiwidW5pcXVlU2VjdXJpdHlOYW1lIjoidGVzdHVzZXIiLCJhdF9oYXNoIjoiWGMtWmdEOENDWDNndVdkMS1WTGR6QSJ9.xpNN7qGWEellulDtuzdr3Ft7xQo7Z2iIu-GvpLwHrQs"}] Exit |
Can I see the JWT in readable format?
The OIDC runtime will attempt to print out the ID token and access token in readable format. You can search for "id token[" or "access token[":
[1/25/17 11:40:24:188 CST] 0000008c SessionData 3 id token[header[{"alg":"HS256"}], claims[{"iss":" [1/25/17 11:40:24:188 CST] 0000008c SessionData 3 access token[NotJWTFormat] |
Is there an easy way to follow the overall flow in an OIDC trace?
If your editor has the ability to list all instances of a search string, you can search for "==> OIDC:" to see a high-level flow of the OIDC TAI processing in a trace. For example:
Find all "==> OIDC:", Match case 165 54:[8/5/20 19:45:36:318 EDT] 00000001 RelyingPartyU 3 ==> OIDC: BEGINNING TO CALL OUT TO DISCOVERY ENDPOINT ON OP 180 54:[8/5/20 19:45:37:584 EDT] 00000001 RelyingPartyU 3 ==> OIDC: RETURNED FROM DISCOVERY ENDPOINT 5859 53:[8/5/20 19:47:18:069 EDT] 00000097 RelyingParty < ==> OIDC: isTargetInterceptor returns [true] Exit 5886 54:[8/5/20 19:47:18:069 EDT] 00000097 RelyingParty 3 ==> OIDC: Inbound request [https://localhost:9443/snoop] 5919 54:[8/5/20 19:47:18:069 EDT] 00000097 RelyingParty 3 ==> OIDC: INITIATING LOGIN 6060 54:[8/5/20 19:47:18:178 EDT] 00000097 RelyingParty 3 ==> OIDC: Sending redirect to [https://localhost:9444/oidc/endpoint/OP/authorize] via javascript 6063 54:[8/5/20 19:47:18:194 EDT] 00000097 RelyingParty 3 ==> OIDC: PROCESS COMPLETE 6578 53:[8/5/20 19:47:24:782 EDT] 00000097 RelyingParty < ==> OIDC: isTargetInterceptor returns [true] Exit 6605 54:[8/5/20 19:47:24:798 EDT] 00000097 RelyingParty 3 ==> OIDC: Inbound request [https://localhost:9443/oidcclient/client1?code=mw73jEP6LoWqvNr9sxRidPY97lVjcq&state=-256255792_1596671238069] 6613 54:[8/5/20 19:47:24:798 EDT] 00000097 RelyingParty 3 ==> OIDC: PROCESS LOGIN RESPONSE FROM OP 6654 54:[8/5/20 19:47:24:798 EDT] 00000097 RelyingParty 3 ==> OIDC: BEGINNING CALL OUT TO TOKEN ENDPOINT ON OP 6676 54:[8/5/20 19:47:24:892 EDT] 00000097 RelyingParty 3 ==> OIDC: RETURNED FROM CALL OUT TO TOKEN ENDPOINT 6761 54:[8/5/20 19:47:24:892 EDT] 00000097 RelyingPartyU 3 ==> OIDC: BEGINNING TO CALL OUT TO USERINFO ENDPOINT ON OP 6779 54:[8/5/20 19:47:24:923 EDT] 00000097 RelyingPartyU 3 ==> OIDC: RETURNED FROM USERINFO ENDPOINT 6981 54:[8/5/20 19:47:25:079 EDT] 00000097 RelyingParty 3 ==> OIDC: Sending redirect to [https://localhost:9443/snoop] 6984 54:[8/5/20 19:47:25:079 EDT] 00000097 RelyingParty 3 ==> OIDC: PROCESS COMPLETE 7244 53:[8/5/20 19:47:25:095 EDT] 00000097 RelyingParty < ==> OIDC: isTargetInterceptor returns [true] Exit 7271 54:[8/5/20 19:47:25:095 EDT] 00000097 RelyingParty 3 ==> OIDC: Inbound request [https://localhost:9443/snoop] 7292 54:[8/5/20 19:47:25:110 EDT] 00000097 RelyingParty 3 ==> OIDC: AUTENTICATING USING SESSION COOKIE. 7405 54:[8/5/20 19:47:25:110 EDT] 00000097 RelyingParty 3 ==> OIDC: PROCESS COMPLETE Total found: 20 |
If your editor can't list all, then you can do repetitive searches on "==> OIDC:" to follow the flow through the trace.
Does the OIDC TAI require session affinity?
When running in a cluster environment, the OIDC TAI either requires session affinity or the use of a load balancer that is using an algorithm that sends rapid requests from the same client to the same cluster member. If you are using IHS as your front end, ensure that you have the OIDC TAI property, provider_<id>.createSession set to true. The default is false. This property directs the OIDC runtime to create the JSESSIONID cookie that IHS requires to maintain session affinity.
Request
Number
|
Request | Response | Cookies |
---|---|---|---|
1 | Request to the secure application URL | Set redirect to the OP login URL | Set state cookie |
2 | Request to the OP login URL |
Set redirect to the WAS OIDC client URL
(/oidcclient by default)
|
|
3 |
Request to the WAS OIDC client URL
(/oidcclient by default)
|
Set redirect to the application URL | Remove state cookie Set session cookie |
4 | Request to the application URL |
Set LTPA cookie
(if configured)
|
When state cookies are enabled, the OIDC TAI uses a local cache with cookie backup for state data. When cluster caching is enabled, a DynaCache shared cluster cache is used for session data. State cookies and cluster caching are enabled by default. This sounds like the session affinity issue should be covered. The problem is that the OIDC TAI has authenticated the user on step 3, but then the request is sent back into the TAI on step 4 by core security requesting authentication again. This requires the session data in the cache. The time elapsed between steps 3 and 4 is not long enough for the cache to replicate, therefore, requests 3 and 4 must be handled by the same JVM. This means that the entire login process must occur on a single JVM.
How can I enable OpenId Connect across multiple clusters within the cell?
The protected resources must reside on the same application server on which the OIDC RP application, WebSphereOIDCRP.ear, is installed and accepting requests.
- To meet this requirement, when running in a multiple cluster environment, the OIDC TAI requires session affinity across multiple clusters.
- To set session affinity across multiple clusters you must use Intelligent Management for Web Server Plugins.
- The following steps are required to enable OpenId Connect across multiple clusters within the cell:
See Configuring Intelligent Management for web servers for information on how to set up Intelligent Management. - Set the following OIDC TAI property:
provider_<id>.createSession=true - Map the OIDC RP application to the clusters where you intend to use it.
- Set up Intelligent Management.
- Set the following OIDC TAI property:
Can you make the OIDC TAI not write an LTPA cookie?
The OIDC TAI itself does not write LTPA cookies. However, when the OIDC TAI passes information to core security to create the Subject, it can say if it wants the LTPA cookie created or not. There is an OIDC TAI configuration option for setting the LTPA cookie. The property to use is provider_(id).setLtpaCookie.
The OIDC TAI can operate in two modes: an OpenID Connect Relying Party and JWT authentication. In OIDC RP mode, the setLtpaCookie property defaults to true. In JWT authentication mode, setLtpaCookie defaults to false.
How does the OIDC TAI use DynaCache?
How can I tell if DynaCache is enabled?When the DynaCache feature is enabled on your server, the OIDC TAI uses DynaCache to manage the session and state caches regardless of the TAI's clusterCaching setting. When you set clusterCaching=false, the DistributedObjectCache named OIDCRPDistributedCacheMap is still created, but KEY_ENABLE_CACHE_REPLICATION is set to false instead of true. This means that each cluster member will have its own cache.

[3/1/17 13:37:29:774 CST] 0000008c DynaCacheUtil 3 isDynamicCacheEnabled returns [true]. |
If the DynaCache feature is enabled on your server, you can customize the caching behavior by creating your own JNDI cache definition. If you create your own JNDI cache for use by the OIDC TAI, the property to pass it to the TAI is -jndiCacheName. See Using object cache instances for additional information about setting up a JNDI cache.
If the DynaCache feature is not enabled on your application server, local in-memory state and session caches are used. There are some local cache customization settings for the TAI:
sessionCacheSize sessionCacheCleanupFrequency maxStateCacheSize |
CWTAI2028W: The OpenID Connect test fix will stop taking requests on [2/2/2017 12:00 PM].
This means several things:
|
If you've received an OIDC test fix that is tightly controlled, you should test the fix, then uninstall it as soon as you can to return to your original level.
The OIDC TAI is configured to intercept my requests, but the requests are going directly to my application and not being redirected to the OP
In this example, we are going to debug the following issue:- The URI that we want to have redirected to the OP for authentication is /myLogin.
- When the request is received by the application server, the request is being sent directly to /myLogin; an authentication request is not sent to the OP.
Debug procedure:
- Make sure that trust association is enabled:
[1/10/20 13:25:05:163 EST] 00000001 TrustAssociat 3 isTrustAssociationEnabled returns [true] - Make sure the RelyingParty class is a configured TAI:
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat 3 getInterceptors returns [not null]
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat 3 TAI class name[0]: com.ibm.ws.security.web.TAMTrustAssociationInterceptorPlus
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat 3 TAI class name[1]: com.ibm.ws.security.spnego.TrustAssociationInterceptorImpl
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat 3 TAI class name[2]: com.ibm.ws.security.oidc.client.RelyingParty - Make sure the RelyingParty class was initialized successfully:
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat A SECJ0121I: Trust Association Init class com.ibm.ws.security.oidc.client.RelyingParty loaded successfully - Make sure that the RelyingParty configuration is loaded successfully:
[1/10/20 13:24:54:345 EDT] 00000001 RelyingParty < initialize Exit
[1/10/20 13:24:54:345 EDT] 00000001 RelyingParty < getVersion returns [1.3.0] Exit
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat A SECJ0122I: Trust Association Init Interceptor signature: 1.3.0
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat < loadInterceptor (success) Exit- Take action:
- Search the trace for the entries like this:
[1/10/20 13:24:54:345 EDT] 00000001 TrustAssociat < loadInterceptor (exception) Exit - Page back in the trace to find the configuration error.
Action: Fix the configuration error.
- Search the trace for the entries like this:
- Take action:
- Check to see if RelyingParty.isTargetInterceptor is being invoked for the URI
- Search the trace for isTargetInterceptor.
- Check a few lines down to find the URI being evaluated, for example:
[1/10/20 13:24:54:355 EST] 00000094 OidcTAIConfig 3 Evaluating for request uri: [/myLogin]
- Take action:
- If you find an entry for your URI, check a little farther down in the trace to see if the TAI is intercepting the request:
[1/10/20 13:24:54:357 EST] 00000094 RelyingParty < isTargetInterceptor returns [false] Exit - If your URL is going through the TAI, but you are being sent to your endpoint and not the OP, then isTargetInterceptor must be returning false.
- If isTargetInterceptor returns true, and you are not redirected to the OP, then some error occurred in the TAI, and you would be getting a 403.
- If you do not find an isTargetInterceptor entry for your URI, check to see if your URI is protected. If the URI has no web constraints, the request will not go through any TAI:
[1/10/20 11:29:18:001 EST] 0000009a WebConstraint > getConstraints: Entry
/myLogin
GET
[1/10/20 11:29:18:001 EST] 0000009a WebConstraint 3 webConstraintsTable.length = 0
[1/10/20 11:29:18:001 EST] 0000009a WebResourceCo > isStandardHTTPMethod Entry
GET
[1/10/20 11:29:18:001 EST] 0000009a WebResourceCo < isStandardHTTPMethod Exit
true
[1/10/20 11:29:18:001 EST] 0000009a WebConstraint < getConstraints Exit
[1/10/20 11:29:18:001 EST] 0000009a WebCollaborat 3 No WebConstraints for URI = /myLogin, method = GET
Action: If your URI is not protected, protect it.
- If you find an entry for your URI, check a little farther down in the trace to see if the TAI is intercepting the request:
CWTAI2007E: The OpenID Connect relying party (RP) encountered a failure during the login. The exception is [StateId parameter is null]. Check the logs for details that lead to this exception.
The "StateId parameter is null" error occurs when an endpoint that has the same context root of WebSphereOIDCRP.ear is invoked with an HTTP request that does not contain a StateId parameter. The default context root for OIDC RP callback ear, WebSphereOIDCRP.ear is /oidcclient. The OIDC RP callback in intended to be called directly by an OP and those requests must contain a StateId parameter. This error ordinarily occurs when the endpoint was invoked by a browser instead of an OP. Alternatively, the OP may be failing to send the StateId parameter.
CWTAI2009I: The OpenID Connect relying party (RP) did not find an entry for session cookie OIDCSESSION_12345678 in the Session cache.
The OIDC TAI maintains session data for a client in DynaCache or a local cache. The session data entries in the cache hold the JWTs and other information required to maintain the session. The index into the session data cache is held in a browser cookie. It is possible that the browser cookie can still exist, but there is no session data entry in the cache to go with it. You should only get this error if you are running in a cluster environment and clusterCaching=true (the default). Common causes for this error are:
- You do not have session affinity and not enough time has elapsed for DynaCache to replicate across the cluster.
- The volume of active users is causing OIDC sessions to be evicted from the cache.
Remediation:
Do one or more of the following:
- Enable session affinity.
- If you cannot enable session affinity and your load balancer is using the round-robin algorithm, consider changing your load balancer algorithm to something that is more likely to hit the same cluster member for requests from the same client in rapid succession.
- If the DynaCache feature is enabled on your server, consider customizing the caching behavior by creating your own JNDI cache definition. See the entry, How does the OIDC TAI use DynaCache?, above for information about how the OIDC TAI uses DynaCache.
- Remove the OIDC class, com.ibm.ws.security.oidc.client.RelyingParty, from the base security custom property com.ibm.websphere.security.InvokeTAIbeforeSSO so that the session is maintained by the LTPA cookie instead of the OIDC cookie. Consider the following when making this decision:
- What happens if you add the class to InvokeTAIbeforeSSO?
If you add the OpenID Connect Relying Party TAI (OIDC RP TAI) to InvokeTAIbeforeSSO, the TAI will be invoked each time a request is made to the protected resource:- The first time a user logs in, they will be redirected to the OpenID Connect provider (OP) and a set of JSON Web Tokens (JWT) will be sent to the application server for the user.
- On the first request that the application server receives after the access token from the JWT expires, a refresh cycle will begin. Depending on OIDC and OP settings, one of the following will occur:
- The user will be redirected to the OP
- The refresh token from the JWT will be sent to the OP to get a new access token.
- What happens if you do not add the class to InvokeTAIbeforeSSO?
If you do not add the OpenID Connect Relying Party TAI class to the InvokeTAIbeforeSSO list, the server will check for LTPA cookies on the request before invoking the TAI:- The first time a user logs in, they will be redirected to the OpenID Connect provider (OP) and a set of JSON Web Tokens (JWT) will be sent to the application server for the user.
- On the first request that the application server receives after the LTPA expires, the user will be redirected to the TAI.
- If the access token has also expired, a refresh cycle will begin (see the explanation above).
- If the access token has not expired, a new LTPA token will be created.
-
Avoid trouble: If the LTPA expiration is longer than that of the access token, it is possible to end up with expired JWTs on a user's WebSphere Subject. Consider this if down-stream applications use the JWTs stored on the WebSphere Subject.
Avoid trouble: If you have shared LTPA keys with other WebSphere cells in your environment, then the LTPA cookies already generated by those cells are valid for access to the protected resources. Until the user is redirected to the OP after the LTPA expires, the Subject will only contain what was placed on it by the other cell.
- What happens if you add the class to InvokeTAIbeforeSSO?
Does my application have access to the JWTs that were received from the OP?
The OpenID Connect TAI puts the ID token, access token and refresh token in a Hashtable in the private credentials on WebSphere runAs Subject. The OIDC TAI provides an application programming interface called com.ibm.websphere.security.oidc.util.OidcClientHelper. You can use this API to perform many functions related to the TAI. The OidcClientHelper API is available starting in WebSphere fix packs 8.5.5.16 and 9.0.5.0, and OIDC TAI v1.2.0.
You can retrieve the tokens from the runAs Subject in one of two ways:
- Use the com.ibm.websphere.security.oidc.util.OidcClientHelper API to retrieve the tokens from the runAs Subject for you.
import com.ibm.websphere.security.oidc.util.OidcClientHelper;private static String getIdToken() throws java.lang.Exception {try {return OidcClientHelper.getIdTokenFromSubject();} catch (java.lang.Exception e) {return null;}return null;}
- Retrieve the tokens from the runAs Subject yourself:
This example uses the WSSUtilFactory.getRunAsSubject() convenience method to get the WebSphere runAs Subject. This method is available starting in fix packs 8.0.0.13, 8.5.5.10 and 9.0.
import java.util.Hashtable;
import java.util.Iterator;
import javax.security.auth.Subject;
import com.ibm.websphere.wssecurity.wssapi.WSSUtilFactory;
private static final String ID_TOKEN = "id_token";
private static final String ACCESS_TOKEN = "access_token";
private static final String REFRESH_TOKEN = "refresh_token";
private static final String USER_INFO = "user_info";
private static final String TOKEN_TYPE = "token_type";
private static final String SCOPE = "scope";
private static String getIdToken() {
String idToken = null;
WSSUtilFactory wssuf = WSSUtilFactory.getInstance();
Subject subject = wssuf.getRunAsSubject();
if (subject != null) {
Iterator authIterator = subject.getPrivateCredentials(Hashtable.class).iterator();
if ( authIterator.hasNext() ) {
Hashtable creds = (Hashtable) authIterator.next();
if ( creds != null ) {
idToken = (String) creds.get(ID_TOKEN);
}
}
}
return idToken;
}
CWTAI2007E: The OpenID Connect relying party (RP) encountered a failure during the login. The exception is [com.ibm.ws.security.oidc.client.RelyingPartyException: CWTAI2031E: The OpenID Connect state cookie [OIDCSTATE_sp1] does not exist on the HTTP request.].
This is an error because the OIDC TAI was unable to perform a complete login. However, depending on of the environment, this error message may be expected and can be ignored. Further information and direction can be obtained from the Explanation and User Action for the CWTAI2031E message:
Explanation:When you get this message, the OIDC TAI was unable find its state cookie on the HTTP request. When you receive this message as part of CWTAI2007E, the OIDC TAI was unable to retrieve the state information from the local cache, so it must use cookies for state data instead of local storage and then the state cookie was not found on the HTTP request. The stateId is created by the OIDC TAI when the client makes a request. This stateId is sent to the OP and the OP returns this stateId to the OIDC TAI. This stateId is used to associate the authentication response from the OP with the client's original request data to the protected resource. This message means that there was either no OIDC state cookie or no data in the OIDC state cookie with which to restore the client's original request data. This problem can occur if:
|
User Action:
|
CWTAI2019E: The state id [8he53qrmnp4mtkm20f1v357vq6_1495623614293] in the OpenID Connect relying party (RP) state cookie [OIDCSTATE_sp1] does not match the state id [9if64rsnoq5nuln31g2w468wr7_2506734725304] received from the OpenID Connect provider.
This is an error because the OIDC TAI was unable to perform a complete login. Further information and direction can be obtained from the Explanation and User Action for the CWTAI2019E message:
Explanation:
When you receive this message, the OIDC TAI is using cookies to retrieve the state data for the request either because the state data was not found in the local cache or local caching was disabled. The stateId is created by the OIDC TAI when the client makes a request. This stateId is sent to the OP and the OP returns this stateId to the OIDC TAI. This stateId is used to associate the authentication response from the OP with the client's original request data to the protected resource. This message means that the stateId in the authentication response from the OP is different than the stateId in the OIDC TAI state cookie, therefore the client's original request data cannot be restored. The most likely cause for this problem is that the client initiated a request to a protected resource, then, before completing the login with the OP, the client initiates a login to another protected resource and the cookie written by the first request was overwritten by the second. |
User Action:
There are several things that you can do about this issue:
|
CWTAI2030I: The OpenID Connect TAI was unable to retrieve the request data with stateId [8he53qrmnp4mtkm20f1v357vq6_1495623614293] from the state map. It may have expired.
This is an informational message. If it is part of a CWTAI2007E, there is an error because the OIDC TAI was unable to perform a complete login. However, depending on of the environment, this error message may be expected and can be ignored. Further information and direction can be obtained from the Explanation and User Action for the CWTAI2030I message:
Explanation:
When you receive this message as part of CWTAI2007E, the OIDC TAI is using only local storage for state data with no cookie backup. The stateId is created by the OIDC TAI when the client makes a request. This stateId is sent to the OP and the OP returns this stateId to the OIDC TAI. This stateId is used to associate the authentication response from the OP with the client's original request data to the protected resource. This message means that the OIDC TAI was unable to retrieve the data for the client's original request from local storage using the stateId that was returned from the OP. This can be caused by several things:
If you see this message in a log without it being part of a CWTAI2007E error, the OIDC TAI has logged this message before attempting to use the cookie. No action is required in this case unless you also get an error with the cookie. |
User Action:
If you are running in a cluster environment, you need to ensure:
When both cookies and local state caching are enabled, the TAI will use local storage first, then use the cookie as a backup.
|

|
CWTAI2007E: The OpenID Connect relying party (RP) encountered a failure during the login. The exception is [com.ibm.ws.security.oidc.client.RelyingPartyException: The value for the OIDC state cookie [OIDCSTATE_NGE3OGY0NGQtY2E0ZS00] failed validation.].
To debug this error, do the following:
|
If you find that you are getting this cookie validation error and you have verified that your process did not produce the cookie, if you are operating in a cluster environment, do the following:
- Ensure that you have session affinity configured on your front end.
- If you are using IHS as your front end, ensure that you have the provider_<id>.createSession OIDC TAI custom property set to true. The default is false. This property directs the OIDC runtime to create the JSESSIONID cookie that IHS requires to maintain session affinity.
This realm is not the current realm, nor the admin realm, nor a trusted realm
When you access your protected resource, then successfully log in to the OP, you may be presented with a form login. When this happens, you may see an entry like this in one of the most recent FFDC files:com.ibm.websphere.security.auth.WSLoginFailedException: This realm is not the current realm, nor the admin realm, nor a trusted realm: SomeForeignRealm com.ibm.ws.security.config.SecurityConfigImpl@855256a2 C:\was90011_base\WebSphere\AppServer\profiles\server\config\cells/wsx7Cell/security.xml (admin) :com.ibm.websphere.security.auth.WSLoginFailedException: This realm is not the current realm, nor the admin realm, nor a trusted realm: SomeForeignRealm |
To debug the issue, do the following one of the following:
|
Remediation:
Regardless of where it came from, to fix this issue, perform one of the following actions:
|
OIDC cookies are not deleted when I log out
In order for OIDC cookies to be deleted on logout, the HttpServletRequest.logout method must be invoked from an OIDC protected URL. When this happens, the RelyingParty.logout method is invoked. If you have this problem, you need to see if the RelyingParty.logout is being invoked. Search your OIDC trace for:
==> OIDC: PERFORMING LOGOUT |
If you don't see that entry in your OIDC trace, these are the most likely causes:
- There is no code that invokes HttpServletRequest.logout.
- The code that invokes HttpServletRequest.logout is not intercepted by the TAI because:
- The endpoint is not intercepeted by the TAI's filters.
- The endpoint does not have security constraints, therefore it did not enter the TAI.
See Enabling programmatic logout for an OpenID Connect Relying Party in the IBM Documentation for information on how to perform OIDC logout to ensure that OIDC cookies are removed upon WebSphere logout.
How can I set up my Google™ API Console project so that I can use the Google OP with the WebSphere OIDC TAI?
If you want to use the Google OP with the OIDC TAI, you must first have a Google API Console project. Your console project must have at least one web client configuration.
Go to the Examples: OpenID Connect, Liberty and WebSphere traditional page to see steps for Setting up a Google™ API Console project to use the Google OP with a WebSphere traditional or Liberty OIDC RP.
How can I set up the WebSphere OIDC RP TAI to use the Google™ OP?
You can configure the WebSphere traditional OIDC RP to use the Google as the OP server.
Go to the Examples: OpenID Connect, Liberty and WebSphere traditional page to see steps for Setting up the WebSphere traditional OIDC RP TAI to use the Google™ OP.
Note:
This document uses the term WebSphere traditional to refer to WebSphere Application Server v9.0 traditional, WebSphere Application Server v8.5 full profile, WebSphere Application Server v8.0 and earlier, WebSphere classic, traditional WebSphere, traditional WAS and tWAS.
Related Information
Was this topic helpful?
Document Information
Modified date:
17 March 2022
UID
swg21975593