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 - A Quick Intro
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.
Configuring Application Passwords in JAS
A pre-requisite is to configure application passwords with ELM and JAS. The instructions are covered in the following wiki Article
Accessing ELM Protected Resources via Password Grant Type
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.
High Level Authorization Flow
Considering ELM deployed with Jazz Authorization Server which is delegating Authentication to a another OIDC Provider. The Access flow is as following
- Pre-Req - Generate an app password for the User
- Pre-Req - Register a new Client with Jazz Authorization Server
- Request for Access Token using app password
- (Optional) Validate the Access Token by retrieving User credentials
- Access ELM Protected Resources via Access Token
Generate app password for the user
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.
- Click on Add New, Select app-password and click Generate
- UserId :
JazzUser
- App Password :
u5RFiMZzrWJMCHtzf69DELLbF3Wc7h3V7okOcnNozF
The application password is valid for 90 days by default. You can modify the App password Lifetime by adding the parameter
appPasswordLifetime
Register Client with Jazz Authorization Server
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
- JAS_ADMIN and PASSWORD - Jazz Authorization Server Administrator User and password
- CLIENTNAME - Name to uniquely identify your Client
- CLIENT_ID and CLIENT_SECRET (You can create your own)
- Redirect URI – Application Redirect URIs
- Trusted URI - Trusted URIs of Application acessing Jazz Authorization Server
- FUNCTIONAL USER - The user ID to associate with a request made on behalf of a client (Create a user, grant access to projects and assign licenses)
- DONOT change values for
scope
, preauthorized_scope
, response types
and grant types
Here is an example command for registering a clientId to be used with CURL commands
# ./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"
- You can review the registration details via the URL
https://jas.example.com/oidc/endpoint/jazzop/registration
Update appPasswordAllowed to true
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:
- Edit the exported file curl.json and change
appPasswordAllowed
and appTokenAllowed
values from: "appPasswordAllowed" : false,
"appTokenAllowed" : false,
- TO
"appPasswordAllowed" : true,
"appTokenAllowed" : true,
Request for Access Token using app password
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"
Access ELM Protected Resources with Access Token
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>
List User Info from Access Token
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"}
Accessing ELM Protected Resources using App-Token
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
- Click on Add New and select app-token and Generate
Limitations
- app-tokens are locked to the first application it is used against, example if the token is used to access protected resources of ERM, it cannot be used to access APIs of EWM, ETM etc.
- Each ELM application needs a different app-token
Advantage
- While Access Tokens generated by different OAuth2.0 types are valid for 2 hours similar to a user session, app-token are long lived and can be configured for custom lifetime, default being 90 days. You can modify the Token Lifetime by adding the parameter appTokenLifetime
Use App Token to access ELM Application Protected Resources
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
External links: