How to configure PhenixID Signing Services (or PAS) with person search API

This document describes how to configure PAS/Signing with person search API. Signing Workflow will consume this API when performing user searches / lookups.

You may use the PhenixID Signing Services that has been setup for Signing Workflow or a standalone PhenixID Authentication Services / PhenixID Signing Services.

Audience

System administrators. The reader is expected to have basic knowledge about PhenixID Authentication Services / Signing Services. The reader is expected to have basic knowledge about the pipes data model (items).

About the API

Setting up the API is simply about exposing three execution flows (pipes) over HTTP.  

Exposing the pipes module

Expose the pipes module by enabling http access and assign it to a specific port. It is recommended to assign this to the non-default http port. Follow this configuration step-by-step. If needed, adjust it to suite your environment.

 

  1. Login to Configuration Manager
  2. Browse to Scenarios->Connections
  3. Add a new https connection, use port 7443 as the port (change to suite your environment). Example:

4. When finished, copy the ID value of the new connection.

5. Click Advanced

6. Click on the pen to the right of modules

7. Locate the pipes module.

8. Add two parameters to the pipe module -> config section. Change the http_configuration_ref value to match the copied ID in a previous step.

           "http_enabled" : "true",
		    "http_configuration_ref" : "c4ff1335-d429-476e-bd33-c058fb6f4723"

 

Full example:

{
		"name": "com.phenixidentity~phenix-pipes",
		"scope": "global",
		"singleton": "true",
		"config": {
		    "http_enabled" : "true",
		    "http_configuration_ref" : "c4ff1335-d429-476e-bd33-c058fb6f4723"
		},
		"enabled": "true",
		"created": "2019-02-18T08:49:29.238Z",
		"id": "8589385b-2555-440c-a310-3fe75e8d04a3"
	},

 

9. Click Stage changes and commit changes.

Adding internal user search operation

The internal user search operation performs a user search when the user selects "internal" in the Signing Workflow user interface.

The pipe will return multiple items. The first item in the item set is a header item which the caller (Signing Workflow) will ignore. The following items will be consumed though. Each item corresponds to one user.

  1. Login to configuration manager
  2. Go to Advanced
  3. Click on the plus sign next to Pipes
  4. Add this pipe:
{
    "id" : "internal_user_search_swf",
    "description" : "Internal user search",
    "http_enabled" : "true",
    "http_path_pattern" : "GET:/pipes/users/search",
    "http_response_content_type" : "text/plain",
    "valves" : [ {
      "name" : "ItemCreateValve",
      "config" : {
        "dest_id" : "header_item",
        "exec_if_expr" : "flow.isEmpty()"
      }
    }, {
      "name" : "PropertySetValve",
      "config" : {
        "name" : "query",
        "value" : "{{item.query}}(mail={{request.mail}})",
        "exec_if_expr" : "request.get('mail')!=null && request.get('mail').length>0"
      }
    }, {
      "name" : "PropertySetValve",
      "config" : {
        "name" : "query",
        "value" : "{{item.query}}(givenName={{request.firstName}})",
        "exec_if_expr" : "request.get('firstName')!=null && request.get('firstName').length>0"
      }
    }, {
      "name" : "PropertySetValve",
      "config" : {
        "name" : "query",
        "value" : "{{item.query}}(sn={{request.lastName}})",
        "exec_if_expr" : "request.get('lastName')!=null && request.get('lastName').length>0"
      }
    }, {
      "name" : "PropertySetValve",
      "config" : {
        "name" : "query",
        "value" : "{{item.query}}(sAMAccountName={{request.userId}})",
        "exec_if_expr" : "request.get('userId')!=null && request.get('userId').length>0"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "source",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('source')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "identifier",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('identifier')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "externalIds",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('externalIds')"
      }
    }, {
      "name" : "LDAPSearchValve",
      "config" : {
        "connection_ref" : "REPLACE-LDAP-CONNECTION",
        "base_dn" : "REPLACE-BASE-DN",
        "scope" : "SUB",
        "size_limit" : "500",
        "filter_template" : "(&{{item.query}})",
        "allow_multiple" : "true",
        "item_include_expr" : "item.containsProperty('query')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "identifier",
        "value" : "sAMAccountName={{item.sAMAccountName}}",
        "item_include_expr" : "!item.containsProperty('identifier')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "source",
        "value" : "INTERNAL",
        "item_include_expr" : "!item.containsProperty('source')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "externalIds",
        "value" : "{{item.sAMAccountName}}",
        "splitter" : ";",
        "item_include_expr" : "!item.containsProperty('externalIds')"
      }
    } ]
  }

 

5. Find the id of your LDAP connection.

6. Replace  REPLACE-LDAP-CONNECTION with the fetched id.

7. Replace REPLACE-BASE-DN with the LDAP distinguised name of your search base

8. Make sure the identifier value and externalIds value (sAMAccountName in the example above) matches the SAML NameID of the internal users logging in to Signing Workflow. Change if needed.

9. Click Stage changes and commit changes.

Adding internal user lookup

The internal user lookup operation performs a user lookup on a user that has been selected as signer on a signing workflow errand, where the user has been found through the internal user search.

