More Resources:
Integration Walkthroughs
This document provides in detail the steps involved with integrating an existing application or login process with PingFederate using the Agentless Integration Kit. In addition to providing detailed integration steps, the document will provide some example integration scenarios and sample code for both IDP and SP integration.
This document will use an example “traditional” application and demonstrate how to integrate both the user authentication process and the application session creation into the PingFederate product to facilitate federated authentication.
There are multiple ways an application can be integrated into a federated SSO model, for example:
This document specifically refers to the following versions:
It is assumed the audience understands core federation concepts (Identity Provider / Service Provider roles, browser SSO authentication process) and basic application development concepts.
For browser SSO, PingFederate supports an "adapter" interface to provide "first-mile" and "last-mile" integration. When a user requests authentication to a federated SSO connection, PingFederate will send the user to an IDP Authentication Adapter to perform the authentication of the identity and to return information about the identity back to the login process. Similarly when PingFederate receives a federated security token and needs to create an application session from those credentials, an SP Adapter is called to perform this action.
PingFederate includes a large number of commercial integration kits and two code-based integration methods that can be used to create custom authentication adapters and custom application integration hooks:
The agentless kit does not require any libraries to be deployed on the integration endpoint to interface with the OpenToken it is considered language agnostic and can be used for almost any integration scenario.
Examples of where a custom IDP adapter may be used are:
The Agentless integration kit involves two main processes, the "pickup" process and the "dropoff" process.
The pickup process is used by the integration endpoint to fetch attributes from the PingFederate server. For example, the SP adapter collects information from the PingFederate server about an identity so that it can create an application session.
The pickup process involves the adapter making a HTTP GET to the PingFederate pickup endpoint. The client will authenticate to PingFederate and use a specific "reference" value to pickup the attributes appropriate to the transaction. More details about the pickup process are included in the product documentation for the agentless integration kit.
When accessing pickup endpoint, the endpoint should include the adapter instance ID as a HTTP header during the pickup call. When multiple adapters are configured on the PingFederate server, this header is required so it is a good habit to include the value by default. The header name is "ping.instanceId" and the value must match the "Instance Id"value of the adapter configured in the PingFederate console.
The basic steps you must follow to implement the Pickup process are:
For example, if a reference ID of 12345 was provided to an adapter, then using the following adapter configuration information:
PingFederate server | https://pf.company.com:9031 |
Adapter instance ID | sample_adapter |
Adapter user name | sample_id |
Adapter pass phrase | sample_password |
The following HTTP GET command would be issued to pickup the attributes referenced by the reference ID 12345. This example uses HTTP BASIC authentication:
GET https://pf.company.com:9031/ext/ref/pickup?REF=12345 HTTP/1.1
Authorization: BASIC c2FtcGxlX2lkOnNhbXBsZV9wYXNzd29yZA==
ping.instanceid: sample_adapter
PingFederate will respond with a response containing the attributes and associated session information:
HTTP/1.1 200 OK
{
"authnCtx":"urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified",
"partnerEntityID":"company:saml20:idp",
"subject":"jsmith",
"instanceId":"sample_adapter",
"sessionid":"sFMcTOaropYv5gYQZi1ZOpX7DZ8",
"authnInst":"2013-03-28 20:42:10-0500"
}
The dropoff process is the reverse of the pickup process. The integration endpoint will send attribute-value pairs to PingFederate and in return receive a reference ID to use when referring to these attributes.
The high level steps involved in the drop off process are:
Using the same scenario as above, we will dropoff the value of "jsmith" in the attribute "subject" to the PingFederate dropoff endpoint.
POST https://pf.company.com:9031/ext/ref/dropoff HTTP/1.1
Content-Length: 20
Content-Type: application/json
Authorization: BASIC c2FtcGxlX2lkOnNhbXBsZV9wYXNzd29yZA==
ping.instanceId: sample_adapter
{
“subject”:”jsmith”
}
The response from PingFederate to this request will be a reference ID, in this example the REF value returned is "54321":
HTTP/1.1 200 OK
{
“REF”:”54321”
}
To secure the interaction between PingFederate and the application being integrated, the agentless adapter will authenticate to PingFederate during pickup and dropoff events. This section will outline the three methods that the agentless adapter can use to authenticate to PingFederate:
Note: The examples in this document will use HTTP BASIC authentication (RFC 2617) however the three authentication mechanisms will be discussed in detail here.
Applications that don’t have support for certificate authentication or Base64 encoding the custom HTTP header variables (ping.uname and ping.pwd) can be used to send the adapter credentials to PingFederate. For example, the dropoff request sample above can be modified to use custom headers instead of BASIC authentication:
POST https://pf.company.com:9031/ext/ref/dropoff HTTP/1.1
Content-Length: 20
Content-Type: application/json
ping.uname: sample_id
ping.pwd: sample_password
ping.instanceId: sample_adapter
{
"subject":"jsmith"
}
HTTP Basic authentication involves Base64 encoding the username and password and including it in the HTTP Authorization header. The format is:
"Authorization: BASIC " + Base64_Encode( [USERNAME] + ":" + [PASSWORD] )
So using the above example, the Authorization header will be:
"Authorization: BASIC " + Base64_Encode("sample_id:sample_password")
finally:
"Authorization: BASIC c2FtcGxlX2lkOnNhbXBsZV9wYXNzd29yZA=="
This will result in a request as follows:
POST https://pf.company.com:9031/ext/ref/dropoff HTTP/1.1
Content-Length: 20
Content-Type: application/json
Authorization: BASIC c2FtcGxlX2lkOnNhbXBsZV9wYXNzd29yZA==
ping.instanceId: sample_adapter
{
"subject":"jsmith"
}
Mutual TLS authentication requires some pre-work on the PingFederate side and a slight change to how the adapter communicates with PingFederate.
Using the same example above, I am going to include a client certificate with the subject DN of "CN=sample_cert,O=company.com,C=US". For step three above, I have modified the "Allowed Subject DN" configuration item with the Subject DN of our certificate.
The adapter code was also modified to send the client certificate with the request. The client certificate was exported to a PEM file and the key has a passphrase of "sample_key_password". The code sample below uses PHP to send the client certificate:
$client_cert = dirname(__FILE__).'/sample_cert.cert.pem';
$client_key = dirname(__FILE__).'/sample_cert.key.pem';
$client_key_password = ‘sample_key_password’;
$http_headers[] = 'ping.instanceId: '.$adapter_instance_id;
// PHP can use curl to make the HTTP calls to the pickup endpoint
$crl = curl_init();
// Dropoff URL
curl_setopt($crl, CURLOPT_URL, $dropoff_loc);
curl_setopt($crl, CURLOPT_SSLCERT, $client_cert);
curl_setopt($crl, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($crl, CURLOPT_SSLKEY, $client_key);
curl_setopt($crl, CURLOPT_SSLKEYPASSWD, $client_key_password);
…
$result = curl_exec($crl);
The HTTPS request was changed to use the secondary HTTPS port (9032) of our PingFederate server so our HTTP POST now looks like (the certificate is transported during SSL/TLS negotiation and does not appear in the HTTP request):
POST https://pf.company.com:9032/ext/ref/dropoff HTTP/1.1
Content-Length: 20
Content-Type: application/json
ping.instanceId: sample_adapter
{
"subject":"jsmith"
}
Note: OpenSSL can be used to convert the PKCS12 certificate and key that is exported from the PingFederate administration console to a PEM format:
PEM certificate only:
openssl pkcs12 -in <<certname>>.p12-passin pass:<<pass>> -nokeys -out <<certname>>.cert.pem
PEM key only:
openssl pkcs12 -in <<certname>>.p12 -passin pass:<<pass>> -nocerts -out <<certname>>.key.pem
PEM certificate + key:
openssl pkcs12 -in <<certname>>.p12 -passin pass:<<pass>> -out <<certname>>.certandkey.pem
Any errors during the processing of pick and dropoff requests from PingFederate will be returned as HTTP status codes. For example if an incorrect client ID or password was specified, then a 401 HTTP error would be returned during the pickup / dropoff process.
If an error occurs during an authentication attempt, then the authentication form should handle the error (ie display a message to the user) and abort the SSO process. An application will only receive a sign-in request from a user that was authenticated by the IDP (a failed authentication would not be redirected back to the application). Any errors received during the authentication process should be handled as appropriate knowing the user would have already completed the authentication process at the IDP.
Note: Error screens should be located outside the protected content. When a user receives an error during the sign-in or authorization stages, they need to be able to view the error rather being sent back through the authentication process.
Ensure that the application server and the federation server are both within reasonable close time synchronization. The value of the “Reference Duration” configuration setting can also be used to allow for a larger tolerance for time skew.
The IDP adapter should maintain session for the user so that subsequent calls for authentication can re-use this login session and provide single sign-on for the user.
Note: The IDP adapter should honor the "forceAuthn" parameter to force the user to enter credentials even if the user has an existing session.
Deep linking or direct linking refers to the ability to access a page nested inside the protected content directly without having to navigate through a landing page. A deep link will be received by the application via the “TargetResource” parameter included in the initial redirect to the sign-in URL.
The application should honor this URL during the sign-on process and redirect the user to the deep-link after the application session is created. When recovering from a timeout or other scenario that may require re-authentication, the application should include the requested URL in the request also.
Note: When passing the TargetResource parameter or any URL parameter, be sure to URL-encode the value.
Authorization includes determining whether the user has access to the application and what roles the user has when they are inside the application. The application will receive an already authenticated user and should perform any authorization decisions before creating an application session.
It is important to place any error pages (i.e. “You are not authorized” errors) outside of the protected content area – otherwise you will send the user through an authentication loop as they continually try to authenticate to view the error page.
The application will receive an already authenticated user from a trusted identity provider that can contain additional attributes. This authenticated identity can be used to provision new accounts into the application store or update existing user profile information.