Один из механизмовIDM Midpoint — Personas позволяет создавать управляемых двойников и хотя сами разработчики не очень доверяют этой функции (прочитайте вот тут внизу — типичный Evolveum) его вполне можно использовать в интересных сценариях. В статье не только покажу как можно использовать Personas но и залезу в дебри авторизации, потому что одно дело делать все Midpoint админом вручную а другое «давайте сами всё через GUI»!
Что такое Personas человеческим языком — это создание и обновление через маппинг сущности User — связь User to User. Пользователю А дается роль которая создает еще одного пользователя В, в которого по маппингу копируется данные из пользователя А. Если в А что то меняется и на это есть маппинг то это сразу обновляется в В. Вся суть в этой связи, а В сам по себе еще один полноценный пользователь для Midpoint.
Мы будем делать следующее: Создавать так называемую техническую учетку(virtual identities), на которую пользователь из основной учетки будет запрашивать роли предназначенные только для тех.учетки.
Берем Midpoint 4.9 полностью настроенный под MS AD по предыдущим статьям, у нас уже есть Resource\Windows MS AD. В ресурсе MS AD настроим отдельные Schema Handling\Object type под аккаунты и группы которые будут работать с тех.учетками. В MS AD так же создаем OU Virtual Identities куда будем класть такие аккаунты и группы.
I Архетипы
Создаем архетипы под новее Schema Handling\Object type пока пустые.
В Archetypes\New archetypes имя Persona VIRT ArcheType и пока настраиваем только отображение, в Archetypes\Persona VIRT ArcheType\ArcheType policy\Display\Icon заполняем согласно своим визуальным предпочтениям.

В Archetypes\New archetypes имя AD Group Special ArcheType и пока настраиваем только отображение, в Archetypes\AD Group Special ArcheType\Archetype policy\Display\Icon заполняем согласно своим визуальным предпочтениям.

II Object template
При создани Persona у пользователя указывается архетип и Object template — в котором прописывается как расскладывать данные из пользователя в Persona.
В Object templates>New object template создаем object template под названием VIRT persona Object Template. В его RAW code вставляем перед </objectTemplate>
код
<mapping id="10">
<name>adminStatus to persona</name>
<source>
<path>c:activation/c:administrativeStatus</path>
</source>
<expression/>
<target>
<path>c:activation/c:administrativeStatus</path>
</target>
</mapping>
<mapping id="16">
<name>nickName to nickName+</name>
<source>
<path>c:nickName</path>
</source>
<expression>
<script>
<code>'virt-' + nickName</code>
</script>
</expression>
<target>
<path>c:nickName</path>
</target>
</mapping>
<mapping id="18">
<name>nickName to name+</name>
<source>
<path>c:nickName</path>
</source>
<expression>
<script>
<code>'virt-' + nickName</code>
</script>
</expression>
<target>
<path>c:name</path>
</target>
</mapping>
<mapping id="20">
<name>fullName to fullName</name>
<source>
<path>c:fullName</path>
</source>
<target>
<path>c:fullName</path>
</target>
</mapping>
<mapping id="22">
<name>personalNumber to personalNumber+</name>
<source>
<path>c:personalNumber</path>
</source>
<expression>
<script>
<code>'virt-' + personalNumber</code>
</script>
</expression>
<target>
<path>c:personalNumber</path>
</target>
</mapping>
Это так же можно видеть в Object templates>New object template\VIRT persona Object Template\Mappings

Берем из пользователя nickName и personalNumber добавляем спереди «virt-» и пишем в Person
Да nickName уже должен быть!
III Resource Scheme Handler Object Type под VIRT аккаунты в AD
В ресурсе AD создаем отдельный Scheme Handler Object Type под VIRT привожу сразу кодом, вставлять перед </schemaHandling>
код
<objectType id="11502">
<kind>account</kind>
<intent>intent MS AD account VIRT persona</intent>
<displayName>MS AD account VIRT persona</displayName>
<delineation>
<objectClass>ri:user</objectClass>
<filter>
<q:text>attributes/sAMAccountName startsWith "virt-"</q:text>
</filter>
</delineation>
<focus>
<archetypeRef oid="b21dc019-d581-43f5-9fba-55fe09ba9eb7" relation="org:default" type="c:ArchetypeType">
<!-- Persona VIRT ArcheType -->
</archetypeRef>
</focus>
<attribute id="11504">
<ref>ri:cn</ref>
<outbound>
<name>01 out virt</name>
<strength>strong</strength>
<source>
<path>nickName</path>
</source>
</outbound>
</attribute>
<attribute id="11506">
<ref>ri:employeeNumber</ref>
<outbound>
<name>07 out virt</name>
<strength>strong</strength>
<source>
<path>personalNumber</path>
</source>
</outbound>
<inbound id="11507">
<name>01 in virt</name>
<strength>strong</strength>
<target>
<path>personalNumber</path>
</target>
<use>correlation</use>
</inbound>
</attribute>
<attribute id="11509">
<ref>ri:sAMAccountName</ref>
<outbound>
<name>02 out virt</name>
<strength>strong</strength>
<source>
<path>nickName</path>
</source>
</outbound>
</attribute>
<attribute id="11510">
<ref>ri:displayName</ref>
<outbound>
<name>03 out virt</name>
<strength>strong</strength>
<source>
<path>nickName</path>
</source>
</outbound>
</attribute>
<attribute id="11512">
<ref>ri:dn</ref>
<outbound>
<name>04 out virt dn</name>
<strength>strong</strength>
<source>
<path>nickName</path>
</source>
<expression>
<script>
<code>baseContext = basic.getResourceIcfConfigurationPropertyValue(resource, 'baseContext')
dn_value = 'CN=' + nickName + ',OU=Virtual Identities,' + baseContext
return dn_value</code>
</script>
</expression>
</outbound>
</attribute>
<attribute id="11514">
<ref>ri:pwdLastSet</ref>
<outbound>
<name>05 out virt</name>
<strength>strong</strength>
<expression>
<script>
<code>return "0"</code>
</script>
</expression>
<condition>
<script>
<code>"add".equals(operation.toString()) && midpoint.isEvaluateNew()</code>
</script>
</condition>
</outbound>
</attribute>
<attribute id="11515">
<ref>ri:userPrincipalName</ref>
<outbound>
<name>06 out virt</name>
<strength>strong</strength>
<source>
<path>nickName</path>
</source>
<expression>
<script>
<code>return nickName + "@168testserverhome.com"</code>
</script>
</expression>
</outbound>
</attribute>
<activation>
<administrativeStatus>
<outbound id="11528">
<name>Block virt form Midpoint</name>
<strength>strong</strength>
<source>
<path>activation/administrativeStatus</path>
</source>
</outbound>
<inbound id="11530">
<name>Block virt form AD</name>
<lifecycleState>draft</lifecycleState>
<strength>strong</strength>
<source>
<path>$shadow/attributes/ri:ADS_UF_ACCOUNTDISABLE</path>
</source>
</inbound>
</administrativeStatus>
</activation>
<credentials>
<password>
<outbound id="11537">
<name>First pasword</name>
<strength>weak</strength>
<expression>
<generate>
<mode>policy</mode>
<valuePolicyRef oid="00000000-0000-0000-0000-000000000003" type="c:ValuePolicyType" xsi:type="c:ObjectReferenceType"/>
</generate>
</expression>
</outbound>
</password>
</credentials>
<correlation>
<correlators>
<items id="11525">
<item id="11526">
<ref>personalNumber</ref>
</item>
</items>
</correlators>
</correlation>
<synchronization>
<reaction id="11518">
<situation>linked</situation>
<actions>
<synchronize id="11519"/>
</actions>
</reaction>
<reaction id="11520">
<situation>unlinked</situation>
<actions>
<link id="11521"/>
</actions>
</reaction>
<reaction id="11522">
<situation>deleted</situation>
<actions>
<deleteResourceObject id="11523"/>
</actions>
</reaction>
</synchronization>
</objectType>
Во многом он повторяет основной Scheme Handler Object Type с мелкими изменениями:
В Scheme Handler\Object Type\MS AD account VIRT persona\Basic attributes прописан Filter чтобы хватать только AD аккаунта имя которых начинается на «virt-»
attributes/sAMAccountName startsWith "virt-"
А в основном соответственно там же надо написать
attributes/sAMAccountName not startsWith "virt-"
Так как у нас создание VIRT учетки подразумевает создание AD учетки под неё, добавим в архетип в Archetypes\Persona VIRT ArcheType перед </archetype>
код
<inducement id="2236">
<construction>
<resourceRef oid="b8618fba-cf8b-416c-8e3b-32ea34cf003d" relation="org:default" type="c:ResourceType">
</resourceRef>
<kind>account</kind>
<intent>intent MS AD account VIRT persona</intent>
</construction>
</inducement>
IV Роль для создания Persona
В Role cоздаем простую черную роль под названием Persona VIRT
Вставляем перед </role>
код
<inducement id="4">
<personaConstruction>
<targetType>UserType</targetType>
<objectMappingRef oid="21239b6d-b888-4187-8eaa-3007aa612c66" relation="org:default" type="c:ObjectTemplateType">
<!-- VIRT persona Object Template -->
</objectMappingRef>
<archetypeRef oid="b21dc019-d581-43f5-9fba-55fe09ba9eb7" relation="org:default" type="c:ArchetypeType">
<!-- Persona VIRT ArcheType -->
</archetypeRef>
</personaConstruction>
</inducement>
Тут указаны OID архетипа Persona VIRT ArcheType и object template VIRT persona Object Template
Даем эту роль Татьяне Петровне роль Persona VIRT через Assigment в ней
В Personas появляется virt-TZemlyanikina

