Writing a Custom SAML Script

You can write SAML response scripts in JavaScript in the Custom Logic area of the SAML Response page of a SAML application.

alt

The custom SAML script specifies elements that must be present in the SAML assertion used to start the current user session with a web application. To write the script, you must know what SAML elements the web application requires. The script must retrieve required information from the web application’s profile and the user object, and must then specify the SAML elements and their values using assertion-set methods. After the script executes, the Privileged Access Service follows the script’s specifications to create a SAML assertion and its enclosing SAML response.

A SAML script is required for each application profile created using the custom SAML application template. To see examples of SAML scripts used to connect to web services, open the application profile for any SAML application in the Apps panel of Admin Portal. Click the SAML Response tab to see the application’s SAML script.

To assist with writing SAML response scripts, the SAML Script Editor includes a context-sensitive autocomplete feature.

Determining SAML requirements for the web application

Each SAML web application typically requires its own set of SAML elements in a SAML assertion. Although many of the elements will be the same from application to application, there are enough variations that one script won’t cover all applications.

To write a script for a SAML web application, you must find out from the application’s publishers what its SAML requirements are. If the application is a large public application, its publishers may present their SAML requirements on their web site. As an example, Salesforce publishes SAML requirements for authentication here. Most large public SAML web applications, however, will probably already be in the app catalog so you won’t need to add them via the generic SAML application template.

For web applications that don’t provide their SAML requirements publicly, you’ll have to contact technical support or their development team to ask about their SAML requirements. This requires some familiarity with SAML. Reading through a public SAML application’s SAML requirements (such as Salesforce’s requirements) is a good start to understanding what a typical SAML application requires.

Retrieving information

The custom SAML script has access to the same JavaScript objects, global methods, and global variables that the user map script has along with some additional application-set methods used to specify SAML elements. To retrieve application and user information, use the Application and LoginUser objects that the Privileged Access Service creates for a user session.

Application object

The Privileged Access Service creates a single Application object for each SAML user session. The object is an instance of the ReadOnlyDataEntity class, and is a read-only object.

