/ Development  

Connecting Okta as IdP through OTDS

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

Every week I see interesting new things passing by which have a relation with our beloved platform. This time an interesting service called Okta. Why?

  • I saw an interesting session during OT World last November
  • Leader in the “Magic Quadrant for Access Management”
  • They are the World’s #1 Identity Platform
  • I’m curious how the connection will look like

After a quick research it looks like they provide a web based Single-Sign-On portal for users! This is also the intention for OTDS…right? Indeed a valid conclusion, but Okta brings it all into the cloud as single point of truth! Nice, but what does this mean? Does it mean me need to maintain our user management into the cloud with Okta? Yes, could be, but it’s also possible to attach your own LDAP interface like the popular “Active Directory”. Didn’t we post already on connecting our own LDAP interface (we used OpenLDAP) as synchronized partition into OTDS? Correct again! So, why Okta? Well, just because we can my friends and because we will learn a lot on the OTDS side of things. Make your own conclusion if it’s beneficial for your own solution, but this post brings a positive vibe to it.

The use-case: Add Okta as primary Identity Provider to the AppWorks platform

These are the steps on the “how” part:

  • Okta
    • Account creation (just a development account will do it for now)
    • Create an integrated SAML 2.0 app
    • Create persons (aka our Users) and assign them to the created app
  • OTDS
    • Creation of an “Authentication Handler”
    • Create an auto-provisioned non-synchronized partition
    • Add the partition to the access roles for the AppWorks resource (which we already have in place)

This is the flow we will start to see in the end of this post.

  1. User opens the AppWorks URL
  2. It’s redirected to the Okta login portal (this skips the OTDS login screen!)
  3. Doing authentication on the Okta side
  4. When valid, redirect the user back to AppWorks (with a SAML cookie!)
  5. The cookie makes sure we are able to SSO into AppWorks

Let get right into it…

Spin up your machine (Make sure you have OTDS connected as Identity Provider) and open AppWorks from your favorite browser. Open the development toolbar (<F12> from a Chrome perspective) and do a login request with your account. From the ‘network’ tab you should see something like this passing by:

For a platform account (in my case ‘sysadmin’)
saml_001

For an OTDS account (in my case ‘awdev’)
saml_002

Both images show a login procedure based on a SAML access token. SAML? Yes, you know…Security Assertion Markup Language. So, this post has to do with the authentication mechanism of the platform. Have also a look at this post where we describe the authentication mechanism of the platform in more details.

Enough of the SAML and OTDS login procedure and let’s see what value Okta will bring to the table…


Setup Okta

Start by creating yourself a developer account on https://developer.okta.com/signup, activate it, and login. You end up in the admin portal where we have the ability to create a new “integrated” application:

saml_004

Make the sign-in method “SAML 2.0” during app creation

Give a nice name like ‘OTDS AppWorks’

saml_005

Click ‘Next’ to continue to the next tab which can be configured like this:

  • Single sign on URL: http://192.168.56.107:8181/otdsws/login
  • Audience URI: http://192.168.56.107:8181/otdsws/login
  • Name ID format: Unspecified
  • Add the following attribute statements (keep them in memory for later usage):

saml_006

Leave the other settings as default! When done, we can click ‘Next’

For the “Feedback” configuration we choose to be a software vendor (as we would like to integrate!). Finally, we can hit the ‘Finish’, and we see the creation of our Identity Provider app.

When you scroll a bit down in the ‘Sign On’ tab, you have the ability to grab the metadata URL for our IdP. Looks like this: https://{host}.okta.com/app/{app_id}/sso/saml/metadata. Just copy the URL for later usage in OTDS!

Time to add some users (aka ‘Persons’) to our App

This can be done from the ‘Directory’ section where we open the ‘People’ node. Here we can add a new person:

saml_007

I just create 2 persons. ‘user1@appworks.com’ and ‘user2@appworks.com’ with both password ‘User@-02’ (Yes, it must be something complex!)

Once created, it’s time to assign those users to our created app:

saml_008

We finished the “Okta” part…Now let’s dive into the OTDS part…


Setup OTDS (to authenticate against Okta)

Open OTDS from a URL like this: http://192.168.56.107:8181/otds-admin/#authhandlers. We land directly on the ‘Auth Handlers’ part of OTDS. Create a new one with input like this:

saml_009

Click ‘Next >’

For the ‘User Partition’, we just use ‘Global’ for now. Click ‘Next >’. You land on the ‘Parameters’ section where we provide information like this:

saml_010

