Azure AD
The sections, below describe how to import Groups and Users from Azure AD. As with all synchronization / import processes, you will have to:
- Develop this script and deploy it using the Groovy manager in the Webconsole
- Configure a synchronization task to execute the script
Import Groups
The script below shows how groups from Azure can be added to the OpenIAM system. Note, that this step does not add users to groups. This is performed in the next step. To use this script, you will need to define the synchronization configuration which will execute this script.
import org.openiam.base.AttributeOperationEnumimport org.openiam.idm.srvc.grp.dto.Groupimport org.openiam.idm.srvc.grp.dto.GroupAttributeimport org.openiam.idm.srvc.synch.dto.LineObjectimport org.openiam.sync.service.impl.service.AbstractGroupTransformScriptclass SubscriptionsToGroupsTransformationScript extends AbstractGroupTransformScript {@Overrideint execute(LineObject rowObj, Group group) {return SKIP/* println "** - Group Transformation script called."try {populateObject(rowObj, group)} catch (Exception ex) {ex.printStackTrace();println "** - Transformation script error."return -1;}println "** - Transformation script completed."return NO_DELETE*/}private void populateObject(LineObject rowObj, Group group) {def columnMap = rowObj.columnMapif (isNewUser) {group.id = null}group.name = columnMap.get("Name")?.valuegroup.policyId = "4000"group.status = "ACTIVE"def type = columnMap.get("Type")?.valueString mdTypeId = null;group.setMdTypeId(mdTypeId)addAttribute(group, "Id", columnMap.get("Id")?.value);addAttribute(group, "Location", columnMap.get("Location")?.value);addAttribute(group, "ResourceGroupName", columnMap.get("ResourceGroupName")?.value);}private void addAttribute(Group g, String name, String value) {GroupAttribute gap = g.getAttributes()?.find({ name.equalsIgnoreCase(it.name) });if (gap) {if (!gap.getValues()?.any { value.equalsIgnoreCase(it) }) {gap.getValues()?.clear();gap.addValue(value);gap.operation = AttributeOperationEnum.REPLACE;}} else {if (!g.getAttributes()) {g.setAttributes(new HashSet<GroupAttribute>());}GroupAttribute ga = new GroupAttribute();ga.setGroupId(g.getId());ga.addValue(value);ga.setName(name);ga.setOperation(AttributeOperationEnum.ADD);g.getAttributes().add(ga);}}@Overridevoid init() {}}
Import users
Groovy script
Select attributes to import
First define a script which will itemize the attributes that you need to sync. This will determine which attributes will be sent back by the Azure AD connector. You should adjust this script to contain on the attributes that are relevant for you. This will be used in your synchronization configuration.
import org.openiam.sync.service.AttributesScriptclass AzureUserSyncAttributes implements AttributesScript {@OverrideString[] getAttributes() {return ["ObjectId", "DisplayName", "ImmutableId","SignInName","Microsoft.Compute/virtualMachines","WhenCreated","Enabled","PasswordNeverExpires","LastPasswordChangeTimestamp",// "Microsoft.Sql/servers",// "Microsoft.Network/networkWatchers",// "Microsoft.Compute/disks",// "Microsoft.Network/networkInterfaces",// "Microsoft.Network/networkSecurityGroups",// "Microsoft.Network/publicIPAddresses",// "Microsoft.Network/virtualNetworks",// "Microsoft.Web/sites",// "Microsoft.Storage/storageAccounts",// "Microsoft.Logic/workflows","LastName", "FirstName", "memberOf","members","CN", "SingInName","cn", "sn", "givenName", "sAMAccountName", "dn","Description","DistinguishedName", "modifyTimestamp", "createTimestamp","mail", "userPrincipalName"] as String[];}}
Map the Azure attributes to OpenIAM
Next, you will need to define a synch process which will map the attributes being sent back by the connector to objects within OpenIAM.
import org.apache.commons.collections.CollectionUtilsimport org.openiam.base.AttributeOperationEnumimport org.openiam.common.beans.mq.LoginMQServiceimport org.openiam.idm.srvc.auth.dto.Loginimport org.openiam.idm.srvc.auth.dto.LoginAttributeimport org.openiam.idm.srvc.continfo.dto.EmailAddressimport org.openiam.idm.srvc.synch.dto.LineObjectimport org.openiam.idm.srvc.user.dto.UserAttributeimport org.openiam.provision.dto.ProvisionUserimport org.openiam.provision.type.Attributeimport org.openiam.sync.service.impl.service.AbstractUserTransformScriptimport java.util.stream.Collectorspublic class AzureUserTransformationScript extends AbstractUserTransformScript {@Overrideint execute(LineObject rowObj, ProvisionUser pUser) {println("Is New User: " + isNewUser)if (isNewUser) {pUser.id = null}populateObject(rowObj, pUser)pUser.setNotifyUserViaEmail(false);pUser.setSkipPreprocessor(true)pUser.setSkipPostProcessor(true)return NO_DELETE}@Overridevoid init() {}String AZURE_MANAGED_SYS_ID = "O365_MANAGED_SYS";private void populateObject(LineObject rowObj, ProvisionUser pUser) {Map<String, Attribute> columnMap = rowObj.columnMapdef attrValattrVal = columnMap.get("ObjectId")if (attrVal) {addAttribute(pUser, attrVal)}if (isNewUser) {//valid only for new users, others are matched with WD so this data come from thereattrVal = columnMap.get("FirstName")if (attrVal) {pUser.firstName = attrVal.value}if (!pUser.firstName) {pUser.firstName = "FirstName"}if (pUser.firstName?.length() > 50) {pUser.firstName = pUser.firstName?.substring(0, 50)}attrVal = columnMap.get("middleName")if (attrVal) {pUser.middleInit = attrVal.value}attrVal = columnMap.get("displayName")if (attrVal) {pUser.setNickname(attrVal?.value);}attrVal = columnMap.get("LastName")if (attrVal) {pUser.lastName = attrVal.value}if (!pUser.lastName) {pUser.lastName = "LastName"}if (pUser.lastName?.length() > 50) {pUser.lastName = pUser.lastName?.substring(0, 50)}}Login lgAzure//for users we use userPrincipalName as login, because it presentedattrVal = columnMap.get("userPrincipalName")//if user has no AD login we add it, if exists we get it and update attributesif (!pUser.getPrimaryPrincipal(AZURE_MANAGED_SYS_ID) && attrVal) {lgAzure = new Login()lgAzure.operation = AttributeOperationEnum.ADDlgAzure.login = attrVal.valuelgAzure.managedSysId = AZURE_MANAGED_SYS_IDlgAzure.setActive(true)pUser.principalList.add(lgAzure)} else {LoginMQService loginMQService = (LoginMQService) context.getBean(LoginMQService.class);lgAzure = pUser.getPrimaryPrincipal(AZURE_MANAGED_SYS_ID)List<LoginAttribute> attributes = loginMQService.getLoginAttributes(lgAzure.getId())Set<LoginAttribute> attSet = new HashSet<>()attSet.addAll(attributes)lgAzure.setLoginAttributes(attSet)attrVal = columnMap.get("pwdLastSet")if (attrVal) {addLoginAttribute(lgAzure, attrVal)}attrVal = columnMap.get("LastPasswordChangeTimestamp")if (attrVal) {addLoginAttribute(lgAzure, attrVal)}attrVal = columnMap.get("PasswordNeverExpires")if (attrVal) {addLoginAttribute(lgAzure, attrVal)}attrVal = columnMap.get("WhenCreated")if (attrVal) {addLoginAttribute(lgAzure, attrVal)}attrVal = columnMap.get("Enabled")if (attrVal?.value) {addLoginAttribute(lgAzure, attrVal)}List<LoginAttribute> list = new ArrayList<>()list.addAll(lgAzure.getLoginAttributes())loginMQService.saveLoginAttributes(list, lgAzure.getId())}}def addEmailAddress(ProvisionUser pUser, EmailAddress emailAddress) {if (!isNewUser) {for (EmailAddress e : pUser.emailAddresses) {if (emailAddress.mdTypeId.equalsIgnoreCase(e.mdTypeId)) {e.setEmailAddress(emailAddress.getEmailAddress())e.setOperation(AttributeOperationEnum.REPLACE)return}}}emailAddress.setOperation(AttributeOperationEnum.ADD)pUser.emailAddresses.add(emailAddress)}def addLoginAttribute(Login login, Attribute attr) {if (attr?.name) {LoginAttribute ladef collect = login.getLoginAttributes().stream().filter({ it -> it.getName().equalsIgnoreCase(attr.getName()) }).collect(Collectors.toList()) //get attribute by nameif (CollectionUtils.isNotEmpty(login.getLoginAttributes()) && collect) {la = collect.get(0)la.setOperation(AttributeOperationEnum.REPLACE)} else {la = new LoginAttribute()la.setOperation(AttributeOperationEnum.ADD)}la.setName(attr.name)List<String> values = new ArrayList<>()values.add(attr.getValue())la.setValues(values)la.setLoginId(login.getId())login.addAttribute(la)}}def addAttribute(ProvisionUser pUser, Attribute attr) {if (attr?.name) {def userAttr = new UserAttribute(attr.name, attr.value)userAttr.operation = AttributeOperationEnum.ADDif (!isNewUser) {for (String name : pUser.userAttributes.keySet()) {if (name.equalsIgnoreCase(attr.name)) {pUser.userAttributes.remove(name)userAttr.operation = AttributeOperationEnum.REPLACEbreak}}}pUser.userAttributes.put(attr.name, userAttr)println("Attribute '" + attr.name + "' added to the user object.")}}}