И заходим в virt-TZemlyanikina смотрим есть ли у ней проэкция в AD, создалась ли учетка AD

Создалась
V Resource Scheme Handler Object Type под AD группы которые будут выдаваться VIRT аккаунтам
В AD создадим и выделим группы которые будут выдаваться только VIRT аккаунтам. Для этого в Midpoint создадим Scheme Handler Object Type под названием MS AD Group Special привожу сразу кодом, вставлять перед </schemaHandling>
код
<objectType id="11582">
<kind>entitlement</kind>
<intent>intent MS AD Group Special</intent>
<displayName>MS AD Group Special</displayName>
<lifecycleState>active</lifecycleState>
<delineation>
<objectClass>ri:group</objectClass>
<filter>
<q:text>attributes/cn contains 'ADGS'</q:text>
</filter>
</delineation>
<focus>
<type>c:RoleType</type>
<archetypeRef oid="0ee145d7-e122-4fb9-a499-5e373fc727e5" relation="org:default" type="c:ArchetypeType">
<!-- AD Group Special ArcheType -->
</archetypeRef>
</focus>
<attribute id="11583">
<ref>ri:cn</ref>
<inbound id="11584">
<name>01 in g</name>
<strength>strong</strength>
<expression>
<script>
<code>"ADGS:" + basic.stringify(input)</code>
</script>
</expression>
<target>
<path>name</path>
</target>
</inbound>
</attribute>
<attribute id="11585">
<ref>ri:displayName</ref>
<inbound id="11586">
<name>02 in g</name>
<strength>strong</strength>
<target>
<path>displayName</path>
</target>
</inbound>
</attribute>
<attribute id="11587">
<ref>ri:distinguishedName</ref>
<inbound id="11588">
<name>03 in g</name>
<strength>strong</strength>
<target>
<path>identifier</path>
</target>
</inbound>
</attribute>
<correlation>
<correlators>
<items id="11589">
<name>Correlate by identifier and dn</name>
<item id="11590">
<ref>identifier</ref>
</item>
</items>
</correlators>
</correlation>
<synchronization>
<reaction id="11591">
<situation>unmatched</situation>
<actions>
<addFocus id="11592"/>
</actions>
</reaction>
<reaction id="11593">
<situation>linked</situation>
<actions>
<synchronize id="11594"/>
</actions>
</reaction>
<reaction id="11595">
<situation>unlinked</situation>
<actions>
<link id="11596"/>
</actions>
</reaction>
<reaction id="11597">
<situation>deleted</situation>
<actions>
<deleteResourceObject id="11598"/>
</actions>
</reaction>
</synchronization>
</objectType>
Обычный код для группы, тут надо обратить внимание на то что написано в Scheme Handler\Object Type\MS AD Group Special\Basic attributes в Filter
attributes/cn contains 'ADGS'
Группы под VIRT аккаунты у нас в AD называются с ADGS... поэтому мы их так и выделяем в фильтре.
А в основном Scheme Handler\Object Type\ для всех групп AD прописываем наоборот
attributes/cn not contains 'ADGS'
Теперь в Scheme Handler\Object Type\MS AD account VIRT persona добавляем код для членства
<association id="3066">
<ref>AD special group membership to Midpoint</ref>
<kind>entitlement</kind>
<intent>intent MS AD Group Special</intent>
<direction>objectToSubject</direction>
<associationAttribute>ri:member</associationAttribute>
<valueAttribute>ri:dn</valueAttribute>
</association>
А в архетип Archetypes\AD Group Special ArcheType\ вставляем перед </archetype>
<inducement id="7">
<construction>
<resourceRef oid="b8618fba-cf8b-416c-8e3b-32ea34cf003d" relation="org:default" type="c:ResourceType">
<!-- Windows MS AD -->
</resourceRef>
<kind>account</kind>
<intent>intent MS AD account VIRT persona</intent>
<association id="28">
<ref>AD special group membership to Midpoint</ref>
<outbound>
<expression>
<associationFromLink>
<projectionDiscriminator xsi:type="c:ShadowDiscriminatorType">
<kind>entitlement</kind>
<intent>intent MS AD Group Special</intent>
</projectionDiscriminator>
</associationFromLink>
</expression>
</outbound>
</association>
</construction>
<order>2</order>
<focusType>UserType</focusType>
</inducement>
Запускаем реконсиляцию Scheme Handler\Object Type\MS AD Group Special и он нам наделает кучу групп начинающихся на «ADGS:»

