Enable OpenID Connect-based single sign-on (SSO) for applications proxied by NGINX Plus, using Ping Identity as the identity provider (IdP).
This guide explains how to enable single sign-on (SSO) for applications being proxied by F5 NGINX Plus. The solution uses OpenID Connect as the authentication mechanism, with Ping Identity (PingFederate or PingOne) as the Identity Provider (IdP), and NGINX Plus as the Relying Party.
Prerequisites
Section titled “Prerequisites”-
PingFederate Enterprise Federation Server or PingOne Cloud deployment with a Ping Identity account.
-
An NGINX Plus subscription and NGINX Plus Release 36 or later. For installation instructions, see Installing NGINX Plus.
-
A domain name pointing to your NGINX Plus instance, for example,
demo.example.com.
Configure PingFederate or PingOne for Enterprise
Section titled “Configure PingFederate or PingOne for Enterprise”Create a new application for NGINX Plus:
-
Log in to your Ping Identity admin console.
-
Go to Applications > Applications.
-
Click the + (plus) symbol to create a new OIDC Application.
-
On the New Application screen:
-
Enter the Name of your application, for example,
nginx-demo-app. -
Select the Application Type OIDC Web App.
-
Select Save.
-
-
In your OIDC application, Select the Overview tab:
-
in the General section, copy your Client ID and Client Secret values. You will need then later when configuring NGINX Plus.
-
In the Connection Details section, copy your Issuer ID. You will need it later when configuring NGINX Plus.
For PingOne Cloud, the Issuer ID generally structured as
https://auth.pingone.com/<environment_id>/as.For PingFederate, the Issuer ID generally structured as
https://pingfederate.example.com:9031appended with the realm path of your environment.
-
-
On the Configuration tab of your OIDC application:
- In the Redirect URIs field, add the NGINX Plus callback URI, for example:
https://demo.example.com/oidc_callback.- In the Post Logout Redirect URIs field, add the post logout redirect URI, for example:
https://demo.example.com/post_logout/.- Select Save.
-
Assign the application to the appropriate Groups or Users who will be allowed to log in.
Enable Front-Channel Logout (optional)
Section titled “Enable Front-Channel Logout (optional)”Front-channel logout allows Ping Identity to notify NGINX Plus when a user signs out of other Single Logout (SLO)-participating applications or from their Ping portal. Ping sends a front-channel HTTP request (typically loaded in a hidden iframe) to a logout URL that you configure in the application settings.
This feature is optional and requires NGINX Plus Release 36 or later, together with the frontchannel_logout_uri directive in the NGINX OIDC provider configuration.
-
In the Ping Identity admin console, open the OIDC application that you created earlier (for example,
nginx-demo-app). -
Locate the Front-channel logout or Single Logout settings for the application. In PingOne, these are available under the Configuration or Policies sections; in PingFederate they are available in the OAuth / OIDC application connection settings. The exact location and labels can vary between product versions.
-
Configure the front-channel logout URL to point to the NGINX Plus front-channel logout endpoint, for example:
https://demo.example.com/front_logout -
Ensure that the front-channel logout request includes both the issuer (
iss) and the session identifier (sid) as query parameters, in accordance with the OpenID Connect front-channel logout specification. If your Ping Identity admin console exposes an option to include session details or send session ID and issuer in logout requests, enable it. -
Save the application configuration.
Get the OpenID Connect Discovery URL
Section titled “Get the OpenID Connect Discovery URL”Check the OpenID Connect Discovery URL. By default, Ping Identity publishes the .well-known/openid-configuration document at the following address:
For PingOne: https://auth.pingone.com/<environment_id>/as/.well-known/openid-configuration
For PingFederate: https://pingfederate.example.com:9031/<realm_path>/.well-known/openid-configuration
-
Run the following
curlcommand in a terminal:Terminal window curl https://auth.pingone.com/<environment_id>/as/.well-known/openid-configuration | jqWhere:
-
the
auth.pingone.comis your PingOne server address (or your PingFederate server for on-premises) -
the
<environment_id>is your PingOne environment ID -
the
/asis the authorization server path -
the
/.well-known/openid-configurationis the default address for Ping Identity for document location -
the
jqcommand (optional) is used to format the JSON output for easier reading and requires the jq JSON processor to be installed.
The configuration metadata is returned in the JSON format:
-
-
Copy the issuer value, you will need it later when configuring NGINX Plus. Typically, the OpenID Connect Issuer for PingOne is
https://auth.pingone.com/<environment_id>/as.
Set up NGINX Plus
Section titled “Set up NGINX Plus”With PingOne or PingFederate configured, you can enable OIDC on NGINX Plus. NGINX Plus serves as the Rely Party (RP) application — a client service that verifies user identity.
-
Ensure that you are using the latest version of NGINX Plus by running the
nginx -vcommand in a terminal:Terminal window nginx -vThe output should match NGINX Plus Release 36 or later:
nginx version: nginx/1.29.3 (nginx-plus-r36) -
Ensure that you have the values of the Client ID, Client Secret, and Issuer obtained during PingOne or PingFederate Configuration.
-
In your preferred text editor, open the NGINX configuration file (
/etc/nginx/nginx.conffor Linux or/usr/local/etc/nginx/nginx.conffor FreeBSD). -
In the
http {}context, make sure your public DNS resolver is specified with theresolverdirective: By default, NGINX Plus re‑resolves DNS records at the frequency specified by time‑to‑live (TTL) in the record, but you can override the TTL value with thevalidparameter:http {resolver 10.0.0.1 ipv4=on valid=300s;# ...} -
In the
http {}context, define the PingOne or PingFederate provider namedpingby specifying theoidc_provider {}context:http {resolver 10.0.0.1 ipv4=on valid=300s;oidc_provider ping {# ...}# ...} -
In the
oidc_provider {}context, specify:-
your actual Ping Client ID obtained in Ping Configuration with the
client_iddirective -
your Client Secret obtained in Ping Configuration with the
client_secretdirective -
the Issuer URL obtained in Ping Configuration with the
issuerdirectiveThe
issueris typically your Ping Identity OIDC URL.For PingOne Cloud, the URL is
https://auth.pingone.com/<environment_id>/as.For PingFederate, the URL is
https://pingfederate.example.com:9031followed by your environment’s realm path.By default, NGINX Plus creates the OpenID metadata URL by appending the
/.well-known/openid-configurationpart to the Issuer URL. If your metadata URL is different, you can explicitly specify the metadata document with theconfig_urldirective. -
The logout_uri is URI that a user visits to start an RP‑initiated logout flow.
-
The post_logout_uri is absolute HTTPS URL where Ping Identity should redirect the user after a successful logout. This value must also be configured in the Ping Identity application’s Post Logout Redirect URIs.
-
If the logout_token_hint directive set to
on, NGINX Plus sends the user’s ID token as a hint to Ping Identity. This directive is required by PingOne. -
The frontchannel_logout_uri directive defines the URI that receives OpenID Connect front-channel logout requests from Ping Identity. This URI must be an HTTPS path and must match the front-channel logout URL configured for the application in Ping Identity. When Ping sends a front-channel logout GET request (typically via a hidden iframe) to this URI with the
issandsidquery parameters, the OIDC module clears the corresponding user session on NGINX Plus. -
If the userinfo directive is set to
on, NGINX Plus will fetch userinfo from Ping Identity and append the claims from userinfo to the$oidc_claims_variables. -
PKCE (Proof Key for Code Exchange) is automatically enabled when the provider’s OpenID Connect discovery document advertises the
S256code challenge method in thecode_challenge_methods_supportedfield. You can override this behavior with thepkcedirective: setpkce off;to disable PKCE even whenS256is advertised, orpkce on;to force PKCE even if the IdP’s metadata does not listS256. -
The OIDC module automatically selects the client authentication method for the token endpoint based on the provider metadata
token_endpoint_auth_methods_supported. When onlyclient_secret_postis advertised, NGINX Plus uses theclient_secret_postmethod and sends the client credentials in the POST body. When bothclient_secret_basicandclient_secret_postare present, the module prefers HTTP Basic (client_secret_basic), which remains the default for Ping Identity.
-
All interaction with the IdP is secured exclusively over SSL/TLS, so NGINX must trust the certificate presented by the IdP. By default, this trust is validated against your system’s CA bundle (the default CA store for your Linux or FreeBSD distribution). If the IdP’s certificate is not included in the system CA bundle, you can explicitly specify a trusted certificate or chain with the ssl_trusted_certificate directive so that NGINX can validate and trust the IdP’s certificate.
:::
```nginxhttp { resolver 10.0.0.1 ipv4=on valid=300s;
oidc_provider ping { issuer https://auth.pingone.com/<environment_id>/as; client_id <client_id>; client_secret <client_secret>; logout_uri /logout; logout_token_hint on; post_logout_uri https://demo.example.com/post_logout/; frontchannel_logout_uri /front_logout; userinfo on;
# Optional: PKCE configuration. By default, PKCE is automatically # enabled when the IdP advertises the S256 code challenge method. # pkce on; }
# ...}```7. Make sure you have configured a server that corresponds to demo.example.com, and there is a location that points to your application (see Step 10) at http://127.0.0.1:8080 that is going to be OIDC-protected:
```nginxhttp {
# ...
server { listen 443 ssl; server_name demo.example.com;
ssl_certificate /etc/ssl/certs/fullchain.pem; ssl_certificate_key /etc/ssl/private/key.pem;
location / { # ...
proxy_pass http://127.0.0.1:8080; } } # ...}```8. Protect this location with Ping Identity OIDC by specifying the auth_oidc directive that will point to the ping configuration specified in the oidc_provider {} context in Step 5:
```nginx# ...location / { auth_oidc ping;
# ...
proxy_pass http://127.0.0.1:8080;}# ...```9. Pass the OIDC claims as headers to the application (Step 10) with the proxy_set_header directive. These claims are extracted from the ID token returned by Ping:
- [`$oidc_claim_sub`](https://nginx.org/en/docs/http/ngx_http_oidc_module.html#var_oidc_claim_) - a unique `Subject` identifier assigned for each user by Ping Identity
- [`$oidc_claim_email`](https://nginx.org/en/docs/http/ngx_http_oidc_module.html#var_oidc_claim_) - the e-mail address of the user
- [`$oidc_claim_name`](https://nginx.org/en/docs/http/ngx_http_oidc_module.html#var_oidc_claim_) - the full name of the user
- any other OIDC claim using the [`$oidc_claim_ `](https://nginx.org/en/docs/http/ngx_http_oidc_module.html#var_oidc_claim_) variable
:::noteEnsure the openid, profile, email Scopes are enabled in Ping Identity.
:::
```nginx# ...location / { auth_oidc ping;
proxy_set_header sub $oidc_claim_sub; proxy_set_header email $oidc_claim_email; proxy_set_header name $oidc_claim_name;
proxy_pass http://127.0.0.1:8080;}# ...```
<span id="oidc_app"></span>10. Provide endpoint for completing logout:
```nginx# ...location /post_logout/ { return 200 "You have been logged out.\n"; default_type text/plain;}# ...```11. Create a simple test application referenced by the proxy_pass directive which returns the authenticated user’s full name and email upon successful authentication:
```nginx# ...server { listen 8080;
location / { return 200 "Hello, $http_name!\nEmail: $http_email\nPing Identity sub: $http_sub\n"; default_type text/plain; }}```12. Save the NGINX configuration file and reload the configuration:
```nginxnginx -s reload```Complete Example
Section titled “Complete Example”This configuration example summarizes the steps outlined above. It includes only essential settings such as specifying the DNS resolver, defining the OIDC provider, configuring SSL, and proxying requests to an internal server.
http { # Use a public DNS resolver for Issuer discovery, etc. resolver 10.0.0.1 ipv4=on valid=300s;
oidc_provider ping { # The issuer is typically something like: # https://auth.pingone.com/<environment_id>/as issuer https://auth.pingone.com/<environment_id>/as;
# Your Ping Identity Client ID and Secret client_id <client_id>; client_secret <client_secret>;
# RP‑initiated logout logout_uri /logout; post_logout_uri https://demo.example.com/post_logout/; logout_token_hint on;
# Front-channel logout (OP‑initiated single sign-out) frontchannel_logout_uri /front_logout;
# Fetch userinfo claims userinfo on;
# Optional: PKCE configuration (enabled automatically when supported by the IdP) # pkce on; }
server { listen 443 ssl; server_name demo.example.com;
ssl_certificate /etc/ssl/certs/fullchain.pem; ssl_certificate_key /etc/ssl/private/key.pem;
location / { # Enforce OIDC with Ping Identity auth_oidc ping;
# Forward OIDC claims as headers if desired proxy_set_header sub $oidc_claim_sub; proxy_set_header email $oidc_claim_email; proxy_set_header name $oidc_claim_name;
proxy_pass http://127.0.0.1:8080; }
location /post_logout/ { return 200 "You have been logged out.\n"; default_type text/plain; } }
server { # Simple test upstream server listen 8080;
location / { return 200 "Hello, $http_name!\nEmail: $http_email\nPing Identity sub: $http_sub\n"; default_type text/plain; } }}Testing
Section titled “Testing”-
Open
https://demo.example.com/in a browser. You will be automatically redirected to the PingOne sign-in page. -
Enter valid Ping Identity credentials of a user who has access the application. Upon successful sign-in, PingOne redirects you back to NGINX Plus, and you will see the proxied application content (for example, “Hello, Jane Doe!”).
-
Navigate to
https://demo.example.com/logout. NGINX Plus initiates an RP‑initiated logout; Ping Identity ends the session and redirects back tohttps://demo.example.com/post_logout/. -
Refresh
https://demo.example.com/again. You should be redirected to Ping Identity for a fresh sign‑in, proving the session has been terminated.
Legacy njs-based Ping Identity Solution
Section titled “Legacy njs-based Ping Identity Solution”If you are running NGINX Plus R33 and earlier or if you still need the njs-based solution, refer to the Legacy njs-based Ping Identity Guide for details. The solution uses the nginx-openid-connect GitHub repository and NGINX JavaScript files.
See Also
Section titled “See Also”Revision History
Section titled “Revision History”-
Version 3 (November 2025) – Updated for NGINX Plus R36; added front-channel logout support (
frontchannel_logout_uri), PKCE configuration (pkcedirective), and theclient_secret_posttoken endpoint authentication method. -
Version 2 (August 2025) – Updated for NGINX Plus R35; added RP‑initiated logout (
logout_uri,post_logout_uri,logout_token_hint) anduserinfosupport. -
Version 1 (March 2025) – Initial version for NGINX Plus Release 34.