When deployed with Jazz Authorization Server (IBM Liberty OIDC feature) Engineering Lifecycle Management solution supports OAuth 2.0. Refer the article ELM and OAuth 2.0 to understand how to use OAuth2.0 protocol flow with ELM deployed with Jazz Authorization Server.
You can further configure the Jazz Authorization Server to delegate the user authentication to your standard, corporate SAML Identity Provideror OIDC Provider.
Starting ELM and JAS version 7.0.2 when configured with a SAML IDP or another OIDC Provider, Non-Web clients can work with Liberty Application Passwords. The Liberty application password feature is a way to circumvent the limitation by using a web browser to handle an identity provider's authentication scheme and producing a relatively long-lived token that can then be used by the native client (non-browser) in a simpler protocol that does not depend on the client being a web browser. The Application Passwords are supported only when JAS is delegating authentication further to a SAML IDP or an OIDC Provider. This feature also allows generating long-lived app token that can be used as an Access token.
The focus of this article is on working with application passwords and application tokens in an OAuth2.0 protocol flow to access ELM Protected resources.
OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.
Access tokens are credentials used to access protected resources. An access token is a string representing an authorization issued to the client. The string is usually opaque to the client. Tokens represent specific scopes and durations of access, granted by the resource owner, and enforced by the resource server and authorization server.
An authorization grant is a credential representing the resource owner's authorization (to access its protected resources) used by the client to obtain an access token. This specification defines four grant types and for further details on the grant types review the OAuth 2.0 Framework at OAuth 2.0 . In this article we will focus on the PasswordGrant Type.
In the next section we introduce how to register a new client in Jazz Authorization Server which is configured with a Third Party OIDC Provider and access ELM Protected resources via the Password grant type.
A pre-requisite is to configure application passwords with ELM and JAS. The instructions are covered in the following wiki Article
The resource owner password credentials grant type is suitable in cases where the resource owner has a trust relationship with the client. Since application passwords are enabled on the Jazz Authorization Server the regular LDAP password will not work with this grant type.
Considering ELM deployed with Jazz Authorization Server which is delegating Authentication to a another OIDC Provider. The Access flow is as following
Once JAS is configured for Application passwords, users will be able to generate app passwords for their userId via the URL https://[JASURL]/oidc/endpoint/jazzop/personalTokenManagement
. We will generate an application password for the userId JazzUser and use it in our example in the next step.
JazzUser
u5RFiMZzrWJMCHtzf69DELLbF3Wc7h3V7okOcnNozF
The application password is valid for 90 days by default. You can modify the App password Lifetime by adding the parameter appPasswordLifetime
Before using OAuth with your application, you must register your application with Jazz Authorization Server. During registration you would need to provide Application Name, Scope, Redirect URI or Callback URL and Grant types. In this example, we are using a Script to list out EWM/ERM project areas and are using CURL commands. We will register a client with JAS mentioning ClientID, ClientSecret and other details as follows
# cd <JAS_HOME>/cli # ./mkclient -a https://jas.example.com/oidc/endpoint/jazzop \ -u <JAS_ADMINISTRATOR>:<PASSWORD> \ -P client_name="<CLIENTNAME>" \ -P client_id="<CLIENT_ID>" -P client_secret="<CLIENT_SECRET>" \ -P redirect_uris="https://<application_URL>/auth/sso","https://<redirect_uri2>/" \ -P trusted_uri_prefixes="https://<Trusted_application_URL>/" \ -P scope="openid profile email general" \ -P functional_user_id="<Functional User>" \ -P functional_user_groupIds="JazzAdmins" \ -P preauthorized_scope="openid profile email general" \ -P response_types="code","token","id_token token" \ -P grant_types="password","authorization_code","client_credentials","implicit","refresh_token","urn:ietf:params:oauth:grant-type:jwt-bearer"
In the above example replace the following variables
jas.example.com
- The URL to your Jazz Authorization Server
scope
, preauthorized_scope
, response types
and grant types
# ./mkclient -a https://jas.example.com/oidc/endpoint/jazzop -u JazzUser:JazzPassword \ -P client_name="CURL Client" -P client_id="curlclientId" -P client_secret="curlclientpassword" \ -P redirect_uris="https://jas.example.com/jazzop","https://localhost/jazzop" \ -P trusted_uri_prefixes="https://jas.example.com/","https://localhost/" \ -P functional_user_id="JazzUser" \ -P functional_user_groupIds="JazzAdmins" \ -P scope="openid profile email general" -P preauthorized_scope="openid profile email general" \ -P response_types="code","token","id_token token" \ -P grant_types="password","authorization_code","client_credentials","implicit","refresh_token","urn:ietf:params:oauth:grant-type:jwt-bearer"
https://jas.example.com/oidc/endpoint/jazzop/registration
There are two variables appPasswordAllowed
and appTokenAllowed
that needs to be set to true
as during registration the mkclient
command does not accept these parameters. We will use the following commands to export and import the registration details:
curlclientId
# cd <JAS_HOME>/cli # ./lsclient -a https://jas.example.com/oidc/endpoint/jazzop -u [UserName]:[Password] curlclientId > curl.json
appPasswordAllowed
and appTokenAllowed
values from: "appPasswordAllowed" : false, "appTokenAllowed" : false,
"appPasswordAllowed" : true, "appTokenAllowed" : true,
# ./ldclient -a https://jas.example.com/oidc/endpoint/jazzop -u [UserName]:[Password] curl.json
In this example, we are using a Script (bash) to list out EWM/ERM project areas and are using CURL commands. Once the user has generated an app-password, along with the ClientID and ClientSecret we can make a POST
request to the Token endpoint URL using CURL as follows:
curl -k --location --request POST \ 'https://jas.example.com/oidc/endpoint/jazzop/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'client_id=curlclientId' --data-urlencode 'client_secret=curlclientpassword' \ --data-urlencode 'scope=openid profile email general' \ --data-urlencode 'username=JazzUser' \ --data-urlencode 'password=u5RFiMZzrWJMCHtzf69DELLbF3Wc7h3V7okOcnNozF'
jas.example.com
is your Jazz Authorization server
password
Is the app password generated by JazzUser earlier
client_Id
, client_secret
are the ones created earlier during registering a client
If the authentication is valid, JAS will send a response containing the Access token (and a refresh token) which is valid for 2 hours by default. The entire response will look something like this:
{"access_token":"8zOuhLoiChkDMVVay1WNwVOracfXZzp8ecnZtRvs","token_type":"Bearer","expires_in":7200,"scope":"general openid profile email","refresh_token":"g87QlO9FKendCs9k46eF0W1MuW2jZaeV8MedUR0fhIVqyRKuua"}
Capture the value "access_token":"8zOuhLoiChkDMVVay1WNwVOracfXZzp8ecnZtRvs"
Note
: This is the first time we would be accessing an ELM based URL
Now that we have an access token for the User JazzUser
who has access to ELM resources, we would be able to retrieve protected resources using this Access Token as a Header on a GET
request.
Here is a GET
request with CURL to list ERM Project Areas, replace the Bearer
value with the Access Token.
curl -k --location --request GET 'https://elm.example.com/rm/process/project-areas' \ --header 'Authorization: Bearer 8zOuhLoiChkDMVVay1WNwVOracfXZzp8ecnZtRvs'
Sample result of the command:
<?xml version="1.0" encoding="UTF-8"?><jp06:project-areas xmlns:jp06="http://jazz.net/xmlns/prod/jazz/process/0.6/"> <jp06:project-area jp06:name="JKE (Requirements Management)"> <jp06:summary>JKE (Requirements Management)</jp06:summary> <jp06:description>The purpose of this project is to specify and manage the requirements of the JKE Business Recovery Matters project.</jp06:description> <jp06:url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ</jp06:url> <jp06:roles-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/roles</jp06:roles-url> <jp06:links-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/links</jp06:links-url> <jp06:members-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/members</jp06:members-url> <jp:admins-url xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/admins</jp:admins-url> <jp06:team-areas-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/team-areas</jp06:team-areas-url> <jp06:project-admins-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/project-admins</jp06:project-admins-url> <jp06:read-access-list-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/read-access-list</jp06:read-access-list-url> <jp:timelines-url xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/timelines</jp:timelines-url> <jp06:access-public>false</jp06:access-public> <jp06:access-visible-to-access-list>false</jp06:access-visible-to-access-list> <jp06:access-visible-to-members>true</jp06:access-visible-to-members> <jp06:modified>Wed, 03 Dec 2020 15:21:11 GMT</jp06:modified> <jp06:archived>false</jp06:archived> <jp:history-url xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/history</jp:history-url> <jp:configuration-management-enabled xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">true</jp:configuration-management-enabled> <jp:configuration-management-mode xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">SINGLE</jp:configuration-management-mode> </jp06:project-area> </jp06:project-areas>
We can send a GET
request to the Userinfo endpoint on JAS to retrieve details of the user to whom the Access Token belongs to. Replace Bearer
value with the Access Token
curl -k --location --request GET 'https://jas.example.com/oidc/endpoint/jazzop/userinfo' \ --header 'Authorization: Bearer 8zOuhLoiChkDMVVay1WNwVOracfXZzp8ecnZtRvs'
Sample result of the command:
{"sub":"JazzUser","groupIds":["cn=JazzUsers,ou=Groups,dc=example,dc=com"],"iss":"https:\/\/jas.example.com\/oidc\/endpoint\/jazzop","email":"jazzuser@jke.net"}
Once JAS is configured for Application passwords, users will be able to generate app tokens
for a specific userId
via the URL https://[JASURL]/oidc/endpoint/jazzop/personalTokenManagement
Limitations
Advantage
Now that we have an app-token for a user who has access to ELM resources, we would be able to retrieve protected resources using this as an Access Token on a GET
request.
Here is a GET
request with CURL to list ERM Project Areas, replace the Bearer
value with the App Token.
curl -k --location --request GET 'https://elm.example.com/rm/process/project-areas' \ --header 'Authorization: Bearer YuZ5H9QtrCv2HBgqlz6UifZ4ZGXA8Wc6IXFZvkHoVf'
Sample result of the command:
<?xml version="1.0" encoding="UTF-8"?><jp06:project-areas xmlns:jp06="http://jazz.net/xmlns/prod/jazz/process/0.6/"> <jp06:project-area jp06:name="JKE (Requirements Management)"> <jp06:summary>JKE (Requirements Management)</jp06:summary> <jp06:description>The purpose of this project is to specify and manage the requirements of the JKE Business Recovery Matters project.</jp06:description> <jp06:url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ</jp06:url> <jp06:roles-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/roles</jp06:roles-url> <jp06:links-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/links</jp06:links-url> <jp06:members-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/members</jp06:members-url> <jp:admins-url xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/admins</jp:admins-url> <jp06:team-areas-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/team-areas</jp06:team-areas-url> <jp06:project-admins-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/project-admins</jp06:project-admins-url> <jp06:read-access-list-url>https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/read-access-list</jp06:read-access-list-url> <jp:timelines-url xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/timelines</jp:timelines-url> <jp06:access-public>false</jp06:access-public> <jp06:access-visible-to-access-list>false</jp06:access-visible-to-access-list> <jp06:access-visible-to-members>true</jp06:access-visible-to-members> <jp06:modified>Wed, 03 Dec 2020 15:21:11 GMT</jp06:modified> <jp06:archived>false</jp06:archived> <jp:history-url xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">https://elm.example.com/rm/process/project-areas/_w-sawC8xEeu-5_iBQYQ_UQ/history</jp:history-url> <jp:configuration-management-enabled xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">true</jp:configuration-management-enabled> <jp:configuration-management-mode xmlns:jp="http://jazz.net/xmlns/prod/jazz/process/1.0/">SINGLE</jp:configuration-management-mode> </jp06:project-area> </jp06:project-areas>
Note: This app token used to list ERM project areas, can only be used with ERM application APIS going forward and will not work for other applications. If you intend to generate a single Access token for all ELM Applications similar to an SSO, use the Password Grant type OAUth2.0 access flow mentioned in the previous section
Status icon key: