On Premises Provisioning Deployment Guide Skip to main content
https://support.okta.com/help/oktaarticledetailpage?childcateg=&id=ka0f0000000ay3ckaw&source=documentation&refurl=http%3a%2f%2fsupport.okta.com%2fhelp%2fdocumentation%2fknowledge_article%2f46749316-on-premises-provisioning-deployment-guide
How satisfied are you with the Okta Help Center?
Thank you for your feedback!
How satisfied are you with the Okta Help Center?
1
2
3
4
5
Very Dissatisfied
Very satisfied
Enter content less than 200 characters.
Average Rating:
On Premises Provisioning Deployment Guide
Published: Jan 12, 2015   -   Updated: May 24, 2017

A full-book pdf version of this guide is attached to this article.

Architecture
Prerequisites
How On-Premises Provisioning Works
High-Level Steps to Set Up On-Premises Provisioning
Example Setup of On-Premises Provisioning and MySQL
Okta Configuration
Sample SCIM Messages
Creating SCIM Connectors
     Resources
     SDK Structure
     Implementing the Interface
     Categories of Okta Functions
     Example Code Explained: createUser
     Testing the Code


The on-premises provisioning feature extends Okta’s provisioning capabilities to on-premises web applications and thick applications that run behind corporate firewalls. Since on-premises applications vary considerably, on-premises provisioning was designed to be modular and flexible. On-premises provisioning supports web-based apps and thick apps, apps with different API versions and languages, and apps with or without Simple Cloud Identity Management (SCIM) compatibility.

On-premises provisioning enables Okta to perform the following nine categories of functions with on-premises applications:

  • Provision new users from Okta to on-prem App
  • Update user profile in on-prem App
  • Import users existing in on-prem App into Okta
  • Push user's password from Okta to on-prem App
  • Import group from on-prem App into Okta
  • Push groups from Okta into on-prem App

Each category might encompass more granular functions. For example, the GROUP_PUSH category includes deleteGroup, updateGroup, createGroup, and getGroup. Details are provided below.

top

Architecture

The on-premises provisioning feature consists of the following components: Okta, the On-Prem Provisioning Agent, a SCIM endpoint or server, custom-coded connectors, and on-premises applications. As shown in the figure below, all components except Okta sit behind a firewall.

opp1a.png

Okta: An identity management service that runs in the cloud. Okta generates provisioning instructions (for example, provision, update, and import) and the provisioning agent generates SCIM requests.

On-Prem Provisioning Agent: A lightweight agent that runs on Linux (CentOS or RHEL) or Windows (x86/x64) server and sits behind a firewall. The On-Prem Provisioning Agent gets provisioning instructions from Okta and sends SCIM messages to the appropriate SCIM endpoint or connector.

SCIM Server: A SCIM-enabled application that receives SCIM requests. If an application natively supports SCIM, it’s a SCIM-enabled application, and the On-Prem Provisioning Agent communicates directly with the app. If an application does not support SCIM but offers provisioning APIs, a SCIM server can act as an intermediary. In this scenario, the SCIM server accepts SCIM requests and integrates with the on-prem application. A SCIM server can be a third-party product or a custom program running on a web-server.

SCIM Connector: A custom-coded SCIM connector (WAR file) that runs on a web server. A connector implements Okta’s SCIMService interface (part of Okta’s on-prem provisioning connector SDK) and defines the following methods: createGroup, createUser, deleteGroup, getGroup, getGroups, getImplementedUserManagementCapabilities, getUser, getUsers, updateGroup, and updateUser. Once written, these methods call application APIs. The connector therefore needs connectivity information for the app (for example, a URL and credentials). A SCIM connector is only required if you do not have a SCIM server and you want to use the SDK.

On-Premises App: An application (web app or thick app) that exposes APIs for the connector to call.

