Trusted Central Signing Service - PhenixID Document Signing Web Application

Prerequisites

- PAS 4.1 or higher installed

- The reader of this document should have some basic knowledge about PhenixID Server.

- Changes will be made to the file phenix-store.json, so please make sure to have a backup  of this file.

Add PhenixID Document Signing Web Application module

- Login to PhenixID Authentication Services - Configuration manager

- Click on the tab Advanced

- Click on the pen to the right of Modules

- Append these modules

{
        "name": "com.phenixidentity~phenix-prism",
        "enabled": "true",
        "config": {
            "display_name": "PhenixID Document Signing",
            "base_url": "/signapp",
            "auth_redirect_url": "/signapp/authenticate/signapp",
            "module_refs": "signappMod"
        },
        "id": "signapp_1"
    },
    {
        "name": "com.phenixidentity~phenix-prism-signingclient",
        "enabled": "false",
        "config": {
            "display_name": "PhenixID Document Signing",
            "base_uri": "signapp",
            "signPipeID": "SignAppDocSignPipe",
            "verifyPipeID": "SignAppDocVerifyPipe",
            "showPipeID": "SignAppDocShowPipe"
        },
        "id": "signappMod"
    }

- Click Stage Changes and Commit Changes

 

- Click on the pen to the right of NODE_GROUPS

- Add the module "signapp_1" to module_refs.

- Click Stage Changes and Commit Changes

Add LDAP Connection

- Logon to Configuration Manager

- Click on Scenarios

- Click Connectios

- Click + next to LDAP and configure your LDAP connection.

- When done, click the Advanced tab

- Expand Database Connections

- Copy the Scenario ID value of the database (ldap) object created. This will be used in later steps.

Add authenticator for PhenixID Document Signing Web Application

First of all, decide which authenticator(s) to be used from this list of available authenticators for PhenixID web apps authentication.

- Click on the pen to the right of Authentication - HTTP

- Add your authenticator(s) via the step-by-steps described here.
Make sure the successURL is /signapp/.

 

In this example, a simple username and password authenticator is used.

{
		"alias": "signapp",
		"name": "PostUidAndPassword",
		"configuration": {
			"pipeID": "pipeSignAppAuth",
			"successURL": "/signapp/",
			"translationKey": "login.messages.information.body.enduser",
			"headingtranslationKey": "login.messages.information.header.enduser",
			"title": "login.messages.information.title.enduser",
			"allowLanguageChange": "true"
		},
		"id": "signapp"
	}

- Click Stage changes and Commit changes

- Click on the pen to the right of Pipes

- Add this pipe configuration. 

{
		"id": "pipeSignAppAuth",
		"valves": [
			{
				"name": "LDAPSearchValve",
				"config": {
					"connection_ref": "replacewithyourconnectionid",
					"base_dn": "DC=example,DC=org",
					"scope": "SUB",
					"size_limit": "0",
					"filter_template": "(uid={{request.username}})",
					"attributes": ""
				}
			},
			{
				"name": "LDAPBindValve",
				"config": {
					"connection_ref": "replacewithyourconnectionid",
					"password_param_name": "password"
				}
			}
		]
	}

Change connection_ref to the ldap Scenario ID value fetched in previous step. 

Change base_dn and filter_template to suit your environment.

- Click Stage changes and Commit changes

Add execution flow (pipe) to display pdf

- Click on the pen to the right of Pipes

- Add this pipe. The configuration in this pipe will fetch the pdf data and store it in the session. The pdf data in the session will be used in later steps to display and sign the pdf.

Please note that this might not suit your environment. Valves can be replaced, removed or added based on your needs. Please view the documentation to get a list of available valves.

 

