Adobe Enterprise and Okta

Issues

Okta Requirement

We require Okta auth for all of our applications. This week we have added Adobe Enterprise into the mix and while it fits the Okta requirement, it’s extremely bare bones. The implementation is not IDP-initiated, meaning the user will still have to go to adobe.com and type in their email before the Okta auth will take place.

User Sync

From an admin perspective, there is a frustrating lack of SCIM or JIT in this integration. Adobe does supply a user sync tool, however, that won’t work for us as we have no interest in maintaining another server just for user sync. We also don’t want manual interaction to create or maintain users and groups. (This is also a reason for moving to Okta and Adobe Enterprise).

No Deprecated Solutions

Adobe has a User Management API and Okta Workflows has a built-in connector for the User Management API however it only authenticates with JWT. This is being deprecated with Adobe and is insecure. Adobe now has an OAuth 2.0 option so we’ll have to build something custom.

Solution

Okta Workflows Connector Builder

Before You Begin in Okta

To obtain the credentials you need to access the Adobe User Management service, create a service account integration using the Adobe Developer Console.

Create a service account integration

  1. Go to https://developer.adobe.com/.
  2. Sign in with system administrator role permissions.
  3. Click Console.
  4. Click APIs and services and then click the APIs tab.
  5. Enter the User keyword into the Search field.
  6. Click Create Project in the User Management API service.
  7. Select the OAuth Server-to-Server option.
  8. Click the Save Configured API.
  9. Under Connected credentials, Click OAuth Server-to-Server.
  10. Leave this page open as you’ll need the data later.

Setup and Auth

Connector builder allows the admin to create their custom cards to be used in Okta workflows. I believe I’ve written about it previously for Duo Auth API.

To get to Connector Builder, open Okta Workflows then in the upper menu bar, to the right of the Question mark, click the four squares and choose Connector Builder. Using the plus button create a new project and name it something that works for you. I chose Adobe User Management and uploaded the Adobe logo to the project.

We then have to set up the Authentication section. While Okta has kinda provided an OAuth 2.0 connect type this won’t work for our needs. I’ll point to the Adobe User Management API documentation now where it shows that scopes are required when getting a token and the OAuth 2.0 option in Connector builder doesn’t account for that. Here is the sample curl command to get a token

curl -L -X POST 'https://ims-na1.adobelogin.com/ims/token/v2?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&scope=openid,AdobeID,user_management_sdk'

Here are the parameters needed to setup authorization.

Get a Token Flow

  1. Click the Flows tab.
  2. Click + New Flow.
  3. Click Add Event.
  4. Click Helper Flow.
  1. Click Add function.
  2. Click Text then Concatenate.
  1. Fill out the concatenate card with the data below. It uses the URL from the curl command above. You’ll want to drag the data over.
  1. Click the + to the right of the Concatenate card
  2. Choose HTTP > Raw Request
    • Drag the Output of Concatenate to URL in Raw Request
    • Use POST as the method
  1. Click the + again and choose Object > Get Multiple.
    • Drag the body output of the HTTP Raw Request to the object field
    • Click in the Click or drag to create and type in access_token
    • Click in the Click or drag to create and type in token_type
    • Click in the Click or drag to create and type in expires_in
  1. Drag the outputs of Get Multiple to Return
  1. Click Save
  2. Name the flow Get a token.

Here is the whole flow as an image.

httpHelper flow

  1. Click the Name of the connector card to get back to the flows tab
  2. Click + New Flow
  3. Click Add Event.
  4. Click Helper Flow.
  5. In the Helper flow card, Click Click or drag to create and type:
    • Relative URL
    • Method
    • Body
  1. Click Add function.
  2. Click Flow Control > Call Flow.
  3. Click Choose Flow > Get a token.
  4. Drag the Connection into connection
  5. Click in Click or drag to create and type access_token
  1. Click the + to the right of the Call Flow card.
  2. Click Text > Concatenate.
  3. Type “Bearer “ (there is a space at the end of Bearer) in text 1 and drag access_token from Call flow into text 2.
  4. Click the gear at the bottom of the card and click edit card.
  5. Click “output” and change the name to Authorization
  1. Click the + to the right of the Call Flow card.
  2. Click Object > Construct.
  3. Drag Authorization from the Concatenate card to the Click or drag here to create.
  4. Click Click or drag here to create and type (or paste) X-Api-Key. Press return.
  5. Drag Client ID from the Connection into X-Api-Key.
  6. Click Click or drag here to create and type (or paste) Content-type. Press return.
  7. Click in the space for Content-type and paste application/json.
  8. Click the gear at the bottom of the card and click edit card.
  9. Click output and change the name to headers.
  1. Click the + to the right of the Object Construct headers card.
  2. Click Text > Concatenate.
  3. Paste the following in text 1: https://usermanagement.adobe.io
  4. Drag Relative URL from the Helper Flow Inputs to text 2.
  5. Click the gear at the bottom of the card and click edit card.
  6. Click output and change the name to URL.
  1. Click the + to the right of the Text Concatenate URL card.
  2. Click HTTP > Raw Request.
  3. Drag URL (step 29) to the url.
  4. Drag Method from the Helper flow Inputs to method.
  5. Drag headers (step 24) to headers.
  6. Drag Body from Helper flow Inputs to body.
  1. Drag statusCode, headers, and body (outputs of the HTTP Raw card) to the Return Card.
  2. This is what the full httpHelper flow should look like.

Putting it all together

Now that we have all our helper flows we can use the Adobe API documentation to build out all our needs. Instead of walking through each card for every flow, I’ll leave an image of the full flow.

Add User to Group

Flow Name: Add User to Group
Description: Adds a user as a member of a group.
Event: Action
Inputs:
– Group Name (List of Text)
– User Email

AuthPing

Flow Name: AuthPing
Description: Test authentication connection
Event: authping
Inputs: None

Create Group

Flow Name: Create Group
Description: Creates a user group.
Event: Action
Inputs:
– Group Name
– Group Description

Create User

Flow Name: Create User
Description: Create a user in the Adobe admin console.
Event: Action
Inputs:
– User Email
– User First Name
– User Last Name
– Country

Delete Group

Flow Name: Delete Group
Description: Deletes an existing user group. No further steps are performed after deletion.
Event: Action
Inputs:
– Group Name

Delete User

Flow Name: Delete User
Description: Removes the user’s membership in the organization, and optionally from membership in a domain that is linked to the given organization through the trusted-domain relationship. This includes any product configs and user groups in the organization that they are a member of.
Event: Action
Inputs:
– User Email

Get All Groups

Flow Name: Get All Groups
Description: Retrieves a paged list of all user groups and product profiles in your organization along with information about them. You can make multiple paginated calls to retrieve the full list.
Event: Action
Inputs:
– Page (Text)

Get User

Flow Name: Get User
Description: Retrieves the details of a single user within a specified organization, identified by email address or username and domain.
Event: Action
Inputs:
– User Email

List All Users

Flow Name: List All Users
Description: Get all users in the Adobe Admin Console
Event: Action
Inputs:
– Page (Text)

Remove User from All Groups

Flow Name: Remove User from All Groups
Description: Removes the membership of users from groups. Removes from all product licenses, user groups, and admin groups.
Event: Action
Inputs:
– User Email

Remove User From Group

Flow Name: Remove User From Group
Description: Removes the membership of users from groups.
Event: Action
Inputs:
– User Email
– Group Name (List of text)