måndag 21 augusti 2017

SCIM no longer a SCAM

Although the SCIM (System for Cross-domain Identity Management) standard has been around since 2011 it has seen little adoption among software vendors. Driving forces behind it can be considered Google, Salesforce.com, Sailpoint and Ping Identity and the idea behind the standard is to simplify exchange of user identity information between IT systems using identities - Identity Silos if you will.


The SCIM standard can be viewed as a successor to SPML (Service Provisioning Markup Language) developed by OASIS with the similar goal but based on an XML framework. With the emerging RESTful world to counter the heavy-weight and cumbersome XML based standards - SCIM was born. SCIM offers a light-weight schema that is JSON and REST-based with a concrete data model but as for any standard - it doesn't become a standard unless it is widely adopted, and here is where SCIM currently is struggling.


The current release of the SCIM standard is SCIM 2.0 and released as IETF RFC 7643 and IETF RFC 7644 with a complementing use-case document as IETF RFC 7642, but most implementations are still SCIM 1.1.


So what is it that SCIM typically can do? Mainly two things; CRUD operation on users and groups. For SCIM to work, the application needs to provide a SCIM compliant service and the integration needs to offer a SCIM compliant connector.


As of "ForgeRock Identity Management 5.5" (Referred to as IDM in this article), a SCIM 1.1 compliant connector will now be part of the product allowing IDM to interact with SCIM complaint services such as Google and WSO2 Identity Server to create, update, delete users and groups. However, since the connector is based on the OpenICF 1.4 framework the connector is backward compatible with previous versions of ForgeRock Identity Management implementing the OpenICF 1.4 framework.


This article will offer a step by step guide how to set up a SCIM compliant test environment based on WSO2 Identity Server, how to configure the SCIM connector in IDM making it ready to provision a set of users to WSO2 Identity Server.


Installation of WSO2 Identity Server is easy and the archive downloaded from WSO2s website with the binary bits is self-contained with everything required to install and run.


Make sure the $JAVA_HOME variable is set appropriately prior to invoking the wso2server.sh script. Possibly some manipulations are required in the startup script to reflect your particular environment.


The following steps are done to install WSO2 Identity Server:


1. Download and extract the wso2is-5.2.0.zip file
2. Run the wso2server.sh on *NIX or wso2server.bat file on Windows,  in the /bin directory
3. Once the server starts, point your Web browser to https://localhost:9443/carbon/
4. User dashboard is available at https://localhost:9443/dashboard


WSO2 Identity Server integrates WSO2s Charon, which is a fully Open Source implementation of the SCIM protocol and provides the necessary serverside components to facilitate a SCIM server exposing SCIM endpoints which expose Users and Groups resources in a RESTful way.


The next step once WSO2 Identity Server is up and running is to create a new service provider followed by configuring SCIM and OAuth.


Login to the admin dashboard (https://localhost:9443/carbon/) using the admin:admin credentials, the locate the Add New Service Provider.
For the inbound provisioning, define PRIMARY as the user/group store for SCIM and be ready to configure the OAuth part.
Configure OAuth and make sure to save the client secret and key  (SCIM connector uses client credential grant type).


Once the service provider is configured accordingly, the SCIM service is ready to be tested with IDM and the SCIM connector.


Unless running ForgeRock Identity Management 5.5 the actual connector needs to be deployed in the IDM install directory. Copy the connector jar file to $OPENIDM/connectors. The connector file is available via Backstage for customers with an active subscription and is not posted here for licensing purposes.

The connector also requires a configuration file that needs to be deployed made available to IDM. Copy the provisioner.openicf-scim.json to $OPENIDM/conf.


Provisioner.openicf-scim.json


{
   "name" : "scim"
   "enabled" : true,
   "connectorRef" : {
       "bundleName" : "org.forgerock.openicf.connectors.scim-connector",
       "connectorName" : "org.forgerock.openicf.connectors.scim.ScimConnector",
       "connectorHostRef" : "#LOCAL",
       "bundleVersion" : "1.4.0.0-SNAPSHOT"
   },
   "poolConfigOption" : {
       "maxObjects" : 10,
       "maxIdle" : 10,
       "maxWait" : 150000,
       "minEvictableIdleTimeMillis" : 120000,
       "minIdle" : 1
   },
   "resultsHandlerConfig" : {
       "enableNormalizingResultsHandler" : true,
       "enableFilteredResultsHandler" : false,
       "enableCaseInsensitiveFilter" : false,
       "enableAttributesToGetSearchResultsHandler" : false
   },
   "operationTimeout" : {
       "CREATE" : -1,
       "UPDATE" : -1,
       "DELETE" : -1,
       "TEST" : -1,
       "SCRIPT_ON_CONNECTOR" : -1,
       "SCRIPT_ON_RESOURCE" : -1,
       "GET" : -1,
       "RESOLVEUSERNAME" : -1,
       "AUTHENTICATE" : -1,
       "SEARCH" : -1,
       "VALIDATE" : -1,
       "SYNC" : -1,
       "SCHEMA" : -1
   },
   "configurationProperties" : {
       "SCIMEndpoint" : "https://localhost:9443/wso2/scim",
       "SCIMVersion" : 1,
       "authenticationMethod" : "BASIC",
       "user" : "admin",
       "password" : "admin",
       "tokenEndpoint" : "https://localhost:9443/oauth2/token"
       "clientId" : "FsvGkUww7vHYYgRh_Hd071iQQroa",
       "clientSecret" : null,
       "acceptSelfSignedCertificates" : true,
       "disableHostNameVerifier" : true,
       "maximumConnections" : 10,
       "httpProxyHost" : null,
       "httpProxyPort" : null
   },
   "objectTypes" : {
       "group" : {
           "$schema" : "http://json-schema.org/draft-03/schema",
           "id" : "__GROUP__",
           "type" : "object",
           "nativeType" : "__GROUP__",
           "properties" : {
               "displayName" : {
                   "type" : "string",
                   "required" : true,
                   "nativeName" : "displayName",
                   "nativeType" : "string"
               },
               "meta" : {
                   "type" : "object",
                   "nativeName" : "meta",
                   "nativeType" : "object",
                   "flags" : [
                       "NOT_CREATABLE",
                       "NOT_UPDATEABLE"
                   ]
               },
               "members" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "members",
                   "nativeType" : "object"
               },
               "__NAME__" : {
                   "type" : "string",
                   "required" : true,
                   "nativeName" : "__NAME__",
                   "nativeType" : "string"
               },
               "externalId" : {
                   "type" : "string",
                   "nativeName" : "externalId",
                   "nativeType" : "string"
               }
           }
       },
       "user" : {
           "$schema" : "http://json-schema.org/draft-03/schema",
           "id" : "__ACCOUNT__",
           "type" : "object",
           "nativeType" : "__ACCOUNT__",
           "properties" : {
               "phoneNumbers" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "phoneNumbers",
                   "nativeType" : "object"
               },
               "emails" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "emails",
                   "nativeType" : "object"
               },
               "__NAME__" : {
                   "type" : "string",
                   "required" : true,
                   "nativeName" : "__NAME__",
                   "nativeType" : "string"
               },
               "active" : {
                   "type" : "boolean",
                   "nativeName" : "active",
                   "nativeType" : "boolean"
               },
               "groups" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "groups",
                   "nativeType" : "object",
                   "flags" : [
                       "NOT_CREATABLE",
                       "NOT_UPDATEABLE"
                   ]
               },
               "costCenter" : {
                   "type" : "string",
                   "nativeName" : "costCenter",
                   "nativeType" : "string"
               },
               "division" : {
                   "type" : "string",
                   "nativeName" : "division",
                   "nativeType" : "string"
               },
               "employeeNumber" : {
                   "type" : "string",
                   "nativeName" : "employeeNumber",
                   "nativeType" : "string"
               },
               "organization" : {
                   "type" : "string",
                   "nativeName" : "organization",
                   "nativeType" : "string"
               },
               "profileUrl" : {
                   "type" : "string",
                   "nativeName" : "profileUrl",
                   "nativeType" : "string"
               },
               "userType" : {
                   "type" : "string",
                   "nativeName" : "userType",
                   "nativeType" : "string"
               },
               "x509Certificates" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "x509Certificates",
                   "nativeType" : "object"
               },
               "manager" : {
                   "type" : "object",
                   "nativeName" : "manager",
                   "nativeType" : "object"
               },
               "userName" : {
                   "type" : "string",
                   "required" : true,
                   "nativeName" : "userName",
                   "nativeType" : "string"
               },
               "timezone" : {
                   "type" : "string",
                   "nativeName" : "timezone",
                   "nativeType" : "string"
               },
               "photos" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "photos",
                   "nativeType" : "object"
               },
               "displayName" : {
                   "type" : "string",
                   "nativeName" : "displayName",
                   "nativeType" : "string"
               },
               "password" : {
                   "type" : "string",
                   "nativeName" : "__PASSWORD__",
                   "nativeType" : "JAVA_TYPE_GUARDEDSTRING",
                   "flags" : [
                       "NOT_READABLE",
                       "NOT_RETURNED_BY_DEFAULT"
                   ]
               },
               "meta" : {
                   "type" : "object",
                   "nativeName" : "meta",
                   "nativeType" : "object",
                   "flags" : [
                       "NOT_CREATABLE",
                       "NOT_UPDATEABLE"
                   ]
               },
               "entitlements" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "entitlements",
                   "nativeType" : "object"
               },
               "department" : {
                   "type" : "string",
                   "nativeName" : "department",
                   "nativeType" : "string"
               },
               "ims" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "ims",
                   "nativeType" : "object"
               },
               "name" : {
                   "type" : "object",
                   "nativeName" : "name",
                   "nativeType" : "object"
               },
               "nickName" : {
                   "type" : "string",
                   "nativeName" : "nickName",
                   "nativeType" : "string"
               },
               "locale" : {
                   "type" : "string",
                   "nativeName" : "locale",
                   "nativeType" : "string"
               },
               "roles" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "roles",
                   "nativeType" : "object"
               },
               "preferredLanguage" : {
                   "type" : "string",
                   "nativeName" : "preferredLanguage",
                   "nativeType" : "string"
               },
               "addresses" : {
                   "type" : "array",
                   "items" : {
                       "type" : "object",
                       "nativeType" : "object"
                   },
                   "nativeName" : "addresses",
                   "nativeType" : "object"
               },
               "title" : {
                   "type" : "string",
                   "nativeName" : "title",
                   "nativeType" : "string"
               },
               "externalId" : {
                   "type" : "string",
                   "nativeName" : "externalId",
                   "nativeType" : "string"
               }
           }
       }
   },
   "operationOptions" : {
       "CREATE" : {
           "objectFeatures" : {
               "__GROUP__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : { }
                   }
               },
               "__ACCOUNT__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : { }
                   }
               }
           }
       },
       "UPDATE" : {
           "objectFeatures" : {
               "__GROUP__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : { }
                   }
               },
               "__ACCOUNT__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : { }
                   }
               }
           }
       },
       "DELETE" : {
           "objectFeatures" : {
               "__GROUP__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : { }
                   }
               },
               "__ACCOUNT__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : { }
                   }
               }
           }
       },
       "TEST" : {
           "objectFeatures" : { }
       },
       "SCRIPT_ON_CONNECTOR" : {
           "objectFeatures" : { }
       },
       "SCRIPT_ON_RESOURCE" : {
           "objectFeatures" : { }
       },
       "GET" : {
           "objectFeatures" : {
               "__GROUP__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : {
                           "SORT_KEYS" : {
                               "type" : "string",
                               "nativeType" : null
                           },
                           "PAGED_RESULTS_OFFSET" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "ATTRS_TO_GET" : {
                               "type" : "array",
                               "items" : {
                                   "type" : "string",
                                   "nativeType" : "string"
                               },
                               "nativeType" : "string"
                           },
                           "PAGE_SIZE" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "PAGED_RESULTS_COOKIE" : {
                               "type" : "string",
                               "nativeType" : "string"
                           }
                       }
                   }
               },
               "__ACCOUNT__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : {
                           "SORT_KEYS" : {
                               "type" : "string",
                               "nativeType" : null
                           },
                           "PAGED_RESULTS_OFFSET" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "ATTRS_TO_GET" : {
                               "type" : "array",
                               "items" : {
                                   "type" : "string",
                                   "nativeType" : "string"
                               },
                               "nativeType" : "string"
                           },
                           "PAGE_SIZE" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "PAGED_RESULTS_COOKIE" : {
                               "type" : "string",
                               "nativeType" : "string"
                           }
                       }
                   }
               }
           }
       },
       "RESOLVEUSERNAME" : {
           "objectFeatures" : { }
       },
       "AUTHENTICATE" : {
           "objectFeatures" : { }
       },
       "SEARCH" : {
           "objectFeatures" : {
               "__GROUP__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : {
                           "SORT_KEYS" : {
                               "type" : "string",
                               "nativeType" : null
                           },
                           "PAGED_RESULTS_OFFSET" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "ATTRS_TO_GET" : {
                               "type" : "array",
                               "items" : {
                                   "type" : "string",
                                   "nativeType" : "string"
                               },
                               "nativeType" : "string"
                           },
                           "PAGE_SIZE" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "PAGED_RESULTS_COOKIE" : {
                               "type" : "string",
                               "nativeType" : "string"
                           }
                       }
                   }
               },
               "__ACCOUNT__" : {
                   "operationOptionInfo" : {
                       "$schema" : "http://json-schema.org/draft-03/schema",
                       "id" : "FIX_ME",
                       "type" : "object",
                       "properties" : {
                           "SORT_KEYS" : {
                               "type" : "string",
                               "nativeType" : null
                           },
                           "PAGED_RESULTS_OFFSET" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "ATTRS_TO_GET" : {
                               "type" : "array",
                               "items" : {
                                   "type" : "string",
                                   "nativeType" : "string"
                               },
                               "nativeType" : "string"
                           },
                           "PAGE_SIZE" : {
                               "type" : "integer",
                               "nativeType" : "integer"
                           },
                           "PAGED_RESULTS_COOKIE" : {
                               "type" : "string",
                               "nativeType" : "string"
                           }
                       }
                   }
               }
           }
       },
       "VALIDATE" : {
           "objectFeatures" : { }
       },
       "SYNC" : {
           "objectFeatures" : { }
       },
       "SCHEMA" : {
           "objectFeatures" : { }
       }
   }
}


