Announcing the Saviynt Knowledge Exchange unifying the Saviynt forums, documentation, training,
and more in a single search tool across platforms. Read the announcement here.

Help Adding to Active Directory multi-valued attribute during provisioning

KenKoch
New Contributor II
New Contributor II

Hello experts! We're trying to configure Active Directory connection to "add" only to a multi-valued proxyAddresses attribute. We do not track the existing proxyAddresses anywhere in Saviynt and thus cannot append to the field. We would like to add only on username changes to verify that the new username@domain is on the AD object. All help is appreciated!  

 
Example for me..
 
EXISTING AD.ProxyAddresses
proxyAddresses: {
SMTP:ken@domain
}
 
I change my email address....
 
ADD THESE ONLY
proxyAddresses: {
smtp:ken@wustl.edu,
SMTP:CHANGED@wustl.edu
}

 

Previous ticket reference, unsolved, was: 1261682

11 REPLIES 11

Darshanjain
Saviynt Employee
Saviynt Employee

Hi @KenKoch 

can you refer the below article,

You need to store the proxy address in some CP value and append as discussed in that article

 

https://forums.saviynt.com/t5/identity-governance/update-proxyaddresses-upon-email-change/m-p/28279

 

Thanks

Darshan

Saathvik
All-Star
All-Star

First you need to pull existing proxy addresses to any of the account CP by using below format in ACCOUNT_ATTRIBUTE mapping. Make sure that CP you have used is of type Longtext to avoid truncation of data.

custompropertyxx::proxyAddresses#String

After that while provisioning you can append the latest email to current list as below

"proxyaddresses":["SMTP:${user.email}","${task?.accountKey.custompropertyxx.replace('SMTP','smtp')}"]

 


Regards,
Saathvik
If this reply answered your question, please Accept As Solution and give Kudos to help others facing similar issue.

KenKoch
New Contributor II
New Contributor II

I follow what you've done, but that isn't a complete solution for me. It's very helpful to know that I can use task.accountKey as a reference point to the account CP though.

In Groovy, here's the entire block of code I would like to run. Is it possible to drop this into a dynamic attribute or inline in the updateAccountJSON?

 

Hi @KenKoch 

This looks like a specific custom code written as per requirement, the exact same cant be applied in saviynt as said above by @Saathvik  and by link,  you can update the proxyaddress.

If the request is via ARS, then possible solution may be write a custom jar and then invoke a sql query to fetch the Proxyaddress via method and see if you can populate the value.

 

Thanks

Darshan 

KenKoch
New Contributor II
New Contributor II

@Saathvik  @Darshanjain 
Thanks for the tips, that got me 99% of the way there. I am stuck due to the AD change map not detecting case sensitive data changes on the multi-value attributes. Any help would be much appreciated! It shows the correct data from my Groovy, but when it builds the change map to flow out there are no changes... the case on the  "smtp" prefix changes though.

In the debug logs I see this, sorted ascending:

2023-07-07/19:45:03.684 [{}] [quartzScheduler_Worker-2] DEBUG ldap.SaviyntGroovyLdapService - DataMap-[proxyAddresses:[SMTP:zeck@uetest.wustl.edu,smtp:zeck@emailtest.wustl.edu]...

2023-07-07/19:45:03.858 [{}] [quartzScheduler_Worker-2] DEBUG ldap.SaviyntGroovyLdapService - LDAP Account Attrs-[proxyaddresses:[smtp:zeck@uetest.wustl.edu, smtp:zeck@emailtest.wustl.edu]...

2023-07-07/19:45:03.861 [{}] [quartzScheduler_Worker-2] DEBUG ldap.SaviyntGroovyLdapService - dataList-[SMTP:zeck@uetest.wustl.edu, smtp:zeck@emailtest.wustl.edu]

2023-07-07/19:45:03.861 [{}] [quartzScheduler_Worker-2] DEBUG ldap.SaviyntGroovyLdapService - values2beAdded (lowercased) = []

2023-07-07/19:45:03.861 [{}] [quartzScheduler_Worker-2] DEBUG ldap.SaviyntGroovyLdapService - dataMapListMap = [smtp:zeck@emailtest.wustl.edu:smtp:zeck@emailtest.wustl.edu, smtp:zeck@uetest.wustl.edu:SMTP:zeck@uetest.wustl.edu]

2023-07-07/19:45:03.861 [{}] [quartzScheduler_Worker-2] DEBUG ldap.SaviyntGroovyLdapService - deleteDataMap = [:]

 

 

 

Here's the code I ended up using in the updateAccountJSON:

"proxyAddresses": [${

String proxyAddresses = task?.accountKey.customproperty56;
String systemUserName = user.systemUserName;
String userEmail = user.email;
String domainName = 'myEmailRoutingDomain';
if (proxyAddresses == null) {proxyAddresses = ''}
proxyAddresses = proxyAddresses.trim();
String primarySMTPAddress = (userEmail != null) ? 'SMTP:' + userEmail.toLowerCase() : 'SMTP:' + systemUserName.toLowerCase() + '@' + domainName.toLowerCase();
String routingSMTPAddress = 'smtp:' + systemUserName.toLowerCase() + '@' + domainName.toLowerCase();

if (!(proxyAddresses.toLowerCase().contains(primarySMTPAddress.toLowerCase()))) {
    proxyAddresses = proxyAddresses + ',' + primarySMTPAddress;
}
if (!(proxyAddresses.toLowerCase().contains(routingSMTPAddress.toLowerCase()))) {
    proxyAddresses = proxyAddresses + ',' + routingSMTPAddress;
}
Set<String> uniqueAddresses = new LinkedHashSet<>();
boolean primaryAddressFound = false;
String[] addressesArray = proxyAddresses.split(',');
for (String address : addressesArray) {
    address = address.trim();
    boolean issmtp = address.toLowerCase().startsWith('smtp:');
    boolean isPrimary = (address.equalsIgnoreCase(primarySMTPAddress));
    if (issmtp && isPrimary && !primaryAddressFound) {
        uniqueAddresses.add(primarySMTPAddress);
        primaryAddressFound = true;
    } else if (issmtp) {
        uniqueAddresses.add(address.toLowerCase());
    } else {
        uniqueAddresses.add(address);
    }
}
StringBuilder formattedAddresses = new StringBuilder();
for (String address : uniqueAddresses) { formattedAddresses.append('"').append(address).append('", '); }
String formattedProxyAddresses = formattedAddresses.toString();
if (formattedProxyAddresses.endsWith(', ')) { formattedProxyAddresses = formattedProxyAddresses.substring(0, formattedProxyAddresses.length() - 2); }
return formattedProxyAddresses;
}]

rushikeshvartak
All-Star
All-Star

"proxyaddresses":["SMTP:${user.email}","${task?.accountKey.customproperty51.replace('SMTP','smtp')}"]

store old proxyAddress in cp51 of account during reconciliation 


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

@rushikeshvartak 

That results in a the CP51 being added as a single value, plus the new value... without the capitalization appropriately implemented. Is there something configured wrong on our multi-value import?

Value in CP51 prior to updateAccount:

KenKoch_0-1688836003428.png

 

After updateAccount in AD actual proxyAddresses:

Value 1: smtp:zeck@uetest.wustl.edu,smtp:zeck@emailtest.wustl.edu
Value 2: smtp:zeck@uetest.wustl.edu

So it removed ? Or override 


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

It used the CP value as a single string in one position of the array, then appended the new value as the second array value but in lowercase instead of the literal SMTP string. 

Can you share with example

before update cp51 

actual expected in target

after in cp51


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

Sure.

account attribute config:

customproperty56::proxyAddresses#String,

PRE-update task
Saviynt account customproperty56 :
  smtp:zeck@emailtest.company.com,smtp:zeck@uetest.company.com

Active Directory proxyAddresses:

  smtp:zeck@emailtest.company.com
  smtp:zeck@uetest.company.com

Expected AD proxyAddresses AFTER update:

  smtp:zeck@emailtest.company.com
  SMTP:zeck@uetest.company.com

POST-update task..
Actual AD proxyAddresses AFTER update:
  smtp:zeck@emailtest.company.comsmtp:zeck@uetest.company.com
  smtp:zeck@uetest.company.com

[This post has been edited by a Moderator to remove sensitive information.]