Если добавить эту роль ADGS группу VIRT аккаунту в Midpoint оно получит эту AD группу. Но если эту роль добавить обычному аккаунту то будет ошибка, так как членстване прописаны, и вообще одно членство рабоатет гуд, а больше одного вообще не работает. Тут просто сделаем policy которая будет кидать всех членов роль ADGS группы у кого нет архетипа Persona VIRT ArcheType в case администратору, пусть сам разбирается.
В архетип Archetypes\AD Group Special ArcheType\ вставляем перед </archetype>
код
<inducement id="30">
<policyRule>
<name>Member must have archetype Persona VIRT ArcheType</name>
<policyConstraints>
<requirement id="31">
<targetRef oid="b21dc019-d581-43f5-9fba-55fe09ba9eb7" relation="org:default" type="c:ArchetypeType">
<!-- Persona VIRT ArcheType -->
</targetRef>
</requirement>
</policyConstraints>
<policyActions>
<approval id="35">
<approverRef oid="00000000-0000-0000-0000-000000000002" relation="org:default" type="c:UserType">
<!-- administrator -->
</approverRef>
</approval>
</policyActions>
<evaluationTarget>assignment</evaluationTarget>
</policyRule>
</inducement>
Теперь если обычному пользователю выдадим роль ADGS группы - администратор получит case