{
   "mappings" : [
       {
           "target" : "system/scim/user",
           "source" : "managed/user",
           "name" : "managedUser_systemScimUser",
           "onCreate" : {
               "type" : "text/javascript",
               "file" : "script/MU2SCIM-sync.js"
           },
           "onUpdate" : {
               "type" : "text/javascript",
               "file" : "script/MU2SCIM-sync.js"
           },
           "properties" : [
               {
                   "target" : "userName",
                   "source" : "userName"
               },
               {
                   "target" : "name/givenName",
                   "source" : "givenName"
               },
               {
                   "target" : "name/familyName",
                   "source" : "sn"
               },
               {
                   "target" : "displayName",
                   "source" : "description"
               },
               {
                   "target" : "active",
                   "default" : true
               },
               {
                   "target" : "password",
                   "source" : "password",
                   "transform" : {
                       "type" : "text/javascript",
                       "globals" : { },
                       "source" : "openidm.decrypt(source);"
                   },
                   "condition" : {
                       "type" : "text/javascript",
                       "globals" : { },
                       "source" : "object.password != null"
                   }
               }
           ],
           "policies" : [
               {
                   "situation" : "CONFIRMED",
                   "action" : "UPDATE"
               },
               {
                   "situation" : "FOUND",
                   "action" : "UPDATE"
               },
               {
                   "situation" : "ABSENT",
                   "action" : "CREATE"
               }
           ],
           "correlationQuery" : {
               "type" : "text/javascript",
               "source" : "var qry = { '_queryFilter': 'userName eq \"' + source.userName + '\"' }; qry;"
           }
       },
       {
           "source" : "system/scim/user",
           "target" : "managed/user",
           "name" : "systemScimUser_managedUser",
           "sourceQueryFullEntry" : false,
           "onCreate" : {
               "type" : "text/javascript",
               "file" : "script/SCIM2MU-sync.js"
           },
           "onUpdate" : {
               "type" : "text/javascript",
               "file" : "script/SCIM2MU-sync.js"
           },
           "properties" : [
               {
                   "target" : "userName",
                   "source" : "userName"
               },
               {
                   "target" : "givenName",
                   "source" : "name/givenName"
               },
               {
                   "target" : "sn",
                   "source" : "name/familyName"
               },
               {
                   "target" : "description",
                   "source" : "displayName"
               }
           ],
           "policies" : [
               {
                   "situation" : "CONFIRMED",
                   "action" : "UPDATE"
               },
               {
                   "situation" : "FOUND",
                   "action" : "UPDATE"
               },
               {
                   "situation" : "ABSENT",
                   "action" : "CREATE"
               }
           ],
           "correlationQuery" : {
               "type" : "text/javascript",
               "source" : "var qry = {'_queryId' : 'for-userName', 'uid' : source.userName}; qry;"
           }
       }
   ]
}


You also need the following onCreate/onUpdate scripts to deal with the complex SCIM objects:


SCIM2MU-sync.js


/*
* Copyright 2017-2017 ForgeRock AS. All Rights Reserved
*
* Use of this code requires a commercial software license with ForgeRock AS.
* or with one of its affiliates. All use shall be exclusively subject
* to such license between the licensee and ForgeRock AS.
*/


// Addresses
// a Managed user contains by default the following "Address" attributes:
// postalAddress
// address2
// city
// postalCode
// country
// stateProvince
if (source.addresses != null) {
print("Found addresses")
var address = source.addresses[0]
target.city = address.locality
target.country = address.country
target.stateProvince = address.region
target.postalCode = address.postalCode
target.postalAddress = address.streetAddress


}


// Email
if (source.emails != null) {
print("Found mail")
var email = source.emails[0]
target.mail = email.value
}


// Telephone
if (source.phoneNumbers != null) {
print("Found phones")
var phone = source.phoneNumbers[0]
target.telephoneNumber = phone.value
}


MU2SCIM-sync.js


/*
* Copyright 2017-2017 ForgeRock AS. All Rights Reserved
*
* Use of this code requires a commercial software license with ForgeRock AS.
* or with one of its affiliates. All use shall be exclusively subject
* to such license between the licensee and ForgeRock AS.
*/


target.__NAME__ = source.userName


// Addresses
// a Managed user contains by default the following "Address" attributes:
// postalAddress
// address2
// city
// postalCode
// country
// stateProvince


var address = {
locality: source.city,
country: source.country,
region: source.stateProvince,
postalCode: source.postalCode,
streetAddress: source.postalAddress,
type: "work"
}


target.addresses = [address]


// Email
if (source.mail != null) {
var email = {
value: source.mail,
type: "work"
}
target.emails = [email]
}


// Telephone
if (source.telephoneNumber != null) {
var phone = {
value: source.telephoneNumber,
type: "work"
}
target.phoneNumbers = [phone]
}


Conclusion


ForgeRock Identity Management is now ready to take advantage of the new SCIM connector and to provision users to a SCIM compliant service. In our case we are utilizing WSO2 Identity Server that has a SCIM compliant interface to accept inbound provisioning requests.


SCIM has long been the attempt to clean up the mess that was called SPML using a RESTful approach but has seen little adoption in the industry aside from a few advocate names. ForgeRock now recognizes the importance of this standard and provides an easy and efficient way to integrate with SCIM compliant services.

söndag 28 maj 2017

Social IdP in OpenIDM 5

The release of OpenIDM 5.0 allows implementors to quickly and efficiently set up integration with three of the major social IdPs; Facebook, Google and LinkedIn. Leveraging a Social IdP for self-service registration and authentication significantly lowers the barrier to enter and gain access to valuable applications and services yet collects valuable and often required information for companies without the end user to manually having to enter the same identity data over and over again.

This article will guide you through the technical setup of setting up and utilize LinkedIn as social IdP for authentication and self-service registration. I will assume that OpenIDM is newly installed.

If you are trying to leverage any of the other supported Social IdPs you need to configure a fully qualified domain name (FQDN) for OpenIDM. LinkedIn accepts Localhost which is why we utilize LinkedIn in this article.

Below are the steps required to perform this setup. Each step will be described in detailed.

  1. Creating an Application in LinkedIn
  2. Configure->Socal ID Providers in OpenIDM
  3. Turn on LinkedIn. Go to dev site and get
    1. Client ID and Client Secret
    2. Insert Redirect URIs
  4. Enable Social Providers authN module
  5. Enable Social Self-Service Registration



Creating an Application in LinkedIn

A prerequisite to being able to set up Social IdP integration in OpenIDM is an existing application in LinkedIn. The LinkedIn developer site allows you to create applications using the LinkedIn API.

  1. Should you not already have a company created, create one.



3. Next step is to create the actual Application. The application will allow you to get two important credentials. Client ID and Client Secret, required for configuring Social IdP integration in OpenIDM. It will also allow you to define Redirect URLs.




Configure->Social Identity Providers in OpenIDM

Next up will are going to configure LinkedIn as a Social Identity Provider. Point your browser to OpenIDM administrative interface and click on Configure->Social Identity Providers in the top menus.


The configuration screen that follows is where the Client ID and Client Secret should be defined.


Make sure you click “save” once the Client ID and Client Secret have been inserted from the LinkedIn Developer Site and the newly created Application in the previous step.

Configure Social Provider as an Authentication module

Since we want to leverage LinkedIn for authentication, we also need to configure Social Identity Provider as an authentication module. The two “Warnings” that pops up will take you straight to the two steps necessary to complete this exercise. Just click on “Social Providers” or via the menu option Configure->Authentication and the the Module tab.


Make sure to select “+ Add”. The default configuration values can be left as is and save the settings by selecting “Submit”.

Ensure LinkedIn is leveraging during Self-Service Registration

