ELM Applications Authentication and Authorization via OAuth 2.0 Workflow
Authors: ShubjitNaik, DineshKumar, BharathRao, SudarshanRaoBuild basis: Engineering Lifecycle Management 7.x and higher
IBM Engineering Lifecycle Management (ELM) applications use a number of authentication protocols: JEE container authentication (Basic and FORM), OAuth 1.0a, OIDC and OAuth 2.0 (embedded in OpenID Connect/OIDC with extensions for the Jazz Security Architecture/JSA profile), Kerberos/SPNEGO, etc.
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 For further details on the workflow on OAuth2.0 and different grant types please review the OAuth 2.0 Framework at OAuth 2.0 . In the next section we introduce how to register a new Client in Jazz Authorization Server and Access ELM Protected resources via the Authorization Code grant type.
Here is an example command for registering a clientId to be used with CURL commands
Following is the command that needs to be run, You will receive a
NOTE: This article covers the OAuth2.0 authentication and friendship relationship between two application servers for establishing an integration. This article is not for authenticating end user scripts or API Automation scripts. End user and Automation scripts should authenticate with actual user IDs for traceability and accountability. Using the OAuth 2.0 consumer keys and secrets is not associated with a particular user.
There are two forms of application-to-application authentication implemented by Jazz applications (ELM), OAuth 1.0aand OpenID Connect.
Up until the 6.0 software release, OAuth 1.0a was the only type of inter-application authentication supported. It requires pair-wise relationships between communicating applications – applications that are registered as "friends" of each other can send requests to each other that will be authenticated using OAuth 1.0a. For bi-directional communications, each application must be a friend of each other. The friending application is allocated a key and secret which it uses to authenticate with the friend application; they are the equivalent of a username and password for the application itself.
Starting CLM version 6.0 Jazz Authorization Server was introduced and when applications are configured with Jazz Security Architecture SSO enabled, they can use OpenID Connect to authenticate with each other. OpenID Connect is a simple identity protocol and open standard that is built on top of the OAuth 2.0 protocol that enables client applications to rely on authentication that is performed by an OpenID Connect Provider to verify the identity of a user.
Review the Jazz Security Architecture on the article https://jazz.net/library/article/75
When deployed with Jazz Authorization Server (IBM Liberty OIDC feature) ELM supports OAuth 2.0. The focus of this article is on accessing ELM protected resources via the OAuth2.0 workflow.
If JAS is further configured to delegate authentication to either a SAML IDP or a Third Party OIDC Server , follow the article OAuth2.0 Access flow with ELM Configured with SAML IdP or Third Party OIDC Provider
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. OAuth 2.0 Protocol Flow
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 For further details on the workflow on OAuth2.0 and different grant types please review the OAuth 2.0 Framework at OAuth 2.0 . In the next section we introduce how to register a new Client in Jazz Authorization Server and Access ELM Protected resources via the Authorization Code grant type.
Accessing ELM Protected Resources via Authorization Code Grant Type
The authorization code grant type is most commonly used because it is optimized for server-side applications and allows confidential and public clients to exchange an authorization code for an access token.High Level Authorization Flow
OAuth 2.0 Framework Reference - Authorization Code Grant Considering ELM deployed with Jazz Authorization Sevrer, the Resource Owner is ELM and the authorization server is Jazz Authorization Server. The Access flow is as following- Pre-Req - Register a new Client with Jazz Authorization Server
- Authentication with Jazz Authorization Server
- Request for Authorization Code
- Request for Access Token with the Authorization Code
- (Optional) Validate the Access Token by retrieving User credentials
- Access ELM Protected Resources via Access Token
Application/Client Registration
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. The redirect URI is where the service will redirect the user after they authorize (or deny) your application, and therefore the part of your application that will handle authorization codes or access tokens. Once your application is registered, the service will issue “client credentials” in the form of a client identifier and a client secret. In this example, we are using a Script to list out EWM/ERM project areas and are using CURL commands. We will create our own ClientID and ClientSecret and register a new client with JAS providing all the details as follows# cd <JAS_HOME>/cli # ./mkclient -a https://<JASURL>/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="authorization_code","client_credentials","implicit","refresh_token","urn:ietf:params:oauth:grant-type:jwt-bearer"In the above example replace the following variables
- JASURL - The Initial URL (and Port if present) 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 typesandgrant 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 grant_types="authorization_code","client_credentials","implicit","refresh_token","urn:ietf:params:oauth:grant-type:jwt-bearer" \ -P response_types="code","token","id_token token"You can review the registration details via the URL
https://jas.example.com/oidc/endpoint/jazzop/registration
Authenticate to Jazz Authorization Server
In this example, we are using a Script (bash) to list out EWM/ERM project areas and are using CURL commands. To generate cookies and headers we make aPOST request to /jazzop/j_security_check URL with a valid ELM User
You can declare USER,PASSWORD,COOKIES and HEADERS as variables to begin with:# USER=JazzUser # PASSWD=JazzUserPassword # COOKIES=cookies.txt # HEADERS=headers.txt Following is the command that needs to be run, You will receive a
HTTP/1.1 302 Found response with jazzop_sso_cookie value which would be used as the Authenticated session for JazzUser.
# curl -X POST -d "j_username=$USER" -d "j_password=$PASSWD" -k -c $COOKIES -b $COOKIES -D $HEADERS "https://[JASURL]/jazzop/j_security_check"
- Replace
[JASURL]with the Jazz Authorization Server URL, examplejas.example.com
HTTP/1.1 302 Found Date: Mon, 30 Nov 2020 12:07:20 GMT Server: IBM_HTTP_Server X-Powered-By: Servlet/3.0 Location: https://jas.example.com/jazzop/ Set-Cookie: jazzop_sso_cookie=UxSR6K3lAKkOF/0cExEYjnVDTJiAlnyETZnUI4wqsoY3dla/RFXkut03WbzPLqLfimCSHsPKhHHCoDe0vP75uC/kznP1azyexmhvnOKWed7qmHRCiBHZLpkR1qnZ51JsJTrn8zCxtHxZaRWMEGH3N9s0JguH6HF0g8ASfILx68g/tEjErbGDf4S+kTGswP4jhdpn2JeNvtG8h4mKa2nPGT1aDjktNcAd0mdoHZkHq88FvDQ3SZmbSJgIgs+7ln5LyeEVA1ey+n/1yD5PKUxz2obmadjoa2lz0qqNBAdbtPB1288bm3+T4apKcv0THgP2lnFUqw496DlZcji+z4Qtc5+DrFfuFpCLYhBr899qNvsFXJPclp2IwnL2aPYibgKR; Path=/ Set-Cookie: WASReqURL=""; Expires=Thu, 01 Dec 1994 16:00:00 GMT; Path=/ Expires: Thu, 01 Dec 1994 16:00:00 GMT Cache-Control: no-cache="set-cookie, set-cookie2" Content-Length: 0 Content-Language: en-US
Request for Authorization Code
To continue with the flow and request an authorization code , construct a URL similar the following (Note we are requesting for response_type=code via the Authorization Endpoint)https://jas.example.com/oidc/endpoint/jazzop/authorize?response_type=code&client_id=curlclientId&client_secret=curlclientpassword&redirect_uri=https%3A%2F%2Fjas.example.com%2Fjazzop &scope=openid%20profile%20email%20general
-
jas.example.comis your Jazz Authorization server -
client_Id,client_secret,redirect_uriandscopeare the ones created earlier during registering a client
GET request to the URL following the CURL command below including the HEADERS and COOKIES from previous step
curl -k -b $COOKIES -c $COOKIES -D $HEADERS -X GET \ "https://jas.example.com/oidc/endpoint/jazzop/authorize?response_type=code&client_id=curlclientId&client_secret=curlclientpassword&redirect_uri=https%3A%2F%2Fjas.example.com%2Fjazzop&scope=openid%20profile%20email%20general"If the request is valid it redirects to the application redirect URI, along with an authorization code generated by the authorization server. This code is relatively short-lived depending on the OAuth service. The
Location value in headers.txt is updated with redirect_uri specified adding a state and code to the query string. Here is a sample output of headers.txt
HTTP/1.1 302 Found Date: Mon, 30 Nov 2020 13:14:48 GMT Server: IBM_HTTP_Server X-Powered-By: Servlet/3.0 Pragma: no-cache Location: https://jas.example.com/jazzop?session_state=QQqRY8PLlilADmJZz8S6ZiU8NTbxY%2B66THdCuDxQU8U%3D.2201081ba070b&code=cb1wdJdAkoVrreyOY2T4B4r3XmHxvc Set-Cookie: oidc_bsc=PbAX7k8cpEKNCJhFvD6BrarEufBPcIiKF7I099IyG+M=; Path=/ Expires: Thu, 01 Dec 1994 16:00:00 GMT Cache-Control: no-store, no-cache=set-cookie Content-Length: 0 Content-Language: en-USCapture the value
code=cb1wdJdAkoVrreyOY2T4B4r3XmHxvc
OR Run the following command to extract the authorization code:
cat headers.txt | grep Location | cut -d '=' -f 3Result:
cb1wdJdAkoVrreyOY2T4B4r3XmHxvc
Request for Access Token
Now we will exchange the Authorization Code for an Access Token. To request for an Access Token using the Authroziaton code from previous setup , we can make aPOST request to the Token endpoint URL using CURL as shown below:
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=authorization_code' \ --data-urlencode 'code=<AUTHORIZATION CODE from previous step>' \ --data-urlencode 'redirect_uri=https://jas.example.com/jazzop' \ --data-urlencode 'client_id=curlclientId' \ --data-urlencode 'client_secret=curlclientpassword'
-
jas.example.comis your Jazz Authorization server -
codeIs the Authorization code generated from the previous step -
client_Id,client_secret,redirect_uriandscopeare the ones created earlier during registering a client
{"access_token":"VQQSVldMW4cUtslwvKdCvC2eYKkq384BCxwsnFqV","token_type":"Bearer","expires_in":7200,"scope":"general openid profile email","refresh_token":"0ORqqbs0EuArYG9nLuFrQnpXxr659G5pSrIsyacDqLvhrGAiK8","id_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzaHViaml0IiwiYXRfaGFzaCI6Il9WSEZZNU9wM3lmRmxzcGNpU0ppRVEiLCJyZWFsbU5hbWUiOiJlbG1jbHVzdGVyczEuZnlyZS5pYm0uY29tOjEwMzg5IiwidW5pcXVlU2VjdXJpdHlOYW1lIjoidWlkPXNodWJqaXQsb3U9VXNlcnMsZGM9bGRhcDMsZGM9Y29tIiwiZ3JvdXBJZHMiOlsiY249SmF6ekFkbWluczMsb3U9R3JvdXBzLGRjPWxkYXAzLGRjPWNvbSIsImNuPUphenpQcm9qZWN0QWRtaW5zMyxvdT1Hcm91cHMsZGM9bGRhcDMsZGM9Y29tIiwiY249SmF6elVzZXJzMyxvdT1Hcm91cHMsZGM9bGRhcDMsZGM9Y29tIl0sImlzcyI6Imh0dHBzOi8vZWxtY2x1c3RlcnMxLmZ5cmUuaWJtLmNvbTo0NDMvb2lkYy9lbmRwb2ludC9qYXp6b3AiLCJhdWQiOiJjdXJsY2xpZW50SWQiLCJleHAiOjE2MDY3NTAyMz
Capture the value "access_token":"VQQSVldMW4cUtslwvKdCvC2eYKkq384BCxwsnFqV"
The Authorization Code flow is complete! We now have the Access Token which can be used to make ELM API requests.
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 UserJazzUser 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 using CURL, replace the Bearer value with the Access Token. curl -k --location --request GET 'https://elm.example.com/rm/process/project-areas' \ --header 'Authorization: Bearer VQQSVldMW4cUtslwvKdCvC2eYKkq384BCxwsnFqV'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, 25 Nov 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 aGET 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 VQQSVldMW4cUtslwvKdCvC2eYKkq384BCxwsnFqV'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"}
JAS with SAML IDP Or Third Party OIDC Providers
When JAS is further configured to delegate authentication to either a SAML IDP or a Third Party OIDC Server the OAuth2.0 flow mentioned in this article isNOT Supported.
Starting version 7.0.2 ELM and JAS 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 OAuth 2.0 Password grant type can be used with Application passwords to generate an access token from JAS, refer this Article OAuth2.0 Access flow with ELM Configured with SAML IdP or Third Party OIDC Provider
Related topics: JazzAuthorizationServer, OAuth 2.0
External links:
Additional contributors: None
| I | Attachment | Action | Size | Date | Who | Comment |
|---|---|---|---|---|---|---|
| |
oauth20protocolflow.jpg | manage | 59.3 K | 2020-11-27 - 11:42 | ShubjitNaik | Source https://oauth.net/2/ |
Contributions are governed by our Terms of Use. Please read the following disclaimer.
Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.

