Handling unmapped fields
Summarize
Summary of Handling unmapped fields
ServiceNow customers can handle unmapped fields during SCIM customization by using various methods to create or update mappings for fields not included in thesysuserandsysusergrouptables. This enables enhanced customization and integration capabilities within the ServiceNow environment.
Show less
Key Features
- SCIM Customization: Admins can create or update SCIM Clients, adding custom scripts in
onBeforeandonAfterscripts to manage unmapped fields. - Scriptable API Access: Use the
snauth.SCIM2Util.getScimProviderCustomizationContext()method to access the SCIM request context and transform attributes in other tables. - Response Customization: Customize responses for GET API calls by extending the
SCIMProviderCustomizationscript, allowing modifications to user and group responses. - Helper Functions: Several functions are available to fetch or set schema values for custom extensions, facilitating easier data manipulation.
Key Outcomes
By implementing these SCIM customization techniques, ServiceNow customers can:
- Effectively manage unmapped fields, ensuring necessary data is captured and utilized within their SCIM integrations.
- Enhance the accuracy and relevance of responses sent back to SCIM clients with custom data, such as user roles and additional attributes.
- Ensure persistence of modified attributes in the SCIM response, improving overall system reliability and data integrity.
You can handle unmapped fields in SCIM customization in different ways.
During SCIM customization, the fields that are not part of the sys_user and sys_user_group tables can be mapped by performing the following functions.
Customize SCIM (Create or Update)
You can create or update the SCIM Client.
- The SCIM admin can add custom scripts in the onBefore and onAfter scripts for fields that are not mapped in ETL Definition or RTE.
- The SCIM admin can override RTE Mappings by adding custom scripts in the onBefore and onAfter scripts.
- You can invoke a scriptable API in the RTE onBefore or onAfter scripts to access incoming request and perform transformations on other tables, lists, and unmapped attributes.
- You can use the
sn_auth.SCIM2Util.getScimProviderCustomizationContext()
method to provide the SCIM request context that contains the
scimResource object. The
scimResource in context represents the following in
each operation:
- POST: The SCIM resource sent in the request payload.
- PUT: The current SCIM resource from database replaced with the SCIM resource sent in thee request payload.
- PATCH: The current SCIM resource from the database after performing the patch operations.
(function onAfter(source, target, importLog) {
var ctx = sn_auth.SCIM2Util.getScimProviderCustomizationContext();
gs.info("scim context ee: " + JSON.stringify(ctx.scimResource));
var roles = ctx.scimResource.roles;
if(roles) {
var removingRolesGR = new GlideRecord("sys_user_has_role");
removingRolesGR.addQuery("user", target.sys_user[0].sys_id);
removingRolesGR.query();
removingRolesGR.deleteMultiple();
for (var i = 0; i < roles.length; i++) {
var addingRolesGR = new GlideRecord("sys_user_has_role");
addingRolesGR.setValue("user", target.sys_user[0].sys_id);
addingRolesGR.setValue("role", roles[i].value);
addingRolesGR.setValue("state", "active");
addingRolesGR.insert();
}
}
var customUserExtn = new global.SCIMProviderCustomization().getCustomExtensionUrn('User');
var salary = ctx.scimResource[customUserExtn].salary;
if (salary) {
var gr = new GlideRecord("u_user_salary");
gr.addQuery("user", target.sys_user[0].sys_id);
gr.query();
if (gr.next()) {
gr.setValue("salary", salary);
gs.info("scim update: " + gr.update());
} else {
gr.setValue("salary", salary);
gr.setValue("user", target.sys_user[0].sys_id);
gr.insert();
}
}
})(source, target, importLog);Customize SCIM response
For the GET API calls, any response back to the SCIM client can be customized using the script by extending the SCIMProviderCustomization script.
While extending the script, the author can override the customizeUserResponse and customizeGroupResponse methods to modify the responses for User and Group resources.
The com.snc.integration.scim2.provider.customization.script.id property enables the SCIM plugin to use the script that should be used for response customization.
var SCIMCustomizationScript = Class.create();
SCIMCustomizationScript.prototype = Object.extendsObject(SCIMProviderCustomization, {
initialize: function() {
SCIMProviderCustomization.prototype.initialize.call(this);
},
customizeUserResponse: function(context) {
try {
var rolesGR = new GlideRecord("sys_user_has_role");
rolesGR.addQuery("user", context.scimResource.id);
rolesGR.query();
var i = 0;
context.scimResource.roles = [];
while (rolesGR.next()) {
context.scimResource.roles[i] = {
display: rolesGR.getElement('role.name').getValue(),
value: rolesGR.getElement('role.sys_id').getValue()
};
i++;
}
var userGR = new GlideRecord("u_user_salary");
userGR.addQuery("user", context.scimResource.id);
userGR.query();
if (userGR.next()) {
var salary = userGR.getValue("salary");
if (salary) {
var customExtensionValue = SCIMProviderCustomization.prototype.getCustomExtensionNodeValue.call(this, "User", context);
customExtensionValue.salary = salary;
SCIMProviderCustomization.prototype.setCustomExtensionNodeValue.call(this, "User", context, customExtensionValue);
}
}
} catch (ex) {
gs.error("err: " + ex);
}
return context;
},
customizeGroupResponse: function(context) {
return context;
},
type: 'SCIMCustomizationScript'
});- The parameter that the customizeUserResponse and customizeGroupResponse methods contain is a context object with one attribute called scimResource. This attribute has all the attributes of a user or group resource object.
- A customized script include can only be created and viewed by the admin.
- If a user or group resource is modified, then you must return the context back.
- If there are no modification of any attribute in the resource object, then set the com.snc.integration.scim2.provider.customization.script.id to empty or return as null.
- If certain attributes are persisted through the onAfter
script, they must be populated with database values in the
scimResource object inside the customized script.
This action is required so that the system can do the following:
- To get the correct scimResource object in onAfter scripts during the PUT and PATCH operation.
- To include the attributes that persisted through the onAfter script in the response back to the client.
Helper functions
The following are some of the helper functions for SCIM customization. These functions enable you to fetch or set different types of information.
| Function | Purpose |
|---|---|
| SCIMProviderCustomization.prototype.getCustomExtensionUrn.call(this, "User"); | Fetch the value of custom extension schema. |
| SCIMProviderCustomization.prototype.getServiceNowExtensionUrn.call(this, "User"); | Fetch the value of the ServiceNow extension schema. |
| SCIMProviderCustomization.prototype.getCustomExtensionNodeValue.call(this, "User", context); | Fetch the custom schema node from the response. |
| SCIMProviderCustomization.prototype.getServiceNowExtensionNodeValue.call(this, "User", context); | Fetch the ServiceNow schema node from the response |
| SCIMProviderCustomization.prototype.setCustomExtensionNodeValue.call(this, "User", context, customExtensionValue); | Set the custom schema node in the response. |
var customExtensionUrn =
SCIMProviderCustomization.prototype.getCustomExtensionUrn.call(this, "User");
var customExtensionValue =
SCIMProviderCustomization.prototype.getCustomExtensionNodeValue.call(this, "User", context);
customExtensionValue.age = "18";
SCIMProviderCustomization.prototype.setCustomExtensionNodeValue call(this, "User", context, customExtensionValue);