The Application object’s properties describe the SAML web application as it’s defined in the application profile. Create a SAML web application profile in the Admin Portal using the customSAML application template (described in Custom SAML Applications.

A script accesses the object’s properties using the object’s single public function.

Function Name Description
Application.Get(*property*) This function returns an Application object property. It takes as its argument a string that specifies the property to return. An example: Application.Get(“Name”) returns the name of the application as entered in the Application Settings tab.

The Application.Get() function may take the following property names as an argument. Each argument returns a different application property. The property names are case-sensitive.

Property Name Description
\_PartitionKey The customer ID used to establish the user session. An example: BZ284.
\_RowKey The UUID (universally unique identifier) of the application.
Description The text description of the web application entered in the description field of the Application Settings tab.
Icon The graphic file used as the icon for this application as set in the Application Settings tab.
Issuer The entity ID specified in the Issuer field of the Application Settings tab. Synonymous with the global variable Issuer.
Name The name of the application as entered in the Application Settings tab.
SamlScript The custom SAML script set in the Advanced tab.
TemplateName The type of generic application template used to define this web application’s profile. Possible return values: Generic SAML Generic User-Password
Url The contact URL specified in the URL field in the Application Settings tab. Synonymous with the global variable ServiceUrl.
UserName Strategy The technique specified in the Application Settings tab to determine the user name (user identity) for a user session. Possible return values: ADAttribute: the Privileged Access Service sets the user name to the specified AD attribute of the current user. The Privileged Access Service queries the connector for the AD attribute. The Privileged Access Service caches the user name so that it doesn’t have to query the connector for this user’s future sessions. Fixed: the Privileged Access Service sets the user name to the value entered in the Application Settings tab. UseScript: the Privileged Access Service executes the user map script to determine the user name.
WebAppType The authentication function used by the web application. Possible return values: SAML UsernamePassword

LoginUser object

The Privileged Access Service creates a single LoginUser object for each SAML user session. The object is an instance of the LoginUser class, and is a read/write object.

The function LoginUser.Get() retrieves any one of the current user’s attributes. It takes as its argument a string that specifies the key of the attribute to retrieve. LoginUser.Get(“mail”), for example, returns the user’s email address as stored in Active Directory.

When LoginUser.Get() executes, the Privileged Access Service contacts the source directory through the connector for the user’s organization and retrieves the attribute. If, for example, an Active Directory user has logged into the Admin Portal as a member of the Acme organization, executing LoginUser.Get() during one of that user’s log-on sessions contacts the Acme Active Directory service through the connector set up in Acme’s internal network. If a user has logged in, executing LoginUser.Get() queries the Cloud Directory Service (CDS).

Not all attributes are common between directory services. If you have uses managed by different directory services (for example, AD and LDAP), use the LoginUser.ServiceType or Login.User.ServiceName properties to determine the user’s source directory and then get the appropriate attribute key. Refer to LoginUser Object for more information.

Example

Copy
if(LoginUser.ServiceType == 'LDAPProxy'){

UserIdentifier = LoginUser.Get('uid');

} else {

UserIdentifier = LoginUser.Username;

}

Explanation

The preceding example checks to see if the user is managed by LDAP. If the user’s service type is LDAPProxy, the script gets the current user’s UID attribute, otherwise it uses the LoginUser.Username property.

The LoginUser object has the following methods:

Function name Description
LoginUser.Get(ADkey) This function returns any one of the current user’s Active Directory attributes. It takes as its argument a string that specifies the key of the attribute to retrieve. An example: LoginUser.Get(“mail”) returns the user’s email address as stored in the user’s Active Directory account.
LoginUser.GetValues(ADkey) This function returns an array with all values of an Active Directory attribute with multiple values for the current user. It takes as its argument a string that specifies the key of the attribute to retrieve. For example, the line setAttributeArray('proxies', LoginUser.GetValues('proxyAddresses')); sets an attribute array named proxies that includes all values for the logged in user for the AD key proxyAddresses.
LoginUser.GetGroupAttributeValues(ADkey) This function returns the values of the current user's groups specified AD attribute. It takes as its argument a string that specifies the key of the attribute to retrieve. An example: LoginUser.GetGroupAttributeValues(“sAMAccountName”) returns the user’s groups sAMAccountName value as stored in the user’s Active Directory account.

The LoginUser object’s properties describe the user as he or she is presented to the web application. The following table describes those properties.

Property name Description
LoginUser.Username The user identity presented in the SAML assertion to the web application. The Privileged Access Service determines the user ID for this user session depending on the “Map to User Accounts” setting in the Application Settings tab. (These settings determine the user name, which is the user ID presented in the SAML assertion.)
LoginUser.FirstName The first name of the user presented in the SAML assertion to the web application. Note the following special cases for parsing this attribute for users in directory services that do not have the FirstName attribute, such as Delinea Directory: FirstName attribute is parsed from the first string of DisplayName. If DisplayName is a single string, the same string is used for the FirstName and LastName attributes. If DisplayName is null, FirstName and LastName return as null. SAML apps that require non-empty values will fail to launch in this case.
LoginUser.LastName The last name of the user presented in the SAML assertion to the web application. Note the following special cases for parsing this attribute for users in directory services that do not have the LastName attribute, such as Centrify Directory: The LastName attribute is parsed from the last string of DisplayName. Any additional strings between the first string and the last string are ignored. If DisplayName is a single string, the same string is used for the FirstName and LastName attributes. If DisplayName is null, FirstName and LastName return as null. SAML apps that require non-empty values will fail to launch in this case.
LoginUser.GroupNames An array of group names for groups in which the user is an effective member (according to the user’s Active Directory account). A user is an effective member of a group if he is either a direct member of the group or is a direct member of a group that is in turn a member of the group. This property returns the same value as LoginUser.EffectiveGroupNames.
LoginUser.GroupNames2 An array of group names for groups in which the user is an effective member (according to the user’s Active Directory account), returning only the user’s group’ ‘name attribute.
LoginUser.RoleNames An array of Privileged Access Service role names for roles in which the user is a member. The following example illustrates how to set an array named "Groups" that includes the Delinea roles that the logged in user is a member of. setAttributeArray("Group", LoginUser.RoleNames);
LoginUser.EffectiveGroupNames An array of group names for groups in which the user is an effective member (according to the user’s Active Directory account). A user is an effective member of a group if he is either a direct member of the group or is a direct member of a group that is in turn a member of the group. This property returns the same value as LoginUser.GroupNames.
LoginUser.GroupDNs An array of distinguished names of groups in which the user is an effective member. This property returns the same value as LoginUser.EffectiveGroupDNs.
LoginUser.EffectiveGroupDNs An array of distinguished names of groups in which the user is an effective member. This property returns the same value as LoginUser.GroupDNs.
LoginUser.ServiceType The type of directory service managing the user’s user object. Possible values are: ADProxy LDAPProxy CDS (Cloud Directory Service) FDS (Federated Directory Service)
LoginUser.ServiceName The name of the directory service managing the user’s user object. These values are set by the network administrator. This property is useful in environments with more than one LDAP proxy.

Specifying SAML assertion elements

The Privileged Access Service offers a group of global assertion-set methods in a user session. These methods set the attributes of the private assertion object, which specifies how the Privileged Access Service will construct the SAML assertion for this user session. Most of these methods take as an argument the value for a specific SAML assertion element. setIssuer(), for example, accepts an entity ID and uses it to specify the issuer URL in the SAML assertion.

Two of the assertion-set methods, setAttribute() and setAttributeArray(), specify a SAML response attribute by name and then specify a value for that attribute that is either a single argument or an array.

The following table lists the most commonly used assertion-set methods. Global Methods describes these methods in full.

global Function Description
setVersion(*samlVersion*) Specifies the version of the SAML assertion. “1” specifies version 1.1, “2” specifies version 2.0. The default is 2 if this function isn’t present in the script.
setIssuer(*issuer*) Specifies the issuer in the SAML assertion. Typically a URL provided by retrieving the Application property Issuer or by using the property’s synonymous variable Issuer.
setSubjectName(*username*) Specifies the subject in the SAML assertion, which is the log-on name used for the web application. It’s typically provided by retrieving the LoginUser.Username property or by using the property’s synonymous variable UserIdentifier. If you have multiple directory sources, use the LoginUser.ServiceName or LoginUser.ServiceType properties to set an appropriate subject name. For example: if(LoginUser.ServiceType == 'LDAPProxy'){ setSubjectName(LoginUser.Get('uid')); } else { setSubjectName(LoginUser.Username); }
setAudience(*audience*) Specifies the audience in an audience restriction in the SAML assertion. This typically takes the entityIDURL such as “https://login/myapp.com".
setRecipient(*recipient*) Specifies the recipient in the SAML assertion’s SubjectConfirmationData element. This typically takes the ACS/entityID URL such as "https://login/myapp.com”.
setSignatureType(*signingPref*) Specifies whether the SAML assertion should be signed, or the SAML response that contains the assertion. The two possible values are “Response” or “Assertion”. The default is “Response” if this function isn’t present in the script.
setServiceUrl(*targetUrl*) Specifies the value for the TARGET form element (the resource requested for the user session) when posting the SAML response. This is typically a URL that is the same as that used for the setHttpDestination() function, typically retrieved through the Application property Url or by using the property’s synonymous variable ServiceUrl.
setHttpDestination(*responseUrl*) Specifies the URL to which to post the SAML response in the response’s HTTP POST binding (the value in the “action=” argument). Typically a URL provided by retrieving the Application property Url or by using the property’s synonymous variable ServiceUrl. You can repeat this assertion-set function at the end of the script using a string to specify an absolute URI if you want to post the SAML response to a specific address, such as a proxy provided by a cloud access security broker (CASB).
setDigestMethodAlgorithm(*'algorithm'*) setDigestMethodAlgorithmspecifies the digest method algorithm to use in the SAML response. Possible values are: sha1 sha256 sha384 sha512 The default value is the same as the SignatureMethod algorithm for the signing certificate selected for the app. For example, setDigestMethodAlgorithm('sha256').
setAttribute(*elementName, elementValue*) This function is needed if the service provider requires a specific value, such as email, to be passed within the SAML assertion. Takes two arguments. The first is a string that specifies the name of a SAML response attribute to set, the second specifies the attribute value. For example, setAttribute(“Email”, LoginUser.Get(“mail”)); specifies the SAML attribute named “Email” to be set to the current user’s email address.
Note: Because Javascript treats the \ (backslash) character as an escape character, if you want to use a \ in your elementValue, you must precede it with another \. For example, if you want to use an elementValue of string "DOMAIN\user" in a SAML response attribute named "exampleAttr", you write: setAttribute("exampleAttr", "DOMAIN\\\\user");
setAttributeArray(*elementName, elementArray*) Takes two arguments. The first is a string that specifies the name of a SAML response attribute to set, the second specifies an array as the attribute value. For example, setAttributeArray('Groups', LoginUser.GroupNames); specifies the SAML attribute named “Groups” to be set to an array of group names in which the current user is a direct member.
Note: Because Javascript treats the \ (backslash) character as an escape character, if you want to use a \ in an elementValue in the elementArray, you must precede it with another \.

To enable autocomplete suggestions in the SAML Script Editor

  1. In the SAML Script Editor, press Ctrl+Spacebar.

    A menu appears showing available functions.

  2. Use the arrow keys to select from available options, then press Enter to select the option.

    Note the help text that appears with each selection.

    In addition, each available selection is coded based on type. For example:

    • F: Function

    • S: String

    • O: Object

  3. Continue editing the script, using Ctrl+Spacebar as necessary for suggestions.

    If you have already entered most of the function and only one possibility remains, Ctrl+Spacebar completes the string rather than showing available choices.

To enter a custom SAML script in the SAML Response page

  1. Scroll down to the Custom Logic area and click in the SAML Script Editor where you want to edit the script.

  2. Enter the SAML script in the text panel, replacing the existing script or using it as a template script.

    Remember that you can press Ctrl + Spacebar to enable the autocomplete feature. In addition, Script Help showing available methods, objects, and variables is available to the right of the Script Editor.

    Incorrect JavaScript syntax in a line triggers a yellow symbol before the line number. Although the text panel offers this simple JavaScript support, if you’re writing a script of any length you may want to use a specialized JavaScript editor and paste the results into the text panel.

    The template script present in the text panel by default will not work as a custom SAML script. You must modify or replace the script to meet the specific requirements of the web application.
  3. (Optional) Click Preview SAML Response, then select a user to preview the results of the script for that user.

    The Preview SAML Response window opens showing SSO Token details and the results of a trace of the script. The SSO token is generated by the Admin Portal for the user to log in to the web application.

  4. Click Save .

    Read Custom SAML Applications for more information about using the generic SAML application template.