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.AttributeOperationEnum
import org.openiam.idm.srvc.grp.dto.Group
import org.openiam.idm.srvc.grp.dto.GroupAttribute
import org.openiam.idm.srvc.synch.dto.LineObject
import org.openiam.sync.service.impl.service.AbstractGroupTransformScript
class SubscriptionsToGroupsTransformationScript extends AbstractGroupTransformScript {
@Override
int 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.columnMap
if (isNewUser) {
group.id = null
}
group.name = columnMap.get("Name")?.value
group.policyId = "4000"
group.status = "ACTIVE"
def type = columnMap.get("Type")?.value
String 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);
}
}
@Override
void 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.AttributesScript
class AzureUserSyncAttributes implements AttributesScript {
@Override
String[] 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.CollectionUtils
import org.openiam.base.AttributeOperationEnum
import org.openiam.common.beans.mq.LoginMQService
import org.openiam.idm.srvc.auth.dto.Login
import org.openiam.idm.srvc.auth.dto.LoginAttribute
import org.openiam.idm.srvc.continfo.dto.EmailAddress
import org.openiam.idm.srvc.synch.dto.LineObject
import org.openiam.idm.srvc.user.dto.UserAttribute
import org.openiam.provision.dto.ProvisionUser
import org.openiam.provision.type.Attribute
import org.openiam.sync.service.impl.service.AbstractUserTransformScript
import java.util.stream.Collectors
public class AzureUserTransformationScript extends AbstractUserTransformScript {
@Override
int 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
}
@Override
void init() {}
String AZURE_MANAGED_SYS_ID = "O365_MANAGED_SYS";
private void populateObject(LineObject rowObj, ProvisionUser pUser) {
Map<String, Attribute> columnMap = rowObj.columnMap
def attrVal
attrVal = 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 there
attrVal = 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 presented
attrVal = columnMap.get("userPrincipalName")
//if user has no AD login we add it, if exists we get it and update attributes
if (!pUser.getPrimaryPrincipal(AZURE_MANAGED_SYS_ID) && attrVal) {
lgAzure = new Login()
lgAzure.operation = AttributeOperationEnum.ADD
lgAzure.login = attrVal.value
lgAzure.managedSysId = AZURE_MANAGED_SYS_ID
lgAzure.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 la
def collect = login.getLoginAttributes().stream().filter({ it -> it.getName().equalsIgnoreCase(attr.getName()) }).
collect(Collectors.toList()) //get attribute by name
if (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.ADD
if (!isNewUser) {
for (String name : pUser.userAttributes.keySet()) {
if (name.equalsIgnoreCase(attr.name)) {
pUser.userAttributes.remove(name)
userAttr.operation = AttributeOperationEnum.REPLACE
break
}
}
}
pUser.userAttributes.put(attr.name, userAttr)
println("Attribute '" + attr.name + "' added to the user object.")
}
}
}

Import Groups

Groovy script