PingOne

Samples

Use these sample expressions to build attribute mappings with the PingOne expression builder.

Sample user model

The examples in this section use the following model:

{
  "user": {
    "name": {
      "given": "John",
      "family": "Doe"
    },
    "role": "SA",
    "memberOfGroupNames": ["Admin", "User"],
    "groupDNs": [
      "CN=Devs,CN=Users,DC=malibu,DC=gl,DC=lab",
      "CN=Admins,CN=Users,DC=malibu,DC=gl,DC=lab"
    ]
  }
}
Literal expressions
Expression Result

'FirstName'

FirstName

"User"

User

1

1

true

true

{'USER'}

['USER']

{'firstName': 'John'}

{
    "firstName": "John"
}
String concatenation
Expression Result

'FirstName' + ', ' + 'LastName'

FirstName, LastName

user.name.given + ', ' + user.name.family

John, Doe
Generate a user alias by concatenating parts of first and last name
Expression Result

#string.substring(user.name.given, 0, 1)
#string.substring(user.name.family, 0, 4)

JDoe
Extract the domain name from an email address
Expression Result

#regex.findAllMatches('user01@test.com', '(?⇐@)[^.]+')

[test]
Output the date as a string in a certain format
Expression Result

#datetime.format('2021-01-01T10:15:00Z', 'EEEE, dd MMMM; h:mm a')

Friday, 01 January; 10:15 AM
Replace a value based on a predefined set of options
Expression Result

user.name.given + ' ' + user.name.family + ', ' + \{'PM': 'Product Manager', 'SA': 'Software Architect'}[user.role] ?: 'Unknown'

John Doe, Software Architect
Change the contents of memberOfGroupNames array to upper case
Expression Result

user.memberOfGroupNames.![#string.upperCase(#this)]

[
    "ADMIN",
    "USER"
]
Use string concatenation to transform the contents of memberOfGroupNames array to a group
Expression Result

user.memberOfGroupNames.!['CN=' + #this
',DC=example,DC=com']

[
    "CN=Admin,DC=example,DC=com",
    "CN=User,DC=example,DC=com"
]
Extract group names from an array of group DNs
Expression Result

user.groupDNs.![#regex.replaceAll(#this, '(CN=)(.?),.', '$2')]

[
    "Devs",
    "Admins"
]

Accessing property names with non-alphanumeric characters

If a property name contains any characters other than alpha-numeric characters and underscores (_), use the map access format instead of dot notation.

The examples in this section use the following model:

{
    "providerAttributes": {
        "full-name": "John Doe",
        "http://www.schema.com/samples/userId": "jdoe00",
        "Email Address": "johndoe00@test.com"
    },
    "custom-attributes": {
        "email": "johndoe00@test.com"
    }
}
Property names with hyphens or dashes
Expression Result

providerAttributes['full-name']

John Doe
Properties with URI or URL based names
Expression Result

providerAttributes['http://www.schema.com/samples/userId']

jdoe00
Property names with blank spaces
Expression Result

providerAttributes['Email Address']

johndoe00@test.com
Property roots with hyphens or dashes
Expression Result

#root['custom-attributes'].email

johndoe00@test.com

Sample expression for virtual server IDs

This section outlines how to use an expression to safeguard against misuse of virtual server IDs (VSIDs) between the identity provider (IdP) and the application, which acts as the service provider (SP). VSIDs allow your PingOne environment to identify itself differently for different purposes. You can define VSIDs on the Configuration tab of the SAML application.

When multiple VSIDs are defined in a SAML application, the application has multiple versions of the Initiate Single Sign-On URL, one for each respective VSID. You can obtain the URLs on the Overview tab for the application by selecting the applicable VSID in the Display Virtual Server ID list. Learn more about defining VSIDs in Editing an application - SAML.

Example scenario

You can create a SAML application and define three VSIDs for Who’s at Work (the IdP) and Widget (the SP) for the following purposes:

Development
  • Who’s at Work entity ID: urn:widget:us:whosatwork:sso:dev (VSID #1)

  • Widget entity ID: https://whosatwork.widget.com

Testing
  • Who’s at Work entity ID: urn:widget:us:whosatwork:sso:test (VSID #2)

  • Widget entity ID: https://whosatwork.widget.com

Production
  • Who’s at Work entity ID: https://sso.whosatwork.com (VSID #3, default)

  • Widget entity ID: https://whosatwork.widget.com

When you select one of the VSIDs on the Overview tab for the application, the Initiate Single Sign-On URL changes because the selected VSID is embedded in the URL.

You can use an expression to prevent unauthorized access and ensure only users from a certain department, such as the Engineering department, can connect to Widget (the SP) for development and testing purposes while allowing users from all departments to connect for production use.

When using multiple VSIDs to distinguish groups of users within one environment, such as different PingOne populations, you can add validation rules to make sure one group of users can’t use SSO using the VSID for another group of users. To prevent unauthorized access, you can use the following example expression to fulfill the saml_subject attribute on the Attribute Mappings tab of the application:

 (
 (context.requestData.virtualServerId eq 'urn:widget:us:whosatwork:sso:dev' and
 user.population.id eq '560b3182-c947-4b53-9621-afbe8dbc2488')
 or
 (context.requestData.virtualServerId eq 'urn:widget:us:whosatwork:sso:test' and
 user.population.id eq '560b3182-c947-4b53-9621-afbe8dbc2488')
 or
 (context.requestData.virtualServerId eq 'https://sso.whosatwork.com')
 )? user.username : null

In this example, the expression allows all users to access Widget for production purposes and ensures only users whose PingOne user records are associated with a particular population can access Widget for development and testing purposes. The expression can also be used to validate other conditions, such as group membership.

If one of the conditions is met, PingOne populates the saml_subject attribute with the user’s username in PingOne. If none of the conditions are met, PingOne determines that saml_subject is null and rejects the request. A SAML assertion can’t be generated without this required attribute.