И конечно сделает reject, хотя надо будет разбираться как вообще это случилось!
VI Создаем авторизационную роль для пользователя для запроса ролей для своего VIRT аккаунта
Авторизация в Midpoint крайне запутана и неописана. Но пойдем с начала.
Пользователь хочет сам запросить роль Persona VIRT для этого эту роль надо пометить как Requestable(в самой роли в Basic).
Так как у всех наших пользователей через архетип Person есть роль End User которая позволяет запрашивать роли в которых Requestable true, то пользователь может уже её запросить но получит ошибку. Надо в роль End User прописать права на создание Persona.
Добавляем перед </role>
стандартный код
<authorization id="889">
<name>auth-persona-execute-add</name>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#add</action>
<phase>execution</phase>
<object id="890">
<type>UserType</type>
<archetypeRef oid="b21dc019-d581-43f5-9fba-55fe09ba9eb7" relation="org:default" type="c:ArchetypeType">
<!-- Persona VIRT ArcheType -->
</archetypeRef>
</object>
</authorization>
<authorization id="888">
<name>auth-persona-execute-modify-delete</name>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#modify</action>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#delete</action>
<phase>execution</phase>
<object id="891">
<type>UserType</type>
<archetypeRef oid="b21dc019-d581-43f5-9fba-55fe09ba9eb7" relation="org:default" type="c:ArchetypeType">
<!-- Persona VIRT ArcheType -->
</archetypeRef>
<owner>
<special>self</special>
</owner>
</object>
</authorization>
OID тут архетипа Persona VIRT ArcheType
И так пользователь запросит, получит VIRT аккаунт, но не увидит этого в своем кабинете Midpoint.
Для этого в роли End User находим в <selfProfilePage>...</selfProfilePage>
код
<panel id="42">
<identifier>personas</identifier>
<visibility>hidden</visibility>
</panel>
И удаляем его!
Так же в End User уже есть авторизация чтобы читать свои persona не трогаем это
<authorization id="4">
<name>self-persona-read</name>
<description>
Allow to read all the personas of currently logged-in user.
</description>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#read</action>
<object id="18">
<type>UserType</type>
<owner>
<special>self</special>
</owner>
</object>
</authorization>
Авторизация в Midpoint состоит из двух кусков то что можно видеть и то что можно делать, они не равнозначны по возможностям настройки — и получается что делать можно слишком много но реально это ограничивается тем что можно увидеть.
А также куски кода можно заснуть в лубые роли назначаемые пользователю, Midpoint все равно всё в кучу собирает и обрабатывает.
Пока роль Persona VIRT сработает только если её назначит administartor у него есть все права на всё. А нам надо прописать чтобы и у пользователя были некие права на работу со своей VIRT personа.
В роль Persona VIRT перед </role> добавляем
код
<authorization id="999">
<name>persona-VIRT-assign-requestable-roles</name>
<description>
</description>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#assign</action>
<phase>request</phase>
<object id="1000">
<type>UserType</type>
<filter>
<q:text>name startsWith "virt-"</q:text>
</filter>
<owner>
<special>self</special>
</owner>
</object>
<target id="23">
<type>RoleType</type>
<filter>
<q:text>name startsWith "ADGS"</q:text>
</filter>
</target>
<relation>org:default</relation>
</authorization>
<authorization id="11">
<name>persona-VIRT-shadow-execution-add-modify-delete</name>
<description>
Authorization that allows to persona-modification of user's accounts, but only in execution phase.
The real limitation of these operations is done in the request phase.
</description>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#add</action>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#modify</action>
<action>http://midpoint.evolveum.com/xml/ns/public/security/authorization-model-3#delete</action>
<phase>execution</phase>
<object id="25">
<type>ShadowType</type>
<owner>
<type>UserType</type>
<archetypeRef oid="b21dc019-d581-43f5-9fba-55fe09ba9eb7" relation="org:default" type="c:ArchetypeType">
<!-- Persona VIRT ArcheType -->
</archetypeRef>
</owner>
</object>
</authorization>
authorization id="999"— конкретно сообщаем что можем assign’ить только своей Persona, причем name которой начинается с «virt-», роли которые начинаются с name «ADGS».
authorization id="11"— а тут уже очень широко написано делай чего хочешь с Shadow у которой владелец с архетипом Persona VIRT ArcheType то есть попадаем в наши VIRT учетки.
Заходим под сотрудником в его кабнет Midpoint идем в Request access\MySelf\Defoult и берем себе роль Person VIRT, кстати Evolveum сообщает что она должна выдавать без одобрителя а то чето не сработает, вот тут внизу написано docs.evolveum.com/midpoint/reference/master/misc/persona/configuration/

Идем в Profile\Personas и видим что Persona появилась и даже у ней уже 1 аккаунт, это как раз учетка AD

Теперь идем в Request access\Group/Others\ выбираем из списка virt-EGost и видим что можем запросить наши секретные роли AD группы

И после идем в Profile\Personas\маленькая стрелка с права в конце на virt-Egost\Assigments\All и вот она ADGS роль группа получена

