How to configure PhenixID Authentication Services OpenIDConnect Provider (OP) with PKCE extension

This document describes how to configure a PhenixID Authentication Services OpenIDConnect Provider (OP) with the PKCE (https://tools.ietf.org/html/rfc7636) Extension.

System requirements

- PhenixID Authentication Services 3.3 OR PhenixID Authentication Services 3.2 with patches applied (see below)

Patch for PhenixID Authentication Services 3.2

  1. Download patch-files from https://files.phenixid.se/s/rMgLfR6RQjxDw8o
  2. Extract the zip
  3. Shutdown PhenixID Authentication Services
  4. Backup the folders <pas_server_root>/mods/com.phenixidentity~auth-http~3.2.0/ and <pas_server_root>/mods/com.phenixidentity~phenix-pipes~3.2.0/
  5. Copy the files OIDCToSAML*.class and paste in <pas_server_root>/mods/com.phenixidentity~auth-http~3.2.0/com/phenixidentity/authentication/handler/oidc/ (replace)
  6. Copy the file Metadata.class and paste in <pas_server_root>/mods/com.phenixidentity~auth-http~3.2.0/com/phenixidentity/authentication/handler/oidc/metadata/ (replace)
  7. Copy the file InputParameterHashURLSafeValve.class and paste in <pas_server_root>/mods/com.phenixidentity~phenix-pipes~3.2.0/com/phenixidentity/pipes/valves/input/ (add)
  8. Start PhenixID Authentication Services.

Setup OpenIDConnect Provider (OP)

[This step is optional if you already have an existing OP that you would like to extend with PKCE functionality)

1. Login to Configuration Manager

2. Navigate to Scenarios->OIDC.

3. Configure an OpenIDConnect Provider by selecting the desired sign-in method. Use the Authorization code flow.

Modify OP configuration

- Login to Configuration Manager

- Click Advanced

- Click the pen to the right of OIDC_OP

- Locate the relevant OP object

- Change params:

token_endpoint_auth_methods_supported = none

- Add param:

code_challenge_methods_supported = S256

Full example below:

	{
		"id": "test2",
		"tenant": "test2",
		"guide_ref": "guides.authentication.oidc.oidctosamlbroker",
		"config": {
			"authorization_endpoint": "https://192.168.145.6:8443/oidc/authenticate/test2",
			"issuer": "https://192.168.145.6:8443/test2",
			"token_endpoint": "https://192.168.145.6:8443/api/authentication/9771550c-9382-4787-88ac-74beba26344b?tenant=test2",
			"response_types_supported": [
				"code"
			],
			"grant_types_supported": [
				"authorization_code"
			],
			"subject_types_supported": [
				"public"
			],
			"id_token_signing_alg_values_supported": [
				"RS256"
			],
			"code_challenge_methods_supported": [
				"S256"
			],
			"scopes_supported": [
				"openid"
			],
			"token_endpoint_auth_methods_supported": [
				"none"
			],
			"claims_supported": [
				"iss",
				"ver",
				"sub",
				"given_name",
				"family_name"
			],
			"end_session_endpoint": "https://192.168.145.6:8443/oidc/authenticate/logout/",
			"request_parameter_supported": "true",
			"signStore": "479cf70f-a3e0-43ff-b99b-6ecb4ab3307d"
		},
		"created": "2020-07-07T12:20:08.756Z"
	},

 - Save the changes

- Verify by browsing to the OP Discovery URL and make sure the changes are displayed.

 

Modify authorization execution flow

(If you are using SAML Identity Provider for your OP, this step is not needed)

- Navigate to the OP scenario -> Execution flow

- Expand the top execution flow

- Add a SessionPropertyReplaceValve and place it among the other SessionPropertyReplaceValve in place.

Config params:
name = code_challenge
value = {{request.code_challenge}}

 

- Save

Modify token endpoint execution flow

 

- Navigate to the OP scenario -> Execution flow

- Expand the Token endpoint execution flow

- Expand RPBasicAuthentictionValve, click Advanced and deselect Enabled

- Add valve InputParameterHashURLSafeValve with the config parameters (key=value):
 provided_param_name = {{request.code_verifier}}
 destination_attribute_name = code_challenge_attribute
 hash_algo = SHA256

 Place the valve after the existing SessionResolveValve

- Add valve FlowFailValve
 message = PKCE failed
 Advanced->skip_if_expr = attributes.code_challenge_attribute.equals(session.get('code_challenge'))

 Place the valve after the newly added InputParameterHashURLSafeValve

- Save