Configure secondfactor selector

Some environments have multiple http authentication methods to choose from for a specific login. In such cases, the AuthSelector authenticator can be used to present a list of authentication method choices to the end user. To make it even easier for the end user, it is possible to use a secondfactor selector. The second factor selector works like this:

- User authenticates with username and password

- The system, via a pipe, finds out the possible second factor delivery methods for the specific user. The logic can be based on directory user object attributes, tokens enrolled etc.

- The second factor delivery methods are presented for the user to choose from.

 

Note:

Before you begin start by taking a backup of the phenix-store.json file.

Prereqs:

The administrator should have knowledge about PhenixID HTTP authenticators and pipes configuration.

Enable the second factor selector module

- Login to the configuration manager

- Click on the configuration tab

- Click on the pen next to Modules

- Paste the below modules. Make sure it is pasted on the right level - before you paste, place the cursor after the first character ([). Change "port" and "ssl" flags to suite your environment.

{
		"name": "com.phenixidentity~phenix-prism",
		"enabled": "true",
		"config": {
			"base_url": "/saml/secondfactor",
			"auth_redirect_url": "/saml/secondfactor/authenticate/usernamepassword",
			"port": "8080",
			"ssl": "false",
			"module_refs": "secondfactor_module",
			"show_header": "false",
			"show_footer": "false"
		},
		"id": "prism_secondfactor"
	},
	{
		"name": "com.phenixidentity~phenix-prism-secondfactorselector~2.0.0",
		"enabled": "false",
		"config": {
			"display_name": "PhenixID 2ndfactor",
			"base_uri": "saml/secondfactor",
			"secondfactorselector_pipe": "getOtpDeliveryMethods",
			"port": "8080",
			"ssl": "false"
		},
		"id": "secondfactor_module"
	}

- Click Stage changes - Commit Changes

- Click on the pen next to System nodes

- Add the module to the node(s) by adding the prism id to the module_refs list.

	{
		"name": "ubuntu",
		"description": "Default node (created automatically)",
		"config": {
			"module_refs": "prism_secondfactor,fd4f5cd3-d98c-4728-bc9f-9777b5d8f2ea,95e347c5-e201-43dc-bb4c-9ea647de46d6,07549273-92e8-4f0a-9ea5-320bdbc10981,a61fb18e-1fe6-406a-b71d-4aceec3fa648,ae5d5079-a6c2-4db7-9788-11e185bc82ea,a071aa69-342e-4993-a4b3-9444f3910cf1,20522a01-2764-491c-9fb2-08cd50bad431,cb4c8ffa-dcff-4269-8167-93ccb98d8614,9b8274dc-7539-48c4-b390-3ea8d6021460"
		},
		"created": "2017-01-21T09:13:58.479Z",
		"id": "d055608c-44bf-486a-90b2-5a7f209d3efb",
		"modified": "2017-02-07T12:41:18.748Z"
	}
 

- Click Stage changes - Commit Changes

Setup username and password authenticator for the second factor selector

Setup the primary authentication (normally username and password) which should be executed before the second factor selector is presented.

- Click on the configuration tab

- Click on the pen next to Authentication - HTTP

- Add the authenticator below.

{
		"id": "usernamepassword",
		"alias": "usernamepassword",
		"name": "PostUidAndPassword",
		"configuration": {
			"pipeID": "pipeUnPw",
			"successURL": "/saml/secondfactor/"
		}
	}

- Click Stage changes - Commit Changes

- Click on the pen next to Pipes

- Add the pipe below. Change connection_ref to point to the id of your LDAP connection. Change base_dn and filter_template to suite your directory.

{
		"id": "pipeUnPw",
		"valves": [
			{
				"name": "LDAPSearchValve",
				"enabled": "true",
				"config": {
					"connection_ref": "ebf0c0d3-32ab-427e-b8a8-1770f53a2daf",
					"base_dn": "dc=bjorken,dc=local",
					"scope": "SUB",
					"size_limit": "0",
					"filter_template": "uid={{request.username}}"
				}
			},
			{
				"name": "LDAPBindValve",
				"enabled": "true",
				"config": {
					"connection_ref": "ebf0c0d3-32ab-427e-b8a8-1770f53a2daf",
					"password_param_name": "password"
				}
			}
		]
	}

- Click Stage changes - Commit Changes

Configure second factor selection pipe

This pipe will fetch the userid and collect possible authentication methods for the user. In the example pipe below, the ldap directory user object attributes mail and mobile will be controlled. If mail contains a value, otp delivery by SMTP will be displayed. If mobile contains a value, otp delivery by SMS will be displayed.

The pipe will also check if the user enrolled for PocketPass and/or OneTouch. If so, option(s) for the(se) method(s) will be displayed as well.

- Login to configuration manager

- Click Configuration tab

- Edit pipes

- Paste pipe below. Edit to suite your environment. Every second factor option is represented as an item with certain properties. Make sure every item returned contains these properties:

* methodDisplayName - this will be displayed as the option to choose for the end user

* URL - this will be the authenticator URL to redirect to if user choose option. Make sure the uri path matches the second factor selector uri (in this example saml/)

* [OPTIONAL] force - (true/false) - set this if you would like to skip the choose dialogue and instead to a automatic redirect to speficied option.

	{
		"id": "getOtpDeliveryMethods",
		"valves": [
			{
				"name": "LDAPSearchValve",
				"enabled": "true",
				"config": {
					"connection_ref": "ebf0c0d3-32ab-427e-b8a8-1770f53a2daf",
					"base_dn": "dc=bjorken,dc=local",
					"scope": "SUB",
					"size_limit": "0",
					"filter_template": "uid={{request.uid}}",
					"attributes": "mobile,mail"
				}
			},
			{
				"name": "ItemCreateValve",
				"enabled": "true",
				"config": {
					"dest_id": "1",
					"exec_if_expr": "flow.items().get(0).containsProperty('mobile')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "methodDisplayName",
					"value": "OTP by SMS",
					"item_include_expr": "item.getId().equals('1')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "URL",
					"value": "http://ubuntu.anders.local:8080/saml/authenticate/1c3a9763-5f75-409a-9d86-7315fbc4b18f",
					"item_include_expr": "item.getId().equals('1')"
				}
			},
			{
				"name": "ItemCreateValve",
				"enabled": "true",
				"config": {
					"dest_id": "2",
					"exec_if_expr": "flow.items().get(0).containsProperty('mail')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "methodDisplayName",
					"value": "OTP by mail",
					"item_include_expr": "item.getId().equals('2')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "URL",
					"value": "http://ubuntu.anders.local:8080/saml/authenticate/mail",
					"item_include_expr": "item.getId().equals('2')"
				}
			},
			{
				"name": "GetTokenExistsValve",
				"config": {
					"username_attribute": "uid",
					"get_value_attribute_key": "HasToken",
	             "token_type": "OATH"
				}
			},
			{
				"name": "ItemCreateValve",
				"enabled": "true",
				"config": {
					"dest_id": "3",
					"exec_if_expr": "flow.property('HasToken').equals('true')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "methodDisplayName",
					"value": "OTP by token",
					"item_include_expr": "item.getId().equals('3')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "URL",
					"value": "http://ubuntu.anders.local:8080/saml/authenticate/token",
					"item_include_expr": "item.getId().equals('3')"
				}
			},
			{
				"name": "GetTokenExistsValve",
				"config": {
					"username_attribute": "uid",
					"get_value_attribute_key": "HasTokenPKI",
					"token_type": "PKI"
				}
			},
			{
				"name": "ItemCreateValve",
				"enabled": "true",
				"config": {
					"dest_id": "4",
					"exec_if_expr": "flow.property('HasTokenPKI').equals('true')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "methodDisplayName",
					"value": "OneTouch",
					"item_include_expr": "item.getId().equals('4')"
				}
			},
			{
				"name": "PropertyAddValve",
				"enabled": "true",
				"config": {
					"name": "URL",
					"value": "http://ubuntu.anders.local:8080/saml/authenticate/ot",
					"item_include_expr": "item.getId().equals('4')"
				}
			},
{
				"name": "ItemRemoveValve",
				"enabled": "true",
				"config": {
					"item_include_expr": "item.getId().startsWith('CN=') && !item.containsProperty('mobile') && !item.containsProperty('mail')"
				}
			}
		]
	}

 

Specifying authenticators

What do you need to think about regarding the authenticators the user chooses from?

* Make sure you add a skip_if_expr on the LDAPBindValve to avoid prompting for password again. This will skip password check if the user  already authenticated with username/password.

{
		"id": "f3a1f850-1c98-4580-8856-147af9145bf9",
		"name": "LDAPBindValve",
		"enabled": "true",
		"config": {
			"connection_ref": "ebf0c0d3-32ab-427e-b8a8-1770f53a2daf",
			"password_param_name": "password",
			"guide_ref": "8452abc3-ac1c-49c6-a261-92855bd0bd7d",
			"skip_if_expr": "request.authenticatedrequest=='true'"
		},
		"created": "2017-02-07T09:49:33.281Z"
	}

 

SAML

For SAML scenarios to work properly with the second factor selector, make sure you add a SAMLDataSave authenticator as the first authenticator in the flow (ie the authenticator pointed to in the POSTSSOURL).

	{
		"alias": "samldatasave",
		"id": "samldatasave",
		"name": "SAMLDataSave",
		"configuration": {
			"nextAuthenticator": "usernamepassword",
			"idpID": "id_to_my_idp"
		}
	}