{
     "id": "SignAppDocShowPipe",
     "description": "Show document",
     "valves": [
        {
          "name": "ItemCreateValve",
          "config": {
              "dest_id": "{{request.user_id}}"
        }
},
        {
          "name": "PropertyAddValve",
          "config": {
              "name": "b64",
              "value": "{{request.body}}"
        }
},
        {
          "name": "SessionLoadValve",
          "config": {
              "id": "{{request.session_id}}"
        }
},
        {
          "name": "SessionPropertyReplaceValve",
          "config": {
              "name": "pdf_data",
              "value": "{{request.body}}"
        }
},
        {
          "name": "SessionPropertyReplaceValve",
          "config": {
              "name": "pdf_filename",
              "value": "{{request.filename}}"
        }
},
        {
          "name": "SessionPropertyReplaceValve",
          "config": {
              "name": "pdf_contentType",
              "value": "{{request.Content-Type}}"
        }
},
        {
          "name": "SessionPersistValve",
          "config": {}
        }
    ]
}

Add execution flow (pipe) to sign pdf

- Click on the pen to the right of Pipes

- Add this pipe. The configuration in this pipe will fetch the logged-in user attributes from the LDAP store and use these attributes to populate the self-signed certificate. The self-signed certificate will then be used to perform the signing operation of the incoming PDF file.

Please note that this might not suit your environment. Valves can be replaced, removed or added based on your needs. Please view the documentation to get a list of available valves.

 


{
     "id": "SignAppDocSignPipe",
     "description": "Sign document",
     "valves": [
        {
          "name": "SessionLoadValve",
          "config": {
              "id": "{{request.session_id}}"
        }
},
        {
          "name": "LDAPSearchValve",
          "config": {
              "connection_ref": "replacewithyourconnectionid",
              "base_dn": "DC=example,DC=org",
              "scope": "SUB",
              "size_limit": "0",
              "filter_template": "uid={{request.userid}}",
              "attributes": "givenName,sn,mail,displayName"
        }
},
        {
          "name": "PropertyAddValve",
          "config": {
              "name": "b64",
              "value": "{{session.pdf_data}}"
        }
},
        {
          "name": "PropertyAddValve",
          "config": {
              "name": "filename",
              "value": "{{session.pdf_filename}}"
        }
},
        {
          "name": "PropertyAddValve",
          "config": {
              "name": "Content-Type",
              "value": "{{session.pdf_contentType}}"
        }
},
{
          "name": "PropertyAddValve",
          "config": {
              "name": "signerID",
              "value": "{{request.userid}}"
        }
},

        {
          "name": "PropertyBase64DecoderValve",
          "config": {
              "source": "b64",
              "dest": "temporary"
        }
},
        {
          "name": "CreateShortTermKeyStoreValve",
          "enabled": "true",
          "config": {
              "subjectKeyParamater": "CN={{item.displayName}},OU=Demo,O=PhenixID",
              "caTemplateKeyParamater": "replacewithyourcaID",
              "keyUsage": [
                "true",
                "true"
              ]
        }
},
        {
          "name": "AddImageToPDFValve",
          "enabled": "true",
          "config": {
              "pathToImage": "C:/Program Files/PhenixID/Server/sign_image/PhenixID-overlay.png",
              "pdfSource": "{{session.pdf_data}}",
              "imagelocation": "northwest"
        }
},
        {
          "name": "PADESSignValve",
          "enabled": "true",
          "config": {
              "keyStoreID": "{{item.keyStoreId}}",
              "pdfSourceData": "{{item.pdfupdated}}",
              "pdfTarget": "document"
        }
},
        {
          "name": "ScriptEvalValve",
          "config": {
              "mime_type": "application/javascript",
              "script": "var array = flow.items().get(0).getPropertyValue('filename').split('.');var fileExt = array.pop();var fileName = array.join('.');flow.items().get(0).replaceProperty('filename', fileName);flow.items().get(0).replaceProperty('filext', fileExt);"
        }
},
        {
          "name": "PropertyRemoveValve",
          "config": {
               "name": "b64"
        }
},
        {
          "name": "PropertyAddValve",
          "config": {
              "name": "filename_to_attach",
              "value": "signed_{{item.filename}}.pdf"
        }
},
        {
          "name": "SMTPValve",
          "config": {
              "userid_param_name": "userid",
              "smtp_host": "smtp.company.org",
              "smtp_port": "587",
              "smtp_username": "[email protected]",
              "smtp_password": "{enc}xxxxxxxxxxxxxxxxxxxxxxxxxxx",
              "mail_param_name": "{{item.mail}}",
              "attachment_param_name": "document",
              "attachment_name_param_name": "filename_to_attach",
              "message_subject": "Your signed document attached",
              "message_body": "Signing procedure completed! Please find the signed document attached!"
        }
     },
{
				"name": "EventValve",
				"config": {
					"event_key": "EVT_000052",
					"parameters": [
						{
							"parameter": "duser",
							"value": "{{item.signerID}}"
						},
						{
							"parameter": "msg",
							"value": "Successfully signed"
						},
						{
							"parameter": "phenixIDIdentifier",
							"value": "SIGN"
						},
						{
							"parameter": "proto",
							"value": "PADES"
						}
					]
				}
			}
   ]
},