VII Операция Миграция
Представим что у вас уже есть VIRT AD учетки в AD, Midpoint конечно об этом ничего не знает и хотелось бы учетки пользователей привязать к VIRT AD учеткам, и наверняка на них в AD уже есть группы, все это чтобы вот сохранилось.
У нас настроенна correlation в Scheme Handler\Object Type\MS AD account VIRT persona\ если employeeNumber в AD совпадает с personalNumber в Midpoint то учетка связывается.
Сделаем в AD в OU Virtual Identities любую учетку «virt‑qwerty», главное чтобы её название начиналось на «virt‑» и был заполнен employeeNumber «virt‑» + personalNumber реального пользователя. Остается только этому пользователю в Midpoint выдать Persona VIRT и все должно привязаться...нет! Как бы смысл correlation что вот это то что нужно для привязки, но Midpoint привяжет только если выполнится correlation и cn(и пр) будет такой же какой прописан в нашем outbound mapping для Scheme Handler\Object Type\MS AD account VIRT и привяжется только если будем давать роль создай учетку AD на Midpoint VIRT учетку
Главное что мы поняли что Midpoint реально надо для привязки в этой ситуaции, миграция она такая, надо подстраиваться! Возможно кстати это глюк версии 4.9, возможно это в целом недописанный механизм связей для Persona!!!
...Значит остаётся всего лишь сделать task с мега скриптом, который будет смотреть в ресурсе есть ли не привязанные Shadow VIRT AD аккаунтов, и если их employeeNumber соответствует personalNumber какого‑то пользователя то выдавать ему роль Persona VIRT, а за тем искать в Midpoint эту новую VIRT учетку и давать ей роль создай AD VIRT учетку.
Переделываем под миграцию все что сделали в V-VI главе, после миграции возвращаем обратно!
В архетипе Persona VIRT ArcheType убираем
<inducement id="2236">
<construction>
<resourceRef oid="b8618fba-cf8b-416c-8e3b-32ea34cf003d" relation="org:default" type="c:ResourceType">
<!-- Windows MS AD -->
</resourceRef>
<kind>account</kind>
<intent>intent MS AD account VIRT persona</intent>
</construction>
</inducement>
Создаем обычную черную роль Persona VIRT MS AD VIRT account в которую вставляем код:
<inducement id="2236">
<construction>
<resourceRef oid="b8618fba-cf8b-416c-8e3b-32ea34cf003d" relation="org:default" type="c:ResourceType">
<!-- Windows MS AD -->
</resourceRef>
<kind>account</kind>
<intent>intent MS AD account VIRT persona</intent>
</construction>
</inducement>
Чтобы при миграции тащило группы с AD VIRT учетки меняем членство в ресурсе AD\Scheme Handler Object Type\MS AD account VIRT persona
было
<association id="3066">
<ref>AD special group membership to Midpoint</ref>
<kind>entitlement</kind>
<intent>intent MS AD Group Special</intent>
<direction>objectToSubject</direction>
<associationAttribute>ri:member</associationAttribute>
<valueAttribute>ri:dn</valueAttribute>
</association>
стало
<association id="3066">
<ref>AD special group membership to Midpoint</ref>
<inbound id="3066478">
<strength>normal</strength>
<channel>http://midpoint.evolveum.com/xml/ns/public/common/channels-3#reconciliation</channel>
<expression>
<assignmentTargetSearch>
<targetType>RoleType</targetType>
<filter>
<q:equal>
<q:path>identifier</q:path>
<expression>
<script>
<code>
return basic.getAttributeValue(entitlement, 'dn')
</code>
</script>
</expression>
</q:equal>
</filter>
</assignmentTargetSearch>
</expression>
<target>
<path>assignment</path>
</target>
</inbound>
<kind>entitlement</kind>
<intent>intent MS AD Group Special</intent>
<direction>objectToSubject</direction>
<associationAttribute>ri:member</associationAttribute>
<valueAttribute>ri:dn</valueAttribute>
</association>
В Service tasks\Iterative action tasks создаем пустую таску под названием Create & Link Midpoint VIRT Persona to existing VIRT AD account
вставляем в неё код, перед </task>
<activity>
<work>
<iterativeScripting>
<objects>
<type>ShadowType</type>
<query>
<q:filter>
<q:text>
resourceRef matches (oid = 'b8618fba-cf8b-416c-8e3b-32ea34cf003d' and targetType = ResourceType) and intent = 'intent MS AD account VIRT persona' and synchronizationSituation= "UNMATCHED"
</q:text>
</q:filter>
</query>
<useRepositoryDirectly>true</useRepositoryDirectly>
</objects>
<scriptExecutionRequest xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3">
<s:action>
<s:type>execute-script</s:type>
<s:parameter>
<s:name>script</s:name>
<s:value xsi:type="c:ScriptExpressionEvaluatorType">
<code>
import com.evolveum.midpoint.xml.ns._public.common.common_3.*
import com.evolveum.midpoint.prism.delta.builder.*
import com.evolveum.midpoint.model.api.*
shadow_virt_employeeNUmber = basic.getAttributeValue(input, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'employeeNumber')
shadow_employeeNUmber = basic.getAttributeValue(input, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'employeeNumber').substring(5)
shadow_ADlogin = basic.getAttributeValue(input, 'http://midpoint.evolveum.com/xml/ns/public/resource/instance-3', 'sAMAccountName').substring(5)
query_user = midpoint.queryFor(UserType.class, "personalNumber = '$shadow_employeeNUmber'")
result_USER = midpoint.searchObjects(query_user)
if (result_USER)
{
user_ass = new ObjectReferenceType()
user_ass.setOid("328685d4-8186-4ab2-85c6-a3d0f08f3ac0")
user_ass.setType(RoleType.COMPLEX_TYPE)
addAssignment = new AssignmentType()
addAssignment.setTargetRef(user_ass)
def delta = []
delta = prismContext.deltaFor(UserType.class).item(FocusType.F_ASSIGNMENT).add(addAssignment.asPrismContainerValue()).asObjectDelta(result_USER.oid)
midpoint.modifyObject(delta, ModelExecuteOptions.createRaw())
midpoint.recompute(UserType.class, basic.stringify(result_USER.oid))
query_virt_user = midpoint.queryFor(UserType.class, "personalNumber = '$shadow_virt_employeeNUmber'")
result_VIRT_USER = midpoint.searchObjects(query_virt_user)
virt_user_ass = new ObjectReferenceType()
virt_user_ass.setOid("fab9abb5-a6d4-4bcf-ba6f-0eed16004d3e")
virt_user_ass.setType(RoleType.COMPLEX_TYPE)
virt_addAssignment = new AssignmentType()
virt_addAssignment.setTargetRef(virt_user_ass)
def virt_delta = []
virt_delta = prismContext.deltaFor(UserType.class).item(FocusType.F_ASSIGNMENT).add(virt_addAssignment.asPrismContainerValue()).asObjectDelta(result_VIRT_USER.oid)
midpoint.modifyObject(virt_delta, ModelExecuteOptions.createRaw())
midpoint.recompute(UserType.class, basic.stringify(result_VIRT_USER.oid))}
</code>
</s:value>
</s:parameter>
</s:action>
</scriptExecutionRequest>
</iterativeScripting>
</work>
</activity>
Код хорошо визуализируется в GUI