The on-premises provisioning feature is modular, flexible, and standards-based. Key design principles include the following:

  • Connections to any on-premises application
  • Faster implementation and deployment time
  • No firewall changes
  • Automatic clustering and failover via multiple On-Prem Provisioning Agents
  • Secure communications between Okta and the On-Prem Provisioning Agent
  • A single On-Prem Provisioning Agent can support multiple connectors
  • All On-Prem Provisioning Agents do not need to support all connectors
  • Modularity enables you to separate On-Prem Provisioning Agent connector code to allow independent updates

Note: Okta sends provisioning instructions to SCIM end points or connectors using SCIM 1.1. See Sample SCIM Messages for examples.

top

Prerequisites

The following components are required in order to install and set up on-premises provisioning:

  • CentOS version 6.4, Red Hat Enterprise Linux 6.x, or Windows installation file that installs the on-prem provisioning agent
  • Java version 1.6 or 1.7
  • For the connector: Apache Tomcat (version 6 supported)
    • Acts as SCIM endpoint
    • Not required if your app natively supports SCIM or you are building your own SCIM end point
    • Can be installed on the same server as the On-Prem Provisioning Agent but not required
    • Hosts custom connectors
  • Maven version 3.1.1
    • Used for building custom connectors (Java required)
    • Can be installed on any computer
    • Set M2, M2_HOME, JAVA_HOME, and PATH environment variables

top

How On-Premises Provisioning Works

This section describes how the on-premises provisioning data flow works with MySQL as a sample on-premises application. Using MySQL as a sample on-premises application. MySQL does not natively support SCIM requests. The figure below shows four main components: Okta, the On-Prem Provisioning Agent, a SCIM server, and an on-premises application (MySQL). 

opp2.png

  1. An Okta admin creates an app in Okta to represent the on-prem app.
  2. The admin attempts to provision a new MySQL user record (a row in a table) by assigning an Okta user to the MySQL app from Okta. Assume Okta has the required attributes to provision a user record to MySQL. Okta then creates a JSON-formatted SCIM representation of a user and a provisioning event (create new user).
  3. The On-Prem Provisioning Agent polls Okta and finds the provisioning event (create new user). The On-Prem Provisioning Agent then gets the JSON-formatted SCIM representation of the user and the URL of the connector WAR on Tomcat. This is configured as the “SCIM connector base URL” in Okta.

    The On-Prem Provisioning Agent then translates the provisioning event (create new user) to a standard SCIM request (i.e., an HTTP PUT, POST, or GET to the /Users endpoint). The SCIM protocol mandates that users be created using an HTTP POST to /Users. Therefore, the On-Prem Provisioning Agent posts the JSON-formatted SCIM representation of a user to URL of connector WAR/Users.
  4. When the connector receives a POST made to /Users with a JSON-formatted SCIM representation of the user, that indicates Okta is trying to create a user in MySQL. The connector parses the JSON-formatted SCIM representation of the user and then creates an Okta SCIMUser object that allows for programmatic retrieval of attributes. The connector then invokes the createUser method (assume this is defined via custom code) and passes it the SCIMUser object.

    Note: The combination of the SCIM endpoint (i.e., /Users or /Groups) and HTTP operation (i.e., GET, POST, PUT, PATCH, and DELETE) determines which method is invoked in the connector. For example, if an HTTP POST is made to URL of connector WAR/Users with a SCIM payload representing a user, the connector calls createUser. Similarly, if an HTTP DELETE is made to URL of connector WAR/Groups/{id}, the connector invokes the deleteGroup method. Refer to the SDK Java docs or the Creating SCIM Connectors section for details.
  5. The createUser method performs several tasks. First, it retrieves the attributes needed from the SCIMUser object to create a user in MySQL. Next, it constructs a corresponding SQL insert command with the attributes. Finally, createUser connects to MySQL and executes the SQL command via JDBC. Assume the connector contains MySQL connection information (MySQL URL, MySQL username, and password).

top

High-Level Steps to Set Up On-Premises Provisioning Using a SCIM Connector