To utilize the identity information available in users LinkedIn profiles during registration and thereby lowering the barrier to register make sure you select Configure->Self Service and turn “Social Registration” to ON.

The Social Registration Properties tab outlines how the identity data will populate the managed user object, which in turn is what we can leverage to provision downstream to integrated target resources. Should you want to amend or augment the user with additional identity data, this is the place where you can make the necessary changes and/or additions.




Should we log out at this point, a LinkedIn authentication button will be displayed on both the Administrative user interface as well as the self-service user interface. The Self-service interface also has a link at the bottom of the page to register for a new account.

                                        

Summary and conclusion 

The introduction of Social IdP integration in OpenIDM 5.0 allows customers to quickly take advantage of Social Identity Providers for self-service registration and authentication. This lowers the barrier to enter and limits the necessity to register using multiple forms being displayed to users. The information gathered allows for downstream provisioning to marketing solutions, such as Marketo, or to other integrated target resources. Try it out and let me know how it goes!

fredag 3 juni 2016

Common Pitfalls deploying OpenIDM

ForgeRock OpenIDM is built around the concept of flexibility, that in itself provides a powerful platform to solve all kinds of Identity provisioning related problems that organizations and enterprises faces. Whether its for internal-facing users such as employees or contractors or if its external facing identities such as customers or partners leveraging services your company exposes, OpenIDM is the ideal platform to address these challenges.

However, with this flexibility comes a great deal of potential pitfalls the reckless implementer can fall into, and since I recently discussed this at the ForgeRock UnSummit in San Francisco, I thought i'd highlight some of these in my blog. 
  • Isolate each piece of the deployment (e.g. source system, target system, IDM repository, etc..) and measure perf.
    • Weakest link will be the limiting factor for recon performance
Yes! We all know that mainframes integrated via screen-scraping is horribly slow performant. Don't expect anything different. 
  • Ensure recon source/target queries return full objects vs using the default of query-all-ids.  This has a dramatic impact on overall recon time as once the initial source/target queries have executed the recon doesn't need to query those systems again until the target objects are updated
  • For very large source datasets, us paging with recon source queries
  • Isolate audit data within it's own database

    Audit can be useful and needed, but if not needed limit the amount of audit data that is written down. Avoid using the repo for audit data storage as this puts stress on the repo and will slow the performance. Always use its own DB. If your use-case do not require audit at all but require super high performance - turn off audit all together.
  • Be wary of circular updates when using bi-directional mappings.

    This is a dangerous one! The scenario where i have essentially two authoritative sources for the same piece of identity data. E.g. a Database containing a set of identity attributes and the same being stored in OpenIDM as part of the Managed User. When changes occur on the database it should propagate back to OpenIDM and when changes occur on OpenIDM it should propagate to the Database - Implemented thru the use of our hooks, e.g. onUpdate. If not careful, one can easily end up in a circular cascading behaviour of updates!
  • Be wary of mappings which always result in a modified target object.  For example when mapping password -> userPassword via the LDAP Connector. The userPassword attribute in the provisioner MUST have the NOT_RETURNED_BY_DEFAULT and NOT_READABLE flags set otherwise OpenIDM will compare the clear-text password value to the hashed userPassword value returned by LDAP and always push a change.
  • In a cluster, always set schedules to persistent and disable concurrent execution
  • Always use the LDAP connector over that of the .NET Connector unless it is impossible to do otherwise. LDAP Connector performance is far greater than that of the .NET Connector

    If managing only users in Active Directory without the need to do more sophisticated things like running scripts, PowerShell CmdLets, setting ACLs etc - the LDAP integration approach is most suitable and much better on performance.
  • Always use immutable IDs for Managed Objects and remote System Objects
Although it is easier when playing with the REST API thru tools such as Curl, using simplified IDs such as human readable clear text names, this is generally a bad idea outside of demoing capabilities, development etc. Leverage the auto-generated UUIDs each object gets in OpenIDM and you will avoid problems later. 


Should you have experienced issues or pitfalls that is worth describing, feel free to drop me a note! 

måndag 1 juni 2015

How to do ScriptedTask in OpenIDM Workflow

Here is a quick demonstration I compiled after the last post. This was demonstrated at the ForgeRock Identity Summit 2015 in Half Moon Bay, CA as well as in a webinar. For all those who missed out on either of these opportunities, here is a quick summary.

The Whats, Whys, and Hows of XDR

Preventing security incidents is one of the primary goals of any security program. This should come as no surprise, and with today's eve...