Change these values to suit your environment:

- LDAPSearchValve: connection_ref, base_dn, filter, attributes

- CreateShortTermKeyStoreValve: subjectKeyParamater, caTemplateKeyParameter (for testing purposes the builtin CA delivered with PhenixID Server can be used. The ID can be found in the file phenix-store.json in the section "CA_CONFIGURATIONS".)

- AddImageToPDFValve, use this valve if you want to add a picture to the end of the PDF file. Point to the picture that should be used. The position is set with the parameter "imagelocation" and value can be northwest, northeast and so on.

NOTE: AddImageToPDFValve will generate the property "pdfupdated" as seen in the example below:
{{item.pdfupdated}}
If AddImageToPDFValve is removed from the flow, "pdfSourceData", on PADESSignValve needs to be changed to "{{item.temporary}}".

- SMTPValve: smtp_host, smtp_port, smtp_username, smtp_password.

NB! An item property named mail is expected to be returned by the pipe. In cases where the emailadress is stored on another attribute than mail in the user store, make sure to add an item property named mail containing the user email adress.

 

- Click Stage changes and Commit changes

Add execution flows (pipe) for verify

- Create a jks trust store file

- Add all the CAs you trust to issue certificates to sign PDFs

- Place the jks file in a folder (example: C:/Program Files/PhenixID/SigningService/custom/trustedcas.jks)

- Click on the pen to the right of Pipes

- Add this pipe. The configuration in this pipe will validate the signature to make sure the data has not been altered.

Please note that this might not suit your environment. Valves can be replaced, removed or added based on your needs. Please view the documentation to get a list of available valves. Please also view this document to see how the certificates can be extracted from the signatures (in order to validate the certificates using this valve).

{
		"id": "SignAppDocVerifyPipe",
		"description": "Verify pdf document signature(s)",
		"valves": [
			{
				"name": "ItemCreateValve",
				"config": {
					"dest_id": "{{request.userid}}"
				}
			},
			{
				"name": "PropertyAddValve",
				"config": {
					"name": "b64",
					"value": "{{request.body}}"
				}
			},
			{
				"name": "PropertyBase64DecoderValve",
				"config": {
					"source": "b64",
					"dest": "temporary"
				}
			},
         {
				"name": "PDFSignatureStatusValve",
				"enabled": "true",
				"config": {
					"pdfSource": "{{item.b64}}",
              "trustStorePath": "C:/Program Files/PhenixID/SigningService/custom/trustedcas.jks",
			     "trustStorePassword": "secret (change this to your jks file pwd)"
				}
			}
		]
	}

- Click Stage changes and Commit changes

Test

  1. Browse to https://<phenix_server>:<phenix_server_http_port>/signapp/
  2. You should be redirected to https://<phenix_server>:<phenix_server_http_port>/signapp/authenticate/signapp
  3. Authenticate
  4. You should now be logged in to the PhenixID Document Signing Web application
  5. Upload a pdf document and click Sign
  6. Verify that a signed pdf document was sent to your mail box
  7. Download the signed pdf document
  8. Upload the signed pdf document and click Verify.
  9. Signature validation should result in a successful (green bar) respons

Troubleshooting

Check server.log file.