The high-level steps below are required to deploy the on-premises provisioning connector. For more detailed step-by-step instructions, refer to Creating SCIM Connectors.

  • Set up the On-Prem Provisioning Agent server
    • Install CentOS or RHEL.

    • Download and install the On-Prem Provisioning Agent (RPM or Windows).

    • Run the configure_agent.sh script to register the agent with Okta. You can also use this script to refresh the Okta API token used by the agent. Make sure to stop the agent before running the script.

Note: By default, the Okta Provisioning Agent communicates with SCIM Server over https, which is the recommended protocol. If you wish to use http communication:

1.  From the configure_agent.sh file, search for Configuring Okta Provisioning agent.

2.  Add the command line argument -allowHttp true \ to the list of commands.

Be advised that https is the recommended protocol.

  • Configure the On-Prem Provisioning Agent to run as a service.
  • Setup your development environment
    • Install Java JDK & Maven.
    • Set required environmental variables (JAVA_HOME, M2, M2_HOME, and PATH).
    • Download Okta SDK and install to local Maven repository.
  • Setup Tomcat (SCIM server)
    • Your Tomcat SCIM server requires Java JRE.
    • Configure Tomcat to run as a service.
  • Write a custom connector in Java.
    • Define the 10 functions in the Okta SCIMService interface (part of SDK).
    • Java docs are included with the SDK in the doc folder.
  • Build the package via Maven and create a .WAR file.
  • Deploy custom connector .WAR file on a Tomcat Apache Server.
    • Tomcat can now receive SCIM requests at the connector.
    • Connector sends SCIM requests to provisioning functions that you define.
  • Configure an application in Okta
    • Enable on-premises provisioning configuration (General tab)
    • Select an On-Prem Provisioning Agent (Provisioning tab)
    • Configure URL to the custom connector WAR file.
      • URL is on the intranet and not public facing; Okta is unaware of it.
      • The provisioning agent must be able to access it; the URL is relative to the provisioning agent.
    • Select unique user field name.
      • Use this to construct a search filter to determine whether a user already exists in app.
      • This is used by checkUserExists(), which requires userIdFieldName and userIdFieldValue.
        • Precursor to createUser, ActivateUser, and ReactivateUser.
        • Valid values are id, phoneNumber, name.familyName, email, userName, and name.givenName.
      • Select authorization type.
        • Choose authorization type if you’ve configured Tomcat to require it.
    • Provision accounts from Okta to on-premises applications.

Note: If you create your own SCIM end point then you only need to perform step 1. You can provide the URI of the SCIM end point when your configure the on-prem app in Okta.

top

Example Setup of On-Premises Provisioning and MySQL

This section provides instructions for configuring an application in Okta to use on-premises provisioning with MySQL. Before you begin, make sure you complete the following tasks:

  • Install and connect your On-Prem Provisioning Agent to your Okta org.
  • Install MySQL and create a sample database and tables.
  • Download the provisioning connector SDK.
  • Install Maven for building package (WAR file).
  • Install Apache Tomcat Server.
  • Build and deploy WAR file for example-mysql-server on Tomcat.
  • Configure your MySQL connection settings in your WAR file.

The figure below shows the architecture of the example setup.

opp3.png

top