Notes:

  • The IdP metadata URL is from the previous copied URL (from the Okta app!)
  • We set the IdP NameID Format to ‘unspecified’ (like we also saw by default in the Okta app!)
  • Active By Default set to false makes sure we first ‘see’ the OTDS login screen instead of directly show the Okta login screen.
  • Update the ‘XML Signature Algorithm’ to http://www.w3.org/2001/04/xmldsig-more#rsa-sha256. Have a look in the Okta app where we use ‘RSA_SHA256’ as “Signature Algorithm”
  • Finally, make sure to map the correct attributes like this (where the ‘claim’ properties need to map the attributes defined in the Okta app):
    saml_011

The rest can be left as default for now; hit ‘Next >’

In the ‘Configuration’ section we just add the ‘mail’ principal attribute, and we save it all.

saml_012

Our ‘AuthHandler’ is created. Double-check on the metadata via URL http://192.168.56.107:8181/otdsws/login?SAMLMetadata=OKTA.

Time to make sure our Okta users will automatically provision into an OTDS partition (as our ‘AuthHandler’ looks globally…remember!). For this we go to the ‘System Config’ section where we make sure to set these 2 attributes:

saml_013

With this setting, we are also required to create a new non-synchronized partition with a corresponding name ‘Auto-Provisioned Accounts’:

saml_014

Finally, we also need to add our brand-new auto-provisioned partition to our ‘AppWorks’ access role (connected to our already available AppWorks resource if you “normally” login through OTDS):

saml_015

DON’T FORGET TO SAVE ONCE ADDED!! (a common mistake!)

Now it’s time for our first test. Have yourself a new browser (use the old IE browser for this first test!) and open the AppWorks login page, so you get the ‘normal’ OTDS login screen. Only this time you also see a new option:

saml_016

You see this OTDS login screen because we set ‘Active by default’ to false on the ‘AuthHandler’ in OTDS!
Why the old IE browser? With the “samesite” changes in Google Chrome and Edge Chromium, additional steps need to be performed to send the correct attributes on the cookies. See here!

Also, make sure you log out from the Okta admin portal (or use a new incognito tab!) before you hit the ‘OKTA’ button. If you get an error like Sorry, you can't access OTDS AppWorks because you are not assigned this app in Okta, you are already logged in with an account which is not assigned to the Okta app!

Once ready, hit the ‘OKTA’ button, and you are redirected to the Okta login page where we should be able to login with our Okta created accounts:

saml_017

After this Okta login, you’ll be redirected back to AppWorks and entering our beloved “valhalla” with the Okta created user! NICEEEEEE! 😅

Question…What happened in OTDS after this login?


A view in OTDS (and AppWorks)

We passed the login screen of AppWorks, and because we have a non-synchronized partition connected to our AppWorks resource in OTDS, we should have a brand-new user account created within AppWorks. Let’s double-check with our ‘awdev’ account through the regular OTDS login procedure as we don’t skip it (yet!):

saml_018

Assigned to zero roles, but we can change this to our own needs.

If this user is in AppWorks, we should also see something in our auto-provisioned partition in OTDS:

saml_019

It’s getting more interesting by the minute! When you look at the properties of this account, you will also see the ‘firstname’, ‘lastname’, and ‘email’ being filled with valid data from Okta. The ‘email’ is the most important one as we defined it as ‘Auth. Principle Attribute’ in the ‘AuthHandler’ settings…remember?

How did the information get from Okta to OTDS? Well, continue the grind…


Raise OTDS log-level

Time to raise the log level of our OTDS instance to expose a bit more login information. For this we need to dive back into OTDS: http://192.168.56.107:8181/otds-admin/
Login with account ‘otadmin@otds.admin (with in my case password ‘admin’) and open the ‘System Config’ section. Here we set the corresponding setting:

saml_020

After this change we can monitor 2 logfiles (with a bit of clean-up for readability!) which monitors a second login attempt with account: user2@appworks.com

  1. tail -999f /opt/tomcat/latest/logs/otds.log
