Open Banking TPP Client Authentication with Ping Identity
The Open Banking Security Profile defines how Third Party Provider (TPP) applications shall obtain and use OAuth and OpenID Connect tokens in a secure way, suitable for financial transactions. TPP applications will need to obtain tokens from account servicing payment service providers (ASPSPs) to initiate and complete transactions once a user has provided consent and authorized the ASPSP.
As part of the process of obtaining tokens, the security profile defines what authentication methods ASPSPs must support and make available to TPPs to authenticate. The following is required by the security profile:
Of the three methods available, MTLS and Private Key JWT are recommended by Open Banking. In this blog post I will explain how to implement Private Key JWT using the Ping Identity software stack. You can also view my previous blogs on how to enable Open Banking dynamic client registration with Ping Identity and how to use the client registration tool.
Private Key JWT authentication is defined by the “JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants” specification and defines a method for a TPP client application to authenticate at an ASPSP sending a JWT token.
In order to be able to authenticate at an ASPSP and request tokens, a TPP must have completed the following steps, explained in the blog about Dynamic Client Registration:
Once a TPP has completed the above initial registration steps, it can obtain tokens from the ASPSP with the following steps:
The following example shows a private key JWT authentication request for an OAuth client credentials grant type (non URL encoded and abbreviated for clarity):
The decoded JWT is displayed below:
To demonstrate how private key JWT client authentication works, I will use a Ping Identity test environment connected to the Open Banking Multi-Party Industry Testing (MIT) Directory, where I have previously registered an ASPSP and an Account Information Service Provider (AISP) and where I have an account as a PTC.
Logical Architecture
The following diagram shows how PingFederate, PingAccess and PingDirectory are deployed and connected in the test environment.
To test client authentication, I start from an environment where PingFederate has already been deployed, enabled for OAuth and where an OAuth client has been created using the registration tool described in the previous blog. PingAccess has also been deployed and configured to protect the PingFederate token endpoint via Mutual TLS (MTLS).
The screenshot below displays the relevant part of the OAuth client configuration that enables private key JWT authentication. This is accessible from the PingFederate administrative UI via the “OAuth Server” menu, selecting the client created with the client registration tool.
The CLIENT AUTHENTICATION field is set to PRIVATE KEY JWT (optionally, replay prevention can be enabled to avoid that a client can reuse the same token to authenticate twice) and the JWKS URL is set to the address of the JWKS associated to the TPP client in the Open Banking directory. This value is derived from the software statement that was submitted as part of the registration request.
When PingFederate receives a private key JWT for client authentication, it validates the token according to the specification; as part of the validation it checks that the “aud” claim of the JWT matches the PingFederate token endpoint, using the PingFederate base URL. In this case, the token endpoint is published via PingAccess using a URL that differs from the PingFederate base URL (because the token endpoint must be protected via MTLS). I need therefore to modify the default configuration to set the correct token endpoint URL in PingFederate to make the “aud” check pass. The configuration is available in the PingFederate management UI in the “OAuth Server” - “Authorization Server Settings” - “TOKEN ENDPOINT BASE URL” field. This field must be set with the base URL used in PingAccess to expose the token endpoint.
To send the authentication requests, I will use a Java tool that generates an authentication JWT and submits a token request to the token endpoint of the ASPSP, using the OAuth client credential grant.
The tool uses the Jose4j library to generate the JWT with the code below:
Once the private key JWT is available, the tool sends the token request to the ASPSP token endpoint. I implemented the actual call with Unirest for convenience.
The tool is available as a Maven project on the Ping Identity GitHub page. To run the tool:
This is the expected output:
Private key JWT eyJraWQiOiJ2TmF1aDEt<Abbreviated>sgTHUN5Q
ASPSP Token endpoint response code 200, body "access_token":"dYFT6Uihl2BHSuJTbiE25C99bZ0x","token_type":"Bearer","expires_in":7200}
Access token dYFT6Uihl2BHSuJTbiE25C99bZ0x
For more information on how Ping Identity can address the technical challenges of securing access to Open Banking APIs, watch the Open Banking Solution Architecture video or visit www.pingidentity.com/PSD2.