Okta Configuration

  1. Sign into your Okta tenant.
  2. Verify that your On-Prem Provisioning Agents are connected to Okta by selecting Dashboard > Agents and verifying that the circle is green.

         Replace_OPP.jpg

  1. Create a SWA application. If you are configuring the example-mysql-server, you must name the app onprem_mysql_app.
  2. Enable on-premises provisioning configuration.
    1. From your Okta Administrator Dashboard, select Applications and select your app.
    2. Click the General tab.
    3. Click the Edit button under Settings.
    4. Select the checkbox for Enable on-premises provisioning configuration.
    5. Click the Save button.
         OPP_newSWA.jpg
  3. Configure and test the connector by performing the following steps:
    1. From your app, select the Provisioning tab.
    2. Click the Edit button under Connector Configuration.
    3. SCIM connector base URL > enter URL of connector (for example, http://localhost:8080/scim-mysql-connector-example-01.01.00-SNAPSHOT). This is the location of the WAR file on Apache Tomcat. In this example, Tomcat and the Okta Provisioning Agent are on the same machine.
    4. Select None for Authorization type. By default, Apache Tomcat does not require authorization.
    5. Enter userName in the unique user field name.
    6. Select your Okta Provisioning Agent in the Connect to these agents field.
    7. Click Test Connector Configuration. Five of nine functions should be detected for the example-mysql-server connector.
           opp6.png
  4. Enable the desired provisioning settings by performing the following steps:
    1. From your app, select the Provisioning tab
    2. Select the checkbox Enable provisioning for onprem_mysql_app.
    3. Select Provision new onprem_mysql_app accounts from Okta.
    4. Select Push Okta user profile updates to onprem_mysql_app.
  5. You should now be able to import accounts from MySQL to Okta. Click the Import tab and then click Import Now as shown in the figure below.

        opp7.png

  1. You should also be able to provision from Okta to MySQL. Assign a user to an app provisions an account to the app.

       opp8.png

An account is created in MySQL if the account does not already exist. Okta first makes a call to the SCIM server to check if the user exists in MySQL. Okta sends a GET request to the SCIM server with a SCIM filter (described in the SCIM specification). The filter depends on the configured "Unique user field name." If the field name you chose is not email (which is multivalued), the filter is an equality filter. For example,

filter=userName%20eq%20%22myemail%40domain.com.

filter=id%20eq%20%22myemail%40domain.com

If the field is email, then the filter is an OR filter (combining two equality filters corresponding to the two email values possible). For example, 

filter=email+eq+%22bjensen%40example.com%22+OR+email+eq+%22my-secondary-email%40domain.com

If you are using the on-premises provisioning SDK, the filter string is abstracted and a call is made to the connector method, getUsers(PaginationProperties paginationProperties, SCIMFilter scimFilter). The SCIMFilter object is a parsed Java object representing the filter string described above.

If the SCIM server returns an output containing users that correspond to the GET request described above, then Okta does not create the user in MySQL. If the SCIM server returns an output without any users corresponding to the GET request, then Okta makes a POST request to the connector with a JSON string that represents the user to be created. In the case of a connector using the on-premises provisioning SDK, a call is made to createUser(SCIMUser scimUser), where the scimUser object wraps the JSON string.

top

Sample SCIM Messages

The following is an example JSON string :

{
"schemas": ["urn:scim:schemas:core:1.0", "urn:okta:onprem_app:1.0:user:custom"],
"userName": "myemail@domain.com",
"emails": [
{
"primary": true,
"value": "myemail@domain.com",
"type": "primary"
},
{
"primary": false,
"value": "mypersonalemail@domain.com",
"type": "secondary"
}
],
"phoneNumbers": [
{
"value": "123-444-5555",
"type": "mobile"
}
],
"name": {
"familyName": "LastName",
"givenName": "FirstName"
},
"active": true,
"password": "verySecure",
"urn:okta:onprem_app:1.0:user:custom": {
"isAdmin": false,
"isOkta": false,
"departmentName": "Testing User"
}
}

The following is an example of a SCIM JSON string for a group :

{
"schemas": ["urn:scim:schemas:core:1.0", "urn:okta:custom:group:1.0"],
"displayName": "AppGroup-04",
"id": "AppGroup-02",
"members" : [{"value": "101", "display": "okta"},{"value": "102", "display": "admin"}],
"urn:okta:custom:group:1.0":{
"description":"This is the second group"
}
}

top

Creating SCIM Connectors

This section describes how to create custom SCIM connectors.

top

Resources

Please refer to the links below, in particular the second one that describes the build process. The build process outlines recommended changes to the configuration files.

Creating SCIM Connectors

Building SCIM Connectors

top

SDK Structure

To begin developing a custom connector, first download the Okta Provisioning Connector SDK from the Okta admin interface (Settings > Downloads). Next, unzip the file and familiarize yourself with the resources in the SDK directory. Finally, run the lib/install.sh script to install the SDK to the local Maven repository. Now, you can code the connector.

 opp9.png
  • doc – Contains SDK JAVA docs; view allclasses-frame.html; refer to SCIMService class
  • example-mysql-server – Contains sample code for a MySQL connector
  • example-server – Contains sample code for in-memory identity store
  • lib – Contains Okta SDK packages (install in Maven)
  • tester – Contains tool for calling/testing connector methods

top

Implementing the Interface

Read the Java docs in the SDK and familiarize yourself with the SCIMService interface. As described above, Okta abstracts the SCIM protocol and provides one interface that contains the following methods to be implemented:

  • createGroup
  • createuser
  • deleteGroup
  • getGroup
  • getGroups
  • getImplementedUserManagementCapabilities
  • getUser
  • getUsers
  • updateGroup
  • updateUser

Learn how the connector receives SCIM requests and invokes the above functions in the connector. SCIM requests hit various endpoints (i.e., /Users and /Groups) at the URL of connector WAR through a variety of HTTP methods (e.g., POST, GET, PUT, DELETE). The table below describes the combinations of HTTP methods and specific SCIM endpoints that map to the 10 functions. For example, if a POST is made to URL of connector WAR/Users, the connector calls createUser(SCIMUser user). Customers define createUser(SCIMUser user) to call an app’s API and create a user.

Connector Method CalledDescriptionMethod gets called when
createUser(SCIMUser user)  Creates a user POST is made to /Users with a SCIM payload representing a user to be created
updateUser(String id, SCIMUser user)  Updates a user PUT is made to /Users/{id} with the SCIM payload representing a user to be updated
getUsers(PaginationProperties pageProperties,                             SCIMFilter filter)  Gets all usersGET is made to /Users
getUser(String id)Gets a particular userGET is made to /Users/{id}
createGroup(SCIMGroup group)Greates a groupPOST is made to /Groups with a SCIM payload representing a group to be created
updateGroup(String id, SCIMGroup group)Updates a groupPUT is made to /Groups/{id} with the SCIM payload representing a group to be updated
getGroups(PaginationProperties pageProperties)  Gets all groupsGET is made to /Groups
getGroup(String id)  Gets a particular groupGET is made to /Groups/{id}
deleteGroup(String id)  Deletes a particular groupDELETE is made to /Groups/{id}
getImplementedUserManagementCapabilities()  Gets implemented Okta Provisioning capabilities GET is made to /ServiceProviderConfigs

top

Categories of Okta Functions

After you code the methods, determine how they will be grouped under the nine categories in Okta (see the table below). Okta uses the categories to render the options available in the GUI. For example, the updateUser method in SCIMService handles several capabilities (PUSH_PASSWORD_UPDATES, PUSH_PENDING_USERS, and PUSH_PROFILE_UPDATES). However, an app might only support PUSH_PROFILE_UPDATES. Consequently, Okta should only display a checkbox to toggle profile push updates. To accomplish this, make sure you correctly define the getImplementedUserManagementCapabilities() method. The third column in the table lists the names of the corresponding methods in the tester. The tester is a command-line tool that Okta provides in the SDK. The tester allows developers to send SCIM requests to the connector without using the On-Prem Provisioning Agent. Use it to test communications between the connector and the application.


Management Functions in the UserManagementCapabilities enum
Methods in SCIMServiceArgument to methodName in tester
GROUP_PUSHdeleteGroupdeleteGroup
updateGroupupdateGroup
createGroupcreateGroup
getGroupgetGroupById
IMPORT_NEW_USERS getUsersdownloadUsers
getGroupsdownloadGroups
IMPORT_PROFILE_UPDATESgetUserimportUserProfile
PUSH_NEW_USERS createUsercreateNewUser
getUserscheckUserExists
PUSH_PASSWORD_UPDATESupdateUserpushPasswordUpdate
PUSH_PENDING_USERScreateUsercreatePendingUser
updateUseractivateUser
getUserscheckUserExists
PUSH_PROFILE_UPDATESupdateUserpushProfileUpdate
PUSH_USER_DEACTIVATIONupdateUserdeactivateUser
REACTIVATE_USERSupdateUserreactivateUser

top

Example Code Explained: createUser

This section explains the example MySQL Connector code that’s included in the SDK. The code describes how to retrieve custom attributes using schemas. Refer to the MySqlSCIMServiceImpl.java file included with the SDK.

First, note the imported classes. Your code should import all com.okta* classes. The last two classes, org.apache.log4j.Logger and org.codehaus.jackson.JsonNode, are optional but recommended for logging and handling attributes, respectively.

import com.okta.scim.server.capabilities.UserManagementCapabilities;
import com.okta.scim.server.exception.DuplicateGroupException;
import com.okta.scim.server.exception.EntityNotFoundException;
import com.okta.scim.server.exception.OnPremUserManagementException;
import com.okta.scim.server.service.SCIMOktaConstants;
import com.okta.scim.server.service.SCIMService;
import com.okta.scim.util.exception.InvalidDataTypeException;
import com.okta.scim.util.model.Email;
import com.okta.scim.util.model.Membership;
import com.okta.scim.util.model.Name;
import com.okta.scim.util.model.PaginationProperties;
import com.okta.scim.util.model.SCIMFilter;
import com.okta.scim.util.model.SCIMFilterType;
import com.okta.scim.util.model.SCIMGroup;
import com.okta.scim.util.model.SCIMGroupQueryResponse;
import com.okta.scim.util.model.SCIMUser;
import com.okta.scim.util.model.SCIMUserQueryResponse;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonNode;

Note that the custom connector implements SCIMService. All methods must be defined. If your on-premises app does not support a certain call, create an empty method.

public class MySqlSCIMServiceImpl implements SCIMService {

Next, note two strings: APP_NAME and USER_CUSTOM_URN that must be properly set. The first identifies the application name in Okta with which the connector is associated. The second identifies a custom namespace/schema that can define custom attributes required by an application.

opp10.png

Next, view the sample code in the createUser method. The code retrieves any custom properties (attributes) by calling getCustomPropertiesMap() on the user. The returned value is a map that is keyed by schema name and mapped to a JsonNode. For example, if onprem_mysql_app had defined two schemas (sets of custom attributes), the map would contain two keys and two JsonNodes. To retrieve a custom attribute, first a specific JsonNode from the map and then get the attribute from the JsonNode.  For example, to retrieve an attribute named customField1 from a specific schema (i.e., the one defined in USER_CUSTOM_URN), use the following code:

String customField1 = user.getCustomPropertiesMap().get(USER_CUSTOM_URN).get("customField1").asText();

In the mysql-example-server connector, custom schemas are not used. Instead, three custom attributes needed by MySQL (birthDate, gender, and hireDate) are hardcoded.

opp11.png

After retrieving custom attributes or properties, the code retrieves the base attributes (first name and last name) from the user. A SQL statement is constructed with the base attributes and the hardcoded attributes. Finally, the SQL statement gets executed.

opp12.png

top

Testing the Code

The Okta On-Premises Provisioning SDK contains a tester command line utility. The tester enables developers to test their connector code without using the On-Prem Provisioning Agent. Okta recommends verifying code with the tester before configuring the connector with the Okta UI and On-Prem Provisioning Agent. The tester contains JSON-formatted SCIM representations of users for various calls. To test the createUser method in the example-mysql-server connector, enter the following command:

$ java -jar scim-sdk-tests.jar -url http://localhost:8080/scim-mysql-connector-example-01.01.00-SNAPSHOT -method createNewUser -file mysql-data/createNewUser.json

See the figure below for the command and output.

opp13.png

The tester directory contains directories named data and mysql-data. Both directories have .json objects that contain dummy data for testing purpose. In the figure above, the tester passed the mysql-data/createNewUser.json object to the connector. The connector extracted information from the JSON object and called the createUser method in the connector.

For additional information, see the README.txt contained in the tester directory.

Post a Comment