Proxy Connect
With Proxy Connect, PingOne Advanced Identity Cloud provides a way to secure traffic to your tenant environments in seamless compliance with the security controls you apply to your company’s other network resources.
You use Proxy Connect rules to restrict access to a PingOne Advanced Identity Cloud tenant environment based on an IP address range or a required security header. If the request matches any of the rules, Proxy Connect lets the request through. If not, PingOne Advanced Identity Cloud responds with HTTP 404 Not Found. This affects the PingOne Advanced Identity Cloud UIs, too, as Proxy Connect prevents browser requests that don’t follow the rules.
For externally facing applications, Proxy Connect works well with a web application firewall (WAF). A WAF protects against distributed denial-of-service, cross-site scripting, and injection attacks. The WAF isn’t application-specific and so doesn’t make application-specific decisions.
Requests from PingGateway can go through the WAF, but they don’t always need to.
When PingGateway redirects the browser to an end-user UI page, such as the sign-on page, target the WAF. There’s nothing special to do in PingGateway other than redirect to the WAF instead of the tenant. This includes the following use cases, where you let the WAF add the required security header to the browser and PingGateway requests:
-
SSO and CDSSO
-
SAML v2.0
-
OpenID Connect
-
Step-up and transactional authorization where a policy can return advices
When PingGateway uses PingOne Advanced Identity Cloud APIs directly without redirecting the browser, you can skip the WAF. This includes headless interactions that involve direct REST requests, not redirects, where you let PingGateway decorate requests with the required security header:
-
PingGateway as an OAuth 2.0 resource server
-
Using a SessionInfoFilter
-
Using a PolicyEnforcementFilter in an SDK-based client application
-
Using a UserProfileFilter
Goals
The following example builds on the OAuth 2.0 use case.
It shows how to decorate requests to PingOne Advanced Identity Cloud with a security header for Proxy Connect.
Prerequisites
-
Get access as an administrator to a PingOne Advanced Identity Cloud tenant with the Proxy Connect add-on feature.
Wait to add Proxy Connect rules until you have added a route to PingGateway and verified the route works without restrictions.
-
Complete the example installation steps to use PingGateway with PingOne Advanced Identity Cloud.
You don’t need the sample application for this example.
Tasks
Task 1: Configure an OAuth 2.0 profile
Configure an OAuth 2.0 client profile for PingGateway as a resource server:
-
Sign on to the Advanced Identity Cloud admin UI as an administrator.
-
Go to Applications > + Custom Application > OIDC - OpenId Connect > Web and add a web application with the following settings:
- Name
-
oauth2-client
- Owners
-
demo user
- Client Secret
-
password
- Sign On > Grant Types
-
Add
Resource Owner Password Credentials
- Sign On > Scopes
-
Add
mail
Task 2: Configure PingGateway
-
Set an environment variable for the base64-encoded PingGateway agent password.
The following command sets the variable to a base64-encoding of the string
password
.$ export AGENT_SECRET_ID='cGFzc3dvcmQ='
A
SystemAndEnvSecretStore
in the route that follows reads the base64-encoded password. -
Restart PingGateway to reload
admin.json
and access the agent password. -
Add a route for token introspection that decorates requests with the security header.
-
Linux
-
Windows
$HOME/.openig/config/routes/proxy-connect.json
%appdata%\OpenIG\config\routes\proxy-connect.json
Show route
{ "name": "proxy-connect", "condition": "${find(request.uri.path, '^/proxy-connect')}", "properties": { "gatewayUsername": "ig_agent", "gatewayPasswordSecretId": "agent.secret.id", "amServiceUrl": "https://myTenant.forgeblocks.com/am" }, "heap": [ { "name": "SystemAndEnvSecretStore-1", "type": "SystemAndEnvSecretStore" }, { "name": "SecurityHeaderFilter", "type": "HeaderFilter", "config": { "messageType": "REQUEST", "add": { "X-Security-Header": [ "f1drybngmzqj5loposddd5p98z886jp9" ] }, "_comment": "The Proxy Connect rule you configure matches this header." }, "capture": "filtered_request" }, { "name": "AmService-1", "type": "AmService", "config": { "url": "&{amServiceUrl}", "realm": "/alpha", "agent": { "username": "&{gatewayUsername}", "passwordSecretId": "&{gatewayPasswordSecretId}" }, "secretsProvider": "SystemAndEnvSecretStore-1", "amHandler": { "type": "Chain", "config": { "filters": [ "SecurityHeaderFilter" ], "handler": "ForgeRockClientHandler" } }, "notifications": { "_comment": "Avoid UpgradeRejectedException: WebSocket upgrade failure: 404", "enabled": false } } } ], "handler": { "type": "Chain", "config": { "filters": [ { "name": "OAuth2ResourceServerFilter-1", "type": "OAuth2ResourceServerFilter", "config": { "scopes": [ "mail" ], "requireHttps": false, "accessTokenResolver": { "name": "TokenIntrospectionAccessTokenResolver-1", "type": "TokenIntrospectionAccessTokenResolver", "config": { "amService": "AmService-1", "providerHandler": { "type": "Chain", "config": { "filters": [ "SecurityHeaderFilter", { "type": "HttpBasicAuthenticationClientFilter", "config": { "username": "&{gatewayUsername}", "passwordSecretId": "&{gatewayPasswordSecretId}", "secretsProvider": "SystemAndEnvSecretStore-1" } } ], "handler": "ForgeRockClientHandler" } } } } } } ], "handler": { "type": "StaticResponseHandler", "config": { "status": 200, "headers": { "Content-Type": [ "text/html; charset=UTF-8" ] }, "entity": "<html><body><h2>Decoded access_token: ${contexts.oauth2.accessToken.info}</h2></body></html>" } } } } }
jsonSource: proxy-connect.json.
The Proxy Connect route:
-
Matches requests whose path starts with
proxy-connect
. -
Defines a HeaderFilter to add the security header.
The header name and value must match the Proxy Connect header rule you configure. This route uses
f1drybngmzqj5loposddd5p98z886jp9
to match the header rule set in Task 4: Set a Proxy Connect rule. -
Configures an AmService whose requests PingGateway decorates with the security header.
As the service can’t decorate websocket requests for notifications, the configuration disables notifications.
-
Uses a OAuth2ResourceServerFilter with a TokenIntrospectionAccessTokenResolver to introspect access tokens.
-
Adds a StaticResponseHandler to display the results of introspection.
-
-
Update the route’s
amServiceUrl
setting to target the PingOne Advanced Identity Cloud tenant and save your work.PingGateway loads the route.
Task 3: Pre-validation
Before you add Proxy Connect rules to restrict access, verify the route works without restrictions.
-
Get an access token using the resource owner password credentials flow:
$ export ACCESS_TOKEN=$(curl \ --request POST 'https://myTenant.forgeblocks.com/am/oauth2/realms/alpha/access_token' \ --user 'oauth2-client:password' \ --data 'grant_type=password' \ --data 'username=demo' \ --data 'password=Ch4ng3!t' \ --data 'scope=mail' \ --silent | jq -r ".access_token")
You don’t need the security header until you configure a Proxy Connect header rule.
-
Use the route to introspect the access token:
$ curl \ --request GET 'https://ig.example.com:8443/proxy-connect' \ --insecure \ --header "Authorization: Bearer ${ACCESS_TOKEN}"
Output<html><body><h2>Decoded access_token: {active=true, scope=mail, realm=/alpha, client_id=oauth2-client, user_id=<uuid>, username=<uuid>, token_type=Bearer, exp=<seconds>, sub=<uuid>, iss=https://myTenant.forgeblocks.com:443/am/oauth2/realms/root/realms/alpha, subname=<uuid>, auth_level=0, authGrantId=<id>, auditTrackingId=<uuid>, expires_in=<seconds>}</h2></body></html>
Task 4: Set a Proxy Connect rule
Learn about this in the Proxy Connect documentation. Once you understand the steps:
-
Configure a Proxy Connect rule to require the following security header, which is the same one set in the Proxy Connect route configuration:
'X-Security-Header: f1drybngmzqj5loposddd5p98z886jp9'
When you first update the header rules, the change is pending (
"requestStatus": "PENDING"
). PingOne Advanced Identity Cloud doesn’t check for the security header when the update is still pending. -
Poll the Proxy Connection configuration in PingOne Advanced Identity Cloud until the request has
"requestStatus": "SUCCESS"
.Once the request is successful, you can’t use the Advanced Identity Cloud admin UI. Your browser doesn’t add the security header by default.
If you must use the Advanced Identity Cloud admin UI again, either reset the header rules to
{"enabled": false, "headers": []}
or configure your browser to add the security header.
Validation
-
Get an access token using the resource owner password credentials flow:
$ export ACCESS_TOKEN=$(curl \ --request POST 'https://myTenant.forgeblocks.com/am/oauth2/realms/alpha/access_token' \ --user 'oauth2-client:password' \ --data 'grant_type=password' \ --data 'username=demo' \ --data 'password=Ch4ng3!t' \ --data 'scope=mail' \ --header 'X-Security-Header: f1drybngmzqj5loposddd5p98z886jp9' \ --silent | jq -r ".access_token")
-
Use the route to introspect the access token:
$ curl \ --request GET 'https://ig.example.com:8443/proxy-connect' \ --insecure \ --header "Authorization: Bearer ${ACCESS_TOKEN}"
Output<html><body><h2>Decoded access_token: {active=true, scope=mail, realm=/alpha, client_id=oauth2-client, user_id=<uuid>, username=<uuid>, token_type=Bearer, exp=<seconds>, sub=<uuid>, iss=https://myTenant.forgeblocks.com:443/am/oauth2/realms/root/realms/alpha, subname=<uuid>, auth_level=0, authGrantId=<id>, auditTrackingId=<uuid>, expires_in=<seconds>}</h2></body></html>
-
In the PingGateway log, notice the filtered requests have the security header:
[CONTINUED]--- (filtered-request) exchangeId:<uuid> - transactionId:<uuid> ---> [CONTINUED]POST https://myTenant.forgeblocks.com/am/oauth2/realms/root/realms/alpha/introspect HTTP/1.1 [CONTINUED]Accept: application/json [CONTINUED]Content-Length: 918 [CONTINUED]Content-Type: application/x-www-form-urlencoded [CONTINUED]X-Security-Header: f1drybngmzqj5loposddd5p98z886jp9 [CONTINUED]token=<token>&token_type_hint=access_token
Change
"capture"
to"_capture"
in the Proxy Connect route to avoid flooding the PingGateway logs.
You’ve successfully shown how to use PingGateway with Proxy Connect.