В Objects мы строкой из Advenced searh описываем какие Shadow из какого Ресурса и из какого Intenta берем. Нас интересуют те которые не привязаны те что UNMATCHED
resourceRef matches (oid = 'b8618fba-cf8b-416c-8e3b-32ea34cf003d' and targetType = ResourceType) and intent = 'intent MS AD account VIRT persona' and synchronizationSituation= "UNMATCHED"
oid — моего ресурса AD у вас будет свой
В Iterative scripting сам код, тут тоже надо поменять oid на свои
328 685d4–8186–4ab2–85c6-a3d0f08f3ac0 — роль Person VIRT
fab9abb5-a6d4–4bcf‑ba6f-0eed16 004d3e — роль Persona VIRT MS AD VIRT account
Перед запуском, у нас реконсилирован в ресурсе AD\Scheme Handler Object Type\MS AD account VIRT persona и в нем есть UNMATCHED VIRT AD аккаунты, а так же у нас реконсилирован в ресурсе AD\Scheme Handler\Object Type\MS AD Group Special

Нас интересует AD учетка virt-MShort на ней две ADGS группы. Запускаем task Create & Link Midpoint VIRT Persona to existing VIRT AD accounts. Запускам реконсиляцию ресурсе AD\Scheme Handler\Object Type\MS AD Group Special чтобы группы выдались
И идем смотрим появился ли в Midpoint virt-MShort а у него группы ADGS

Да
Вот так просто а главное быстро в IDM Midpoint можно начать использовать цифровых двойников