The pipe should return two items. The first item in the item set is a header item which the caller (Signing Workflow) will ignore. The second item, which corresponds to the user, will be consumed by the caller.

  1. Login to configuration manager
  2. Go to Advanced
  3. Click on the plus sign next to Pipes
  4. Add this pipe:
{
    "id" : "internal_user_lookup_swf",
    "description" : "Internal user lookup",
    "http_enabled" : "true",
    "http_path_pattern" : "GET:/pipes/users/internal",
    "http_response_content_type" : "text/plain",
    "valves" : [ {
      "name" : "ItemCreateValve",
      "config" : {
        "dest_id" : "header_item",
        "exec_if_expr" : "flow.isEmpty()"
      }
    }, {
      "name" : "PropertySetValve",
      "config" : {
        "name" : "query",
        "value" : "({{request.q}})"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "source",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('source')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "identifier",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('identifier')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "externalIds",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('externalIds')"
      }
    }, {
      "name" : "LDAPSearchValve",
      "config" : {
        "connection_ref" : "REPLACE-LDAP-CONNECTION",
        "base_dn" : "REPLACE-BASE-DN",       
        "scope" : "SUB",
        "size_limit" : "1",
        "filter_template" : "(&{{item.query}})",
        "allow_multiple" : "true",
        "item_include_expr" : "item.containsProperty('query')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "source",
        "value" : "INTERNAL",
        "item_include_expr" : "!item.containsProperty('source')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "identifier",
        "value" : "sAMAccountName={{item.sAMAccountName}}",
        "item_include_expr" : "!item.containsProperty('identifier')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "externalIds",
        "value" : "{{item.sAMAccountName}}",
        "splitter" : ";",
        "item_include_expr" : "!item.containsProperty('externalIds')"
      }
    } ]
  }

5. Find the id of your LDAP connection.

6. Replace  REPLACE-LDAP-CONNECTION with the fetched id.

7. Replace REPLACE-BASE-DN with the LDAP distinguised name of your search base

8. Make sure the identifier value and externalIds value (sAMAccountName in the example above) matches the SAML NameID of the internal users logging in to Signing Workflow. Change if needed.

9. Click Stage changes and commit changes.

Adding external user lookup

The external user lookup operation performs a user lookup when a user performs an external user search from Signing Workflow. It is also used for a subsequent lookup on the user when the user has been assigned to sign a specific Signing Workflow errand.

The pipe should return two items. The first item in the item set is a header item which the caller (Signing Workflow) will ignore. The second item, which corresponds to the user, will be consumed by the caller.

The example below performs a query to swedish Skatteverket (Navet) to find user information. Based on your environment, the Navet lookup can be changed to SPAR lookup or, if external users reside a a user directory, a user lookup (sql or ldap for example). Please change below to match your requirements and processes!

  1. To user NavetLookup, patch your PhenixID server with that extension.
  2. Login to configuration manager
  3. Go to Advanced
  4. Click on the plus sign next to Pipes
  5. Add this pipe:
{
    "id" : "external_user_lookup_swf",
    "description" : "External user lookup",
    "http_enabled" : "true",
    "http_path_pattern" : "GET:/pipes/users/external",
    "http_response_content_type" : "text/plain",
    "valves" : [ {
      "name" : "ItemCreateValve",
      "config" : {
        "dest_id" : "header_item"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "source",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('source')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "identifier",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('identifier')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "externalIds",
        "value" : "N/A",
        "item_include_expr" : "!item.containsProperty('externalIds')"
      }
    }, {
      "name" : "ItemCreateValve",
      "config" : {
        "dest_id" : "person"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "serialNumber",
        "value" : "{{request.q}}",
        "item_include_expr" : "item.getId().contains('person')"
      }
    }, {
      "name": "PropertyReplaceValve",
      "config": {
        "source": "serialNumber",
        "token": "-",
        "replacement": ""
      }
    }, {
      "name" : "NavetLookupValve",
      "config" : {
        "keystore_path" : "D:/PhenixID/Server/cert/my.p12",
        "keystore_password" : "{enc}abc123",
        "org_nr" : "16xxxxxxxxx",
        "customer_id" : "00xxxxx-yyyy-zzz",
        "personnr_property_name" : "serialNumber",
        "item_include_expr" : "item.containsProperty('serialNumber')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "source",
        "value" : "EXTERNAL",
        "item_include_expr" : "!item.containsProperty('source')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "identifier",
        "value" : "{{item.serialNumber}}",
        "item_include_expr" : "!item.containsProperty('identifier')"
      }
    }, {
      "name" : "PropertyAddValve",
      "config" : {
        "name" : "externalIds",
        "value" : "{{item.serialNumber}}",
        "splitter" : ";",
        "item_include_expr" : "!item.containsProperty('externalIds')"
      }
    } ]
  }

5. Change the NavetLookupValve parameters in bold above. For more information, please view the valve documentation (choose your version).

6. Click stage changes and commit changes.

Test

Use Signing Workflow for testing.

You can also perform testing by simply using a web browser and enter the url and a querystring with search params (matching the request parameter names according to the configuration above).