OpenID Connect with Canvas and TM1
Overview
In general, Open ID Connect has 4 types of flows as defined on https://tools.ietf.org/html/rfc6749
Authorization Code*
Implicit*
Resource Owner Password Credentials
Client Credentials
*Requires user interactions
For this setup we will be using Authorization Code flow for both TM1 and Canvas, and optionally Resource Owner Password Credentials with Canvas if using the Task Scheduler.
The version of TM1 were this was first tested is PA 2.0.5.
Open ID Provider Setup
To setup OIDC Authentication with TM1, you will need the following information / files from your OpenID Provider (Okta, OneLogin, Auth0, etc.):
Client ID
Client Secret
SSL Certificates (Certificate Chains from Root to the End User) of the Authorization Provider
Well Known OpenID Configuration URL
During configuration of your Open ID provider, you will need to provide it with the base URL of your Canvas application and the types of grants / flows it will allow.
For example, with the Samples application, this will be the URL: http://localhost:8080/samples/. For completeness, we will target to have it granted with Resource Owner Password Credentials too – that is, aside from the Authorization Flow.
Below is a sample screenshot from Okta on how the above configuration may look like:
TM1 Pre-OpenID Connect Configuration
Once you have finish the setup with your Open ID Provider, we can now go into configuring TM1.
• Update tm1s.cfg and add the following parameters:
SupportOpenConnect=T
OpenConnectConfig="<path to your TM1 configuration file with OIDC Authorization Provider info>"
The value for the OpenConnectConfig is a json file containing the credentials it needs to communicate with your OpenID Provider.
As an example, we have created an Okta.json file, located at the following path:
OpenConnectConfig="C:\Users\User\Desktop\OIDC\Okta.json"
Where a sample content of the Okta.json file is below:
{
"tm1_client_id":"TM1_OIDC_Registered_Client_ID",
"tm1_client_secret_keyfile":"C:\\CWAS\\db\\canvas_sample\\oidc_key.dat",
"tm1_client_secret_pwdfile":"C:\\CWAS\\db\\canvas_sample\\oidc_file.dat",
"tm1_callback_url":"https://cwtestlab:8882/api/callback",
"tm1_client_claim_map":"sub",
"tm1_discovery_endpoint":"http://cwtestlab:3000/.well-known/openid-configuration"
}
Replace TM1_OIDC_Registered_Client_ID with the Client ID provided by your Authentication Provider for your application.
For the Secret Key File and Password File, generate these files via the tm1crypt.exe file using the Client Secret as provided by your Authentication Provider for your application.
Command to generate looks like this:
<TM1 bin64>\tm1crypt.exe -pwd <client secret> -keyfile
<export_path_of_oidc_secret_key>.dat -outfile <export_path_of_oidc_secret_file>.dat validate Executing the above with the validate parameter, will prompt you to re-enter the client secret key in the end for verification.
The tm1_callback_url is just in the form of
https://<YourRESTAPIURLHost>:< YourRESTAPIURLPort>/api/callback
And lastly, the URL Discovery Endpoint will be the OpenID Configuration URL, that is provided by your Authentication Provider.
If using HTTPS with your Well Known Configuration URL, the SSL Certificates of those URL needs to be imported into TM1. Please see the Import SSL Certificate in the Appendix for this.
On a successful setup, you should see the following similar entry on your TM1 Server Log:
5996 [] INFO 2018-09-20 16:17:14.968 TM1.Server Starting OIDC Key server thread. Thread Id: 5996. TM1 Post-OpenID Connect Configuration
After you have setup your OpenID connection, you will still need to add into TM1 the list of users as will be retrieved from your OpenID Configuration. This might be the email address of the user, or a random user ID. This is usually the “sub” value property of a user, if inspected via the Open ID provider’s API.
Below is an example Open ID Token that could be returned into TM1 (via Okta):
Note that the “sub” value is the username that TM1 will look for on your TM1 application. Depending on the behavior of your TM1 server, this value can also be thrown out by the OIDC loggers if TM1 cannot find them. For this example, we have configured the above to be a user in TM1 as follows:
Also note that you can still login using Architect. All other clients using REST API such as Arc will now need to authenticate first via the OpenID Provider.
Canvas
On your instances.json file, add the following property to the TM1 instance that was configured to connect with OpenID:
• “useSSOWithOIDC”: true
Next, create a JSON file within WEB-INF/config/oidc. The name of the file should match the name of the instance which will be configured for OpenID.
Path should be located in <Canvas Application>/WEB-INF/config/oidc/<instance-name>.json. For dev instance for example, it would be: <Canvas Application>/WEB-INF/config/oidc/dev.json Sample content of the JSON file would be:
{
“clientID”: “XXXX123456789ZZ”,
“clientSecret”: “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA”,
“discoveryEndpoint”: “http://<OpenID Provider’s Well Known Configuration>”
} That should be it!
Restart your Canvas Application Server. Go to your page’s Configuration page for example to trigger the OpenID Connect mechanism.
What to Expect
When you open up a page in Canvas that has TM1 data on it, it will check first if the session is valid.
If not, it will redirect the current page to the Open ID Provider’s Login page to ask the user to login. Once successful, the OpenID Provider will then redirect the user back to the Canvas page that triggers it.
Canvas will now try to login to TM1, given the new set of information present in the URL (the code parameter in particular). If valid, it will proceed as per normal with the page, and all TM1 operations should work based off the user that was retrieved from OpenID.
Appendix
Sample Okta Authorization Flow Setup
Additional OIDC TM1 Loggers
TM1 added new loggers for OIDC purposes. Add the following into your tm1s-log.properties file to generate an oidc.log file you can monitor for OIDC authentication:
log4j.logger.TM1.OID=DEBUG, OIDC
log4j.logger.TM1.OID.JWT=DEBUG, OIDC
log4j.logger.TM1.OID.JWK=DEBUG, OIDC
log4j.logger.TM1.OID.Curl=DEBUG, OIDC
log4j.additivity.TM1.OID=false log4j.additivity.TM1.OID.JWT=false
log4j.additivity.TM1.OID.JWK=false
log4j.additivity.TM1.OID.Curl=false
log4j.appender.OIDC=org.apache.log4j.SharedMemoryAppender
log4j.appender.OIDC.File=../oidc.log
log4j.appender.OIDC.MaxFileSize=10 MB
log4j.appender.OIDC.MaxBackupIndex=5
log4j.appender.OIDC.TimeZone=Local Importing SSL Certificates
You encountered an error when starting up TM1:
1108 [] ERROR 2018-09-20 13:48:54.511 TM1.Server Unable to retrieve OIDC config from discovery endpoint: https://dev-984358-admin.oktapreview.com/oauth2/default/.wellknown/openid-configuration Solution:
The certificates required by TM1 to connect with the Authentication Provider URL is possibly missing. To add these, download from the AP’s site their certificate and add them into TM1 via the
gsk8capicmd_64.exe utility. As of this documentation, this was found under TM1 bin64 path. The following certificates (*.der or *.cer) need to be added into the TM1 store:
Root Certificate
Intermediate Certificates (this can be 1 or more, depending on who issued the certificates)
End User Certificate
All of these can be exported by going into the Well Known OpenID Configuration and Exporting via Edge.
Note that these are Base64-Encoded contents for which inside these files, you will find the following tags: -----BEGIN CERTIFICATE----- until -----END CERTIFICATE-----.
You should now have at least 3 CER/DER files at this point. Note that the CER and DER extension are interchangeable. The important part is the content of the file. All three of them should contain something similar to below:
-----BEGIN CERTIFICATE-----
DB2wHB6/6E3S9zXTYkmq3aY5p0zPhFKxopwlRr47wEqdrnCjV9Kf7SXWSc/QP0SY rlzLoUELl7T2Fa2Ui5wET+/VQYDNbpSiDR75CwD302VhIxJpoVg+GJwqBDsbcad5 rklHEyhfN3avWNTz8Cci/8zHrEDDybC0lEH+xZc5T99JR6/efzA=
-----END CERTIFICATE----- Copy them all base64 encoded files into <TM1 bin64>\ssl folder. We will now add them into the TM1 store via gsk8capicmd_64.exe.
Navigate into <TM1 bin64>\ssl. Assuming that we have the following certificates prepared:
Okta-RootCA.cer
Okta-Intermediate.cer
Okta.cer
Run the following commands:
..\gsk8capicmd_64.exe -cert -add -db ibmtm1.kdb -stashed -format binary -label Okta-RootCA -file Okta-RootCA.cer
..\gsk8capicmd_64.exe -cert -add -db ibmtm1.kdb -stashed -format binary -label Okta-IntermediateCA -file Okta-IntermediateCA.cer
..\gsk8capicmd_64.exe -cert -add -db ibmtm1.kdb -stashed -format binary -label Okta -file Okta.cer As a check that we have imported the correct chain of certificates, run the following command:
..\gsk8capicmd_64.exe -cert -list -db ibmtm1.kdb -stashed -label Okta If you have successfully imported the certificate chain, running the above command will display the RootCA, IntermediateCA and the Okta label as chains of certificates.
Restart TM1 server/service. On the TM1 Server Log file, you should now see a line like this:
5996 [] INFO 2018-09-20 16:17:14.968 TM1.Server Starting OIDC Key server thread. Thread Id: 5996. Generating the Authorization Provider’s Certificate
For the Authorization Provider, you can grab all the Certificates you need by going into the Well Known Open ID URL and exporting the certificate from there. Open them in Internet Explorer and export from there:
On these screenshot, it shows that the URL has three certificates (1 Root, 1 Intermediate and 1 End User Certificate):
Export Each of the three certificates.
On older versions of IE, you might be able to export it directly to a format where the contents of the file starts with BEGIN CERTIFICATE and ends with END CERTIFICATE. But there will be cases where IE allows you to Export it to one type of format only:
On this case, proceed with the export. And then double click on the exported file. It will bring you to a window like below:
Click on the “Details” tab, and then select “Copy to File…”
This will trigger a Wizard. See screenshots below as guide:
References