APAR status
Closed as program error.
Error description
The OIDC TAI has an API to obtain access tokens from an OP using grant_type=client_credentials. Extend the API to to provide program developers a way to obtain access tokens from an OP using grant_type=password. Also provide cache management to facilitate refreshing access tokens that are obtained with either method.
Local fix
Problem summary
**************************************************************** * USERS AFFECTED: IBM WebSphere Application Server * * app developers who want to use * * an OAuth client. * **************************************************************** * PROBLEM DESCRIPTION: There is no OAuth client avalable in * * the application server. * **************************************************************** * RECOMMENDATION: Install a fix pack or interim fix that * * contains this APAR. * **************************************************************** There is no OAuth client available for use in the application server. The OpenID Connect (OIDC) Trust Association Interceptor (TAI) provides OAuth method for obtaining an access token using the client_credentials grant type, but there is no managment provided for refresh.
Problem conclusion
The mechanisims required to communicate with an OAuth provider are already included in the OIDC TAI. The OIDC TAI API is extended to include methods for both the client_credentials and password grant types. The tokens returned from the server are cached and the access token is refreshed if configured to do so. The following API class is added: com.ibm.websphere.security.oidc.util.OauthClientHelper The following methods are included in OauthClientHelper: getValidAccessToken() getValidAccessToken(Subject subj) getValidAccessToken(String token) getClientCredentialsGrantAccessToken() getPasswordGrantAccessToken(String username, String password) createSubjectForJaasLogin(String token) createHashtableForJaasLogin(String token) createHashtableForJaasLogin(String token, boolean allowTokenWithNoSessionData) The OAuth functions that are added to the OIDC TAI are not intended to be a full-function OAuth client. OAuth functions are provided that place minimal impact on the primary OIDC runtime. Two new values are added for the provider_(id).grantType OIDC property. The full list of available values is: client_credentials password all ========================== Configuration Notes: * When the grantType parameter is specified on a configuration entry, that entry is not used for OIDC or JWT authentication. * When a provider entry includes the grantType parameter, the tokenEndpointUrl and clientId properties are required and the clientSecret and scope properties are optional. * There can only be one enty each for grantType=client_credentials and grantType=password. * An entry with grantType=all, will override all other grantType entries. * You can use a discovery endpoint to populate desired Oauth configuration data. * When getClientCredentialsGrantAccessToken is invoked, the configuration associated with the grantType=client_credentials (or all) is used. * When getPasswordGrantAccessToken is invoked, the configuration associated with the granType=password (or all) is used. ========================== Usage Notes: When you are operating from data on the runAs Subject, you may not know if the data was obtained via OAuth APIs or an OIDC login. Because of this, the OAuth data occupies the same cache as the OIDC session data, and the getValidAccessToken methods in the both the OauthClientHelper and OidcClientHelper classes will operate on tokens cached either way. However, if you want to perform any operation that takes an access token as a parameter, the access token must be obtained with an OAuth method, not OIDC. For example, if you want to use OauthClientHelper.getValidAccessToken(String token), you must first obtain the token with one of the OauthClientHelper methods. For instance, getPasswordGrantAccesstoken(). ========================== Javadoc: /* * Retrieve a valid access token based on the access * token in the current runAs Subject * * A null value will be returned in the following * instances: * * Administrative security is not enabled. * * Trust Association is not enabled. * * The OIDC RP TAI is not configured and successfully * initialized. * * There is no access token on the runAs Subject. * * There are any errors while attempting to obtain the * OAuth data associated with the access token on the * runAs Subject. * * The access token on the runAs Subject has expired and * there is no refresh token associated with the access * token. * * The access token on the runAs Subject has expired and * any error occurs while attempting to refresh the * token. * * The access token on the runAs Subject has expired and * any error occurs while updating the OAuth token cache. * * If the access token retrieved from the runAs subject has * expired and is successfully refreshed, the following will * be updated with the new access token: * * * Its associated OAuth data in the OAuth token cache * * The runAs Subject * * This method will only throw an exception if errors occur * related to the initial processing of the runAs Subject. * If an error occurs after information has been retrieved * from the runAs Subject, an FFDC entry will be created, * but the exception will not be emitted by this method and * the method will return null in most cases. If the access * token has been refreshed, but the runAs Subject cannot be * updated, an FFDC will be emitted and the method will * return the new access token. * * If there is a userinfoEndpointUrl configured for the * access token, the user info will also be refreshed. * * @return A valid access token or null if the conditions * listed above are true. * @throws Exception if an error occurs either while * obtaining the runAs Subject or accessing the * private credentials. */ public static String getValidAccessToken() throws Exception; /** * Retrieve a valid access token based on the access token * in the input Subject. * * A null value will be returned in the following instances: * * * The input subject is null. * * Administrative security is not enabled. * * Trust Association is not enabled. * * The OIDC RP TAI is not configured and successfully * initialized. * * There is no access token on the runAs Subject. * * There are any errors while attempting to obtain the * OAuth data associated with the access token on the * runAs Subject. * * The access token on the runAs Subject has expired and * there is no refresh token associated with the access * token. * * The access token on the runAs Subject has expired and * any error occurs while attempting to refresh the * token. * * The access token on the runAs Subject has expired and * any error occurs while updating the OAuth token cache. * * If the access token retrieved from the input subject has * expired and is successfully refreshed, the following will * be updated with the new access token: * * * Its associated OAuth data in the OAuth token cache * * The input Subject * * This method will only throw an exception if errors occur * related to the initial processing of the input Subject. * If an error occurs after information has been retrieved * from the input Subject, an FFDC entry will be created, * but the exception will not be emitted by this method and * the method will return null in most cases. If the access * token has been refreshed, but the input Subject cannot be * updated, an FFDC will be emitted and the method will * return the new access token. * * If there is a userinfoEndpointUrl configured for the * access token, the user info will also be refreshed. * * @return A valid access token or null if the conditions * listed above are true. * @throws Exception if an error occurs when accessing the * private credentials in the Subject. */ public static String getValidAccessToken(Subject subj); /** * Retrieve a valid access token based a cached access token * . * A null value will be returned in the following instances: * * * Trust Association is not enabled. * * The OIDC RP TAI is not configured and successfully * initialized. * * There are any errors while attempting to obtain the * OAuth data associated with the input access token. * * The input access token has expired and * there is no refresh token associated with the access * token. * * The input access token has expired and any error * occurs while attempting to refresh the token. * * The input access token has expired and any error * occurs while updating the OAuth token cache. * * If the input access token has expired and is successfully * refreshed, the following will be updated with the new * access token: * * * Its associated OAuth data in the OAuth token cache * * If there is a userinfoEndpointUrl configured for the * access token, the user info will also be refreshed. * @return A valid access token or null if the conditions * listed above are true. * @throws Exception if an error occurs when accessing the * private credentials in the Subject. */ public static String getValidAccessToken(String token) throws Exception; /** * Retrieve an access token from the token endpoint using * the client_credentials grant_type * * An exception will be emitted in the following instances: * * * Trust Association is not enabled. * * There is no valid OIDC RP TAI configuration entry * specifying grantType=client_credentials or * grantType=all. * * An error occurs while obtaining the access token from * the token endpoint. * * An access token is not received from the token * endpoint. * @return The access token retrieved from the server * @throws Exception if one of the error outlined above * occurs */ public static String getClientCredentialsGrantAccessToken() throws Exception; /** * Retrieve an access token from the token endpoint using * the password grant_type * * An exception will be emitted in the following instances: * * * Trust Association is not enabled. * * There is no valid OIDC RP TAI configuration entry * specifying grantType=password or grantType=all. * * An error occurs while obtaining the access token from * the token endpoint. * * An access token is not received from the token * endpoint. * * @return The access token retrieved from the server * @throws Exception if one of the error outlined above * occurs */ public static String getPasswordGrantAccessToken( String username, String password) throws Exception; /** * Create a Subject based on an OAuth access token. * * This method can be used if you have obtained an OAuth * token in a JAAS login module and want to create a Subject * that the Oauth/OIDC APIs can use. It will contain the * OIDC hashtable that has the access token, refresh token, * etc. If userinfo was obtained during the process, the * WSCREDENTIAL_SECURITYNAME will be set to the user name * from the userinfo. * * An exception will be emitted in the following instances: * * * Trust Association is not enabled. * * There is no valid OIDC RP TAI configuration entry * specifying grantType=password or grantType=all. * * An error occurs while obtaining the access token from * the token endpoint. * * An access token is not received from the token * endpoint. * * The method will return null if the OAuth access token is * not found in the OAuth session cache. * This method will only create Subjects for OAuth tokens * that were obtained with OAuth APIs. * * @return Subject based on the input OAuth access token * @throws Exception if one of the error outlined above * occurs */ public static Subject createSubjectForJaasLogin( String token) throws Exception; /** * Create a Hashtable for use in a JAAS login based on an * OAuth access token. * * This method can be used if you have obtained an OAuth * token in a JAAS login module and want to create a * Hashtable that the Oauth/OIDC APIs can use. This * Hashtable is added to the Subject that you create. If * userinfo was obtained during the process, the * WSCREDENTIAL_SECURITYNAME will be set to the user name * from the userinfo. * * An exception will be emitted in the following instances: * * * Trust Association is not enabled. * * There is no valid OIDC RP TAI configuration entry * specifying grantType=password or grantType=all. * * An error occurs while obtaining the access token from * the token endpoint. * * An access token is not received from the token * endpoint. * * The method will return null if the OAuth access token is * not found in the OAuth session cache. * * @return OIDC Hashtable based on the input OAuth access * token * @throws Exception if one of the error outlined above * occurs */ public static Hashtable createHashtableForJaasLogin( String token) throws Exception; /** * Create a Hashtable for use in a JAAS login based on an * OAuth access token. * * This method can be used if you have obtained an OAuth * token in a JAAS login module and want to create a * Hashtable that the Oauth/OIDC APIs can use. This * Hashtable is added to the Subject that you create. If * userinfo was obtained during the process, the * WSCREDENTIAL_SECURITYNAME will be set to the user name * from the userinfo. * * An exception will be emitted in the following instances: * * * Trust Association is not enabled. * * There is no valid OIDC RP TAI configuration entry * specifying grantType=password or grantType=all. * * An error occurs while obtaining the access token from * the token endpoint. * * An access token is not received from the token * endpoint. * * set allowTokenWithNoSessionData to true if you want a * Hashtable back even if no entry in the OAuth token cache * is found for the token. In this case, only the token * itself will be in the hashtable. If you put the * Hashtable on a Subject, the Oauth/OIDC APIs will be able * to retrieve it. * * @return OIDC Hashtable based on the input OAuth access * token * @throws Exception if one of the error outlined above * occurs */ public static Hashtable createHashtableForJaasLogin( String token, boolean allowTokenWithNoSessionData) throws Exception; The fix for this APAR is targeted for inclusion in fix packs 8.5.5.20 and 9.0.5.7. For more information, see 'Recommended Updates for WebSphere Application Server': https://www.ibm.com/support/pages/node/715553
Temporary fix
Comments
APAR Information
APAR number
PH23614
Reported component name
WEBS APP SERV N
Reported component ID
5724H8800
Reported release
900
Status
CLOSED PER
PE
NoPE
HIPER
NoHIPER
Special Attention
NoSpecatt / Xsystem
Submitted date
2020-03-23
Closed date
2021-02-17
Last modified date
2021-02-17
APAR is sysrouted FROM one or more of the following:
APAR is sysrouted TO one or more of the following:
Fix information
Fixed component name
WEBS APP SERV N
Fixed component ID
5724H8800
Applicable component levels
R850 PSY
UP
R900 PSY
UP
[{"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SSEQTP","label":"WebSphere Application Server"},"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"9.0","Line of Business":{"code":"LOB45","label":"Automation"}}]
Document Information
Modified date:
01 November 2021