1
2
3
4
5
6
7
8
9
10
|SAML2Handler||Returning SAML packet: <AuthnRequest Destination="https://{host}.okta.com/app/{okta_app_id}/{id}/sso/saml"><saml:Issuer>http://192.168.56.107:8181/otdsws/login</Issuer><NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"/></AuthnRequest>
|OtdsAuthenticationManager||Authentication attempt with handler OKTA result {CLIENT_CONTINUE_NEEDED, null, null, null}
|SAML2Handler||Processing SAML response: {base_64_string}
|SAML2Handler||NameID in SAML Assertion is user2@appworks.com
|ReplayCache||uuid added to cache: SAML_http://www.okta.com/{UUID}
|OtdsAuthenticationManager||Authentication attempt with handler OKTA result {SUCCESS, null, null, user2@appworks.com}
|OtdsAuthenticationManager||Search for user2@appworks.com using attributes [mail] returned: null
|RestConnector||Entering Create method for entity with attributes : {user_attributes}
|OtdsAuthenticationManager||Search for user2@appworks.com using attributes [mail] returned: cn=user2@appworks.com,ou=OKTA,ou=Root,ou=Auto-Provisioned Accounts,ou=IdentityProviders,dc=identity,dc=opentext,dc=net
|AsEngine||createTicket: Resource ID: 94ce0699-f3a2-4a15-9a2d-b38b61f81610, OTDS user ID: user2@appworks.com, Credential name: user2@appworks.com, entryDN: cn=user2@appworks.com,ou=OKTA,ou=Root,ou=Auto-Provisioned Accounts,ou=IdentityProviders,dc=identity,dc=opentext,dc=net

We can clearly see our new Okta SAM 2.0 request with a SAML response in base64 format (which we will decode in the next section!). Eventually we can also see the creation of our ‘User’ entity as part of the Identity Package.

  1. tail -999f /opt/tomcat/latest/logs/directory-access.log
1
2
|Authentication Service|Success Access|27,Initial authentication successful|192.168.56.1|""|Auto-Provisioned Accounts|"user2@appworks.com"|"Authentication success: user2@appworks.com using authentication handler OKTA for resource 94ce0699-f3a2-4a15-9a2d-b38b61f81610"
|Authentication Service|Success Access|56,Ticket Created|192.168.56.1|""|Auto-Provisioned Accounts|"user2@appworks.com"|"User name [user2@appworks.com] in resource ID [94ce0699-f3a2-4a15-9a2d-b38b61f81610]"

The above log-file shows us eventually a valid authentication for the related partition in OTDS.

DONE…almost!


Tools for troubleshooting

We saw, in the response of the SAML2Handler, a base64 string passing by. What information is behind it? Get a copy of that string from the logfile and open SAML Tool. You can copy it into the left bottom box called “XML to be Base64 Decode“ and hit the ‘Decode’ button. Now you are provided with a familiar XML assertion like this (cleaned for readability):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<saml2p:Response>
...
<saml2:Assertion>
<saml2:Issuer>...</saml2:Issuer>
<ds:Signature>
...
</ds:Signature>
<saml2:Subject>
<saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">user2@appworks.com</saml2:NameID>
...
</saml2:Subject>
<saml2:Conditions>
<saml2:AudienceRestriction>
<saml2:Audience>http://192.168.56.107:8181/otdsws/login</saml2:Audience>
</saml2:AudienceRestriction>
</saml2:Conditions>
<saml2:AuthnStatement>
...
</saml2:AuthnStatement>
<saml2:AttributeStatement>
<saml2:Attribute Name="firstname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml2:AttributeValue>User</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="lastname" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml2:AttributeValue>Two</saml2:AttributeValue>
</saml2:Attribute>
<saml2:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified">
<saml2:AttributeValue>user2@appworks.com</saml2:AttributeValue>
</saml2:Attribute>
</saml2:AttributeStatement>
</saml2:Assertion>
</saml2p:Response>

Another nice tool is a Chrome extension called SAML-tracer. Although my Chrome is not working for this demo (because of the non-security), we can still have a nice response to analyze:

saml_021

Do we learn stuff here…Or what!? 🤓

Give me more, give me more…Well, have you ever analyzed the “OTDS configuration Report”!?
http://192.168.56.107:8181/otds-admin/#systemstatus

saml_022

Open the downloaded file in Notepad and have a search on OKTA 😜


Final test

Our final test is off-course the update on the ‘Active By Default’ flag on our AuthHandler in OTDS!

saml_023

Time for a quick retest where you will eventually also get green flags for a valid login to AppWorks; redirected from OTDS through Okta. If you made it this far you are crowned as the SAML-Okta expert…Hooray!


A fascinating “DONE” where we did a dive in the world of SAML tokens supported with a cloud Identity Provider app crafted in Okta. I thought this was hard stuff to do, but eventually even I made it come to life. With this integration we also learned new things on the OTDS side of things; like the auto-provisioned partition, and the debugging options! I would say, have a great week-end…CU next week in a new post on AppWorks Tips.

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?