Привилегии и ассоциации#
Привилегия (entitlement) - это объект ресурса, похожий на учетную запись. Но в отличие от учетной записи привилегия не представляет пользователя. Привилегия представляет собой привилегию, право доступа, роль на стороне ресурса или группу либо любую аналогичную концепцию. Привилегии очень часто используются для представления групп.
IDM можно настроить так, чтобы он полностью понимал привилегии. IDM может знать, какие объекты ресурсов представляют группы. Поэтому IDM может управлять членством в группах структурированным и автоматизированным способом. IDM может перечислять привилегии, а значит, его можно использовать для создания умных и удобных пользовательских интерфейсов. Поддержка привилегий в выходит за рамки возможностей подавляющего большинства решений по управлению идентификацией.
Почему привилегии так важны?
Управление членством в группе традиционно является одним из худших кошмаров систем управления идентификацией. Хотя концепция группировки поддерживается почти каждым ресурсом, фактическая реализация групп сильно различается. Некоторые системы хранят список групп в объектах учетных записей. Другие системы (например, LDAP) хранят список участников в объектах групп. Системы часто хранят список идентификаторов членов или групп в простых строковых атрибутах, поэтому автоматически определить, какой атрибут используется, сложно. Традиционно поддержка членства в группах требовала значительной настройки инструментов управления идентификацией, что замедляло выполнение проектов. Еще хуже было то, что это требовало дорогостоящего обслуживания, такого как ручная синхронизация списка групп и ролей в системе управления идентификацией. Такая ситуация просто неприемлема для эффективной развертки управления идентификацией.
Вот почему в IDM предусмотрена единая поддержка привилегий. IDM может управлять всеми группами единообразно независимо от механизма группировки, который использует ресурс. Все, что требуется, - это несколько строк конфигурации. И кошмар закончился. Особенно когда привилегии сочетаются с мощью назначений и универсальной синхронизации.
Тень привилегии#
Важно помнить, что привилегия является объектом ресурса. Привилегия находится на ресурсе. Это не объект, который поддерживается IDM. Привилегии отражают только реальность на ресурсе. Подобно всем другим объектам на стороне ресурса право представлено в IDM только как тень.
Привилегия, учетная запись и пользователь#
Основная цель привилегии заключается в том, чтобы она было связано с учетными записями (не пользователями!). Например, учетную запись можно добавить в группу. В IDM это реализуется путем ассоциации «привилегии группы» с учетной записью пользователя. Компонент предоставления IDM соответствующим образом изменяет ресурс для добавления учетной записи в группу. Подобно другим операциям, связанным с тенями, IDM затем забывает об этом. Информация остается только на ресурсе (если кэширование теней включено.) Когда происходит такая ассоциация, ситуация выглядит так:
Подобно атрибутам учетной записи, IDM всегда считывает свежие данные из ресурса при работе с правами. Поэтому IDM не нужно запоминать ассоциацию. Она может прочитать его непосредственно из ресурса в любое время. И именно это делает IDM, когда извлекается тень учетной записи:
IDM извлекает теневую копию из своего репозитория и использует идентификаторы, хранящиеся в тени, для поиска объекта учетной записи на ресурсе. IDM получает объект учетной записи. Затем IDM ищет информацию о привилегиях в учетной записи и обрабатывает любые ассоциации. IDM (или соответствующему коннектору) может потребоваться извлечь или найти дополнительные объекты для полной обработки ассоциаций. Например, стандартные группы LDAP хранят список участников в объекте группы, поэтому IDM (или коннектор LDAP) должен искать объекты групп для полной обработки информации об ассоциации. Все это делается прозрачно. Независимо от того, какой механизм группировки и ассоциации используется, IDM представляет данные в унифицированной форме.
Функция кеширования теней позволяет хранить части этой информации прямо в репозитории. Это включает отношения между тенями, такие как членство в группе. Однако общее правило, описанное выше, все еще применяется, если запрошенные данные отсутствуют в кеше.
Ассоциации#
Отношения между учетными записями и привилегиями реализуются с использованием так называемых ассоциаций. (Однако у ассоциаций гораздо более широкое применение, как описано ниже.)
Ассоциация — это отношение между субъектом и одним или несколькими объектами.
При использовании ассоциаций для реализации привилегий субъект является стороной, которая получает привилегию (обычно учетная запись), а объектом является сама привилегия (обычно группа).
Ассоциация может быть простой или сложной:
Простая ассоциация — это просто отношение между одним субъектом и одним объектом. Это типичный способ представления привилегий.
Сложная ассоциация имеет либо несколько присутствующих объектов, либо может содержать дополнительные данные (в настоящее время атрибуты и данные активации) самостоятельно. Типичные примеры:
Права доступа пользователя: у пользователя есть набор прав для чтения, записи и/или администрирования заданных каталогов. Каждое право доступа является значением этой ассоциации и имеет пользователя (как его субъект), каталог (как объект) и уровень доступа (как атрибут).
Трудовые договоры по кадрам: человек имеет ряд контрактов, каждый из которых имеет организационную единицу, центр затрат, должность, срок действия и другие данные. Каждый контракт является значением этой ассоциации. Человек является предметом. Организационная единица, центр затрат и должность являются объектами (предполагая, что они представлены отдельными объектами ресурсов в отделе кадров). Все остальное хранится в атрибутах ассоциации и данных активации.
Простые ассоциации полностью поддерживаются срединной точкой.
Сложные ассоциации - это экспериментальная функция.
Ассоциации и ссылочные атрибуты#
Технически ассоциации основаны на так называемых ссылочных атрибутах. Это специальные атрибуты, описывающие отношения (связи) между объектами ресурса. Каждый ссылочный атрибут находится на субъекте, и каждое из его значений (так как они могут быть одно- или многозначными, как и любые другие атрибуты) указывает на один объект.
Обычно ссылочные атрибуты скрыты от пользователей. Они видны только нижним уровням IDM, включая коннекторы.
Простая ассоциация эквивалентна атрибуту ссылки. Нет никаких дополнительных объектов, участвующих в этом процессе.
Сложная ассоциация реализуется с использованием отдельного объекта ресурса данных ассоциации (хранящего данные ассоциации), называемого объектом данных ассоциации. Субъект ассоциации имеет ссылку на этот объект данных ассоциации. Объект данных ассоциации содержит ссылки на отдельные объекты ассоциации.
Некоторые коннекторы, такие как LDAP/AD, поддерживают атрибуты ссылок прямо из коробки. Другие будут предоставлять эту поддержку позже. До тех пор возможно определить симулированные ссылки в средней точке, чтобы вы могли использовать всю мощь ассоциаций в ваших развертываниях.
Примечание о терминологии: элементы, значения и типы
(Чувствуйте себя свободно, чтобы пропустить это примечание, если оно слишком техническое при первом чтении.)
В средней точке мы различаем элементы (также называемые призматическими элементами) и их значения.
Элементы являются свойствами (например, ), ссылками (например, в ) и контейнерами (например, ), которые обеспечивают строительные блоки для объектов в средней точке. Также атрибуты и ассоциации являются специальными видами элементов, используемыми для описания содержимого объектов ресурсов.
Каждый элемент может быть односоставным или многосоставным. Первый может иметь либо ноль до одного значения, тогда как последний может иметь ноль, одно или несколько значений.
Например, атрибут LDAP employeeNumber является одновалентным. Он может иметь ноль или более значений. Атрибут LDAP telephoneNumber является многозначным. Он может иметь ноль, одно или несколько значений.
Ссылочные атрибуты также могут быть однозначными или многозначными. Например, атрибут group (указывающий на группы, членом которых является учетная запись) является многозначным. Каждое из значений называется значение ссылочного атрибута или ссылочное значение для краткости, тогда как сам атрибут называется ссылочный атрибут или ссылка для краткости. Это может показаться странным сначала, но это совершенно логично, когда к этому привыкаешь.
И то же самое относится к ассоциациям. Например, ассоциация group (основанная на атрибуте ссылки group) также является многозначной. Каждое из значений называется значением ассоциации, а сам элемент group называется ассоциацией.
Типы ассоциаций и ссылок
Ассоциации и симулированные ссылочные атрибуты определены на глобальном (широкомасштабном) уровне. Их определения представлены в виде типов ассоциаций и типов ссылочных атрибутов. Когда они применяются к заданному типу объекта или классу (например, account/default или ri:inetOrgPerson), они проявляются там как ассоциация и ссылочный атрибут. (Ассоциации могут быть видны только на типах объектов. Ссылочные атрибуты определяются главным образом на объектных классах, поэтому они видны как на объектных классах, так и на типах объектов.)
Например,
ri:groupMembershipможет быть именем типа ассоциации. При прикреплении к типам объектовaccount/defaultиentitlement/groupон может отображаться там какri:groupассоциация.ri:groupMembershipможет быть именем типа симулируемого ссылочного атрибута. При наличии на объектах классовri:inetOrgPersonиri:groupOfNamesон может отображаться там какri:groupссылочный атрибут.
Второе замечание о терминологии: простое против ссылочного против сложного
(Снова, не стесняйтесь пропустить это примечание, если оно слишком техническое при первом чтении.)
У нас есть следующие виды атрибутов:
Простые атрибуты: содержат только примитивные значения (строки, целые числа, метки времени и так далее). Это единственные атрибуты, присутствующие в IDM. Технически они являются специализацией свойств prism.
Атрибуты ссылок: содержат «указатели» на другие объекты ресурсов, то есть каждое значение атрибута ссылки указывает на один объект. Технически они являются специализацией ссылок prism.
Составные атрибуты: они будут содержать сложные значения, то есть те, которые состоят из дерева простых, ссылочных и сложных атрибутов сами по себе. Технически они будут специализацией контейнеров prism. Они еще не существуют ни в IDM, ни в ConnId. Их использование планируется на будущее.
Что касается ассоциаций, у нас есть два вида ассоциаций:
Простые ассоциации: каждое значение ассоциации указывает на один ресурсный объект. Они функционально эквивалентны атрибутам ссылок.
Сложные ассоциации: каждое значение ассоциации имеет:
ноль, одна или несколько атрибутов ссылки для объектов ассоциации,
ноль, один или несколько простых атрибутов,
необязательно, дополнительная информация, такая как данные активации.
Определение ассоциаций#
Ассоциации определены в разделе Обработка схемы ресурсов.
Давайте сначала рассмотрим определение симулированных ссылок.
Определение типа симулированной ссылки#
Участвующие ресурсные объекты#
Каждый смоделированный тип ссылки имеет две стороны: сторона объекта и сторона субъекта. (Вкратце, мы также называем это участниками.)
Сначала нам нужно определить, какие ресурсные объекты могут участвовать в этом типе ссылок на каждой из этих сторон. Мы называем это разграничением и используем следующие свойства для его выполнения:
Таблица 1. Определение участников типа ссылок
Элемент конфигурации |
Значение |
Пример |
|---|---|---|
|
Имя класса объектов для участника. |
|
|
Определение базовой контекстной среды (контейнер ресурсных объектов). Этот объект будет использоваться в качестве основы для поиска объектов-участников. Обычно только те объекты, которые находятся иерархически ниже , возвращаются таким поиском. |
Экспериментальный. |
|
Определение области иерархии поиска. Оно определяет, насколько «глубоко» должен идти поиск в объектной иерархии. Это применимо только к ресурсам, поддерживающим иерархическую организацию объектов (например, ресурсы LDAP). |
Экспериментальный. |
|
||
|
Ограничение участника до указанного вспомогательного класса объектов, если таковой имеется. Обычно используется, если атрибут привязки определен в этом классе, например, |
Экспериментальный. |
|
Может быть ноль, одно или несколько разграничений. |
Все разграничения на стороне объекта должны иметь один и тот же класс объектов. |
В следующем примере показано, как определить groupMembership тип ссылки, который связывает учетные записи и группы (в качестве субъектов) и группы (в качестве объектов).
Пример определения участников типа ссылок
<capabilities>
<c:configured xmlns="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
<references>
<type>
<name>ri:groupMembership</name>
<subject>
<delineation>
<objectClass>ri:AccountObjectClass</objectClass>
</delineation>
<delineation>
<objectClass>ri:GroupObjectClass</objectClass>
</delineation>
<!-- ... -->
</subject>
<object>
<delineation>
<objectClass>ri:GroupObjectClass</objectClass>
</delineation>
<!-- ... -->
</object>
<!-- ... -->
</type>
<!-- ... -->
</references>
</c:configured>
</capabilities>
При определении ассоциаций поверх смоделированных атрибутов ссылок возможно повторно использовать информацию о разграничении из самих ассоциаций. См. определение участников ассоциации ниже для примера
Привязки#
Далее мы должны определить, как субъекты и объекты связаны друг с другом, в частности:
как найти объекты (то есть значения атрибута ссылки) для заданной ссылки в предмете;
как добавить/удалить объекты (то есть значения атрибута ссылки) для данной ссылки в теме.
IDM поддерживает привязки, которые могут быть либо субъектно-объектными, либо объектно-субъектными.
Направление от субъекта к объекту довольно простое. В этом случае у субъекта (учетной записи) есть список его привилегий (групп). Это может выглядеть так:
Направление от субъекта к объекту
objectclass: account
username: jack
fullName: Jack Sparrow
groups: pirates
groups: captains
objectclass: account
username: will
fullName: Will Turner
groups: pirates
objectclass: group
groupname: pirates
objectclass: group
groupname: captains
В этом случае атрибут привязки на стороне субъекта - это groups, а атрибут привязки на стороне объекта - это groupname.
Управление этой привязкой очень просто.
При чтении IDM просто извлекает субъект (учетную запись), и все необходимые данные находятся там.
При обновлении (то есть добавлении или удалении ссылочных значений) IDM просто добавляет или удаляет соответствующие значения
groupsна субъекте (учетной записи).
Направление от объекта к субъекту более сложное. В этом случае привязка указывает другим образом. Объект (группа) содержит список субъектов (учетных записей), которые являются членами. Вот так:
Направление от объекта к субъекту
objectclass: account
username: jack
fullName: Jack Sparrow
objectclass: account
username: will
fullName: Will Turner
objectclass: group
groupname: pirates
members: jack
members: will
objectclass: group
groupname: captains
members: jack
В этом случае атрибут привязки на стороне субъекта обозначается как username, а атрибут привязки на стороне объекта - как members.
Управление этой привязкой также является сложным.
При чтении мы не можем просто получить субъект (учетную запись). Данные о членстве отсутствуют. Нам нужно искать все объекты. Например, если мы хотим получить список всех групп, к которым принадлежит
jack, нам нужно найти все группы, соответствующие фильтру(members=jack).При обновлении (то есть добавлении или удалении ссылочных значений) IDM должен будет обновить атрибут
membersконкретных групп: значениеjackлибо добавляется к этому атрибуту каждой группы, чье членство добавляется или удаляется изjack, либо удаляется оттуда.
Направленность ссылки имеет значительные последствия во многих областях. Во-первых, это влияет на производительность. Ссылки от объекта к субъекту требуют больше операций, чем ссылки от субъекта к объекту. И обычно эти дополнительные операции представляют собой обширные поиски по ресурсу. Во-вторых, это имеет последствия для поиска неисправностей. Различные типы ссылок производят разные операции коннектора. Особенно поиск ссылок от объекта к субъекту может оказаться довольно сложной задачей для устранения неполадок.
Основные и вторичные привязки#
Существует два типа привязок:
Основная привязка: Это та привязка, которая используется для обновления ссылки. Она также может использоваться для получения значений ссылок, если не определена другая привязка. Она может быть либо объектно-субъектной, либо субъектно-объектной.
Вторичная привязка: Есть ситуации, когда ресурс предоставляет дополнительные данные, позволяющие более эффективно извлекать значения ссылок. В таких случаях вы можете определить вторичную привязку, которая использует их. Она всегда является субъектно-объектной и определяется только в том случае, если основная привязка является объектно-субъектной.
Реальный пример для ресурса LDAP:
Первичная привязка может быть между атрибутом учетной записи
ri:dnи атрибутом группыri:member. Он используется для обновления данных о членстве пользователя в группе.Вторичная привязка может быть между атрибутом учетной записи
ri:memberOfи атрибутом группыri:dn. Она используется для чтения данных о членстве пользователя в группе. АтрибутmemberOf(или аналогичный) обычно предоставляется продвинутыми серверами LDAP. Это виртуальный атрибут учетной записи только для чтения, который содержит список групп, членом которых является учетная запись.
Некоторые примеры#
Это тип ссылки groupMembership, характерный для серверов LDAP. (Если по какой-то причине вы не используете встроенную возможность соединителя LDAP для этого.)
При запросе используется атрибут
ri:memberOfна субъекте (учетной записи или группе).При обновлении используется атрибут
ri:memberобъекта (группы).Ссылка видна как (виртуальный) атрибут ссылки
groupна субъект (учетную запись или группу).
Пример определения членства в группе LDAP
<capabilities>
<c:configured xmlns="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
<references>
<type>
<name>ri:groupMembership</name>
<subject>
<delineation>
<objectClass>ri:inetOrgPerson</objectClass>
</delineation>
<delineation>
<objectClass>ri:groupOfNames</objectClass>
</delineation>
<primaryBindingAttributeRef>ri:dn</primaryBindingAttributeRef>
<secondaryBindingAttributeRef>ri:memberOf</secondaryBindingAttributeRef>
<localItemName>ri:group</localItemName>
</subject>
<object>
<delineation>
<objectClass>ri:groupOfNames</objectClass>
</delineation>
<primaryBindingAttributeRef>ri:member</primaryBindingAttributeRef>
<secondaryBindingAttributeRef>ri:dn</secondaryBindingAttributeRef>
</object>
<direction>objectToSubject</direction>
</type>
</references>
</c:configured>
</capabilities>
Это типичный пример ссылки субъекта на объект.
При запросе и обновлении используется атрибут
ri:privilegesна субъекте (учетной записи).Ссылка отображается как (виртуальный) атрибут ссылки
ri:privна субъект (учетная запись).
Пример пользовательского определения «привилегий»
<capabilities>
<c:configured xmlns="http://midpoint.evolveum.com/xml/ns/public/resource/capabilities-3">
<references>
<type>
<name>ri:accountPrivilege</name>
<subject>
<delineation>
<objectClass>ri:account</objectClass>
</delineation>
<primaryBindingAttributeRef>ri:privileges</primaryBindingAttributeRef>
<localItemName>ri:priv</localItemName>
</subject>
<object>
<delineation>
<objectClass>ri:privilege</objectClass>
</delineation>
<primaryBindingAttributeRef>icfs:name</primaryBindingAttributeRef>
</object>
<direction>subjectToObject</direction>
</type>
</references>
</c:configured>
</capabilities>
Определение участников ассоциации#
Теперь давайте посмотрим, как определяются ассоциации - или, точнее, типы ассоциаций - поверх атрибутов ссылок.
Прежде всего, типы ассоциаций определены вне участвующих типов объектов. Каждый тип ассоциаций содержится в своем собственном элементе associationType под schemaHandling.
Минимальное определение типа ассоциации выглядит так:
<resource>
<!-- ... -->
<schemaHandling>
<!-- ... -->
<associationType>
<name>groupMembership</name>
<subject>
<objectType>
<kind>account</kind>
<intent>default</intent>
</objectType>
<association>
<ref>ri:group</ref>
</association>
</subject>
</associationType>
</schemaHandling>
</resource>
Определение должно содержать имя типа ассоциации, которое должно быть уникальным во всем ресурсе.
Затем оно должно содержать спецификацию типа субъекта или типов, к которым он применяется. В приведенном выше примере тип ассоциации groupMembership применим к типу объекта account/default. Затем элемент association определяет, как представлена эта ассоциация в этом типе объекта. В частности, ri:group - это имя, под которым ассоциация известна для объектов типа account/default.
Если не указано иное, имя ассоциации - здесь ri:group - также является именем атрибута ссылки, который предоставляет данные для этой ассоциации. Другими словами, все значения атрибута ri:group (предоставляемые соединителем или модулем для моделирования атрибутов ссылок) рассматриваются как значения ассоциации ri:group.
Инженер может ограничить значения от соединителя, просматривая определенные типы объектов.
Например, давайте предположим, что у нас есть ресурс Active Directory с двумя типами групп: группы безопасности и группы распространения. В IDM у нас будет два различных типа объектов для них: entitlement/security-group и entitlement/distribution-group. Для простоты допустим, что существует только один тип учетных записей: account/default.
Также давайте предположим, что у нас есть атрибут ссылки ri:group, предоставляемый коннектором, который содержит информацию обо всех группах, членом которых является конкретная учетная запись, включая группы безопасности и распространения. (Так работает простой атрибут memberOf в AD.)
Наконец, давайте предположим, что мы хотим определить две различные ассоциации: ri:securityGroup, содержащую все группы безопасности, и ri:distributionGroup, содержащую все группы распространения.
Определение тогда выглядит так:
Пример двух различных определений типов ассоциаций
<resource>
<!-- ... -->
<schemaHandling>
<objectType>
<kind>account</kind>
<intent>default</intent>
<!-- delineation, attributes, correlation, and synchronization for accounts -->
</objectType>
<objectType>
<kind>entitlement</kind>
<intent>security-group</intent>
<!-- delineation, attributes, correlation, and synchronization for security groups -->
</objectType>
<objectType>
<kind>entitlement</kind>
<intent>distribution-group</intent>
<!-- delineation, attributes, correlation, and synchronization for distribution groups -->
</objectType>
<!-- ... -->
<associationType>
<name>securityGroupMembership</name>
<subject>
<objectType>
<kind>account</kind>
<intent>default</intent>
</objectType>
<association>
<ref>ri:securityGroup</ref>
<sourceAttributeRef>ri:group</sourceAttributeRef>
<!-- inbound and outbound mappings for this type of association -->
</association>
</subject>
<object>
<objectType>
<kind>entitlement</kind>
<intent>security-group</kind>
</objectType>
</object>
</associationType>
<associationType>
<name>distributionGroupMembership</name>
<subject>
<objectType>
<kind>account</kind>
<intent>default</intent>
</objectType>
<association>
<ref>ri:distributionGroup</ref>
<sourceAttributeRef>ri:group</sourceAttributeRef>
<!-- inbound and outbound mappings for this type of association -->
</association>
</subject>
<object>
<objectType>
<kind>entitlement</kind>
<intent>distribution-group</kind>
</objectType>
</object>
</associationType>
</schemaHandling>
</resource>
Что происходит со значениями исходного атрибута ссылки ri:group?
Чтобы избежать дублирования данных, каждое значение исходного атрибута ссылки (то есть того, на котором основана ассоциация) проверяется, и:
Если оно соответствует одной из ассоциаций (
ri:securityGroupилиri:distributionGroupв приведенном выше примере), оно перемещается в эту ассоциацию. Это означает, что значение удаляется из атрибута ссылки и помещается в ассоциацию.Если оно не соответствует ни одной из ассоциаций (или ассоциации вообще не определены), оно остается в исходном атрибуте.
Таким образом, сначала, когда нет определенных ассоциаций, все значения видны в справочном атрибуте. Позже, по мере определения ассоциации или ассоциаций и очистки данных (когда все тени правильно классифицируются по типам объектов), в справочном атрибуте не должно быть никаких значений, и все должно быть видно в ассоциации или ассоциациях.
Ассоциативные маппинги#
Как и простые атрибуты, ассоциации управляются либо вручную через графический интерфейс, либо, что предпочтительнее, автоматически с использованием маппингов.
Исходящие маппинги#
Исходящие маппинги берут информацию из фокусного объекта (например, пользователя) и используют ее для создания значения или значений данной ассоциации.
Наиболее типичным сценарием является получение членства пользователя в роли и использование каждой роли, которая имеет соответствующую группу в качестве своего проецирования на данный ресурс, в качестве целевого объекта ассоциации.
Маппинг выглядит так:
Пример ассоциации исходной привязки
<associationType>
<name>userMembership</name>
<subject>
<objectType>
<kind>account</kind>
<intent>default</intent>
</objectType>
<association>
<ref>ri:group</ref>
<outbound>
<name>account-group-outbound</name>
<strength>strong</strength>
<expression>
<associationConstruction> (1)
<objectRef> (2)
<mapping>
<expression>
<associationFromLink/> (3)
</expression>
</mapping>
</objectRef>
</associationConstruction>
</expression>
</outbound>
</association>
</subject>
<!-- ... -->
</associationType>
1 — Это означает, что мы собираемся построить значение для этой ассоциации (хотя очень простое, состоящее из одной объектной ссылки).
2 — Это описывает значение создаваемой объектной ссылки.
3 — Это говорит о том, что мы должны определить его по членству в роли, как описано выше.
Вместо associationFromLink мы можем использовать любое другое выражение, которое возвращает объекты ShadowAssociationValueType в качестве своего вывода. Еще один типичный пример - это associationTargetSearch.
Важный вопрос здесь заключается в следующем: как IDM должен обрабатывать значения ассоциаций, которые существуют в ресурсе, но не предоставляются исходными привязками? Мы решаем эту проблему в разделе Толерантность к существующим значениям ассоциации ниже.
Маппинг входящих данных#
Маппинги входных данных принимают существующие значения ассоциации и создают или обновляют существующие значения в объекте фокусировки IDM (например, пользователь).
Этот процесс более сложен, чем может показаться. Возможно выполнять более точные обновления: выбирать значения, которые должны быть обновлены, и обновлять их содержимое.
Для этой цели используется associationSynchronization оценщик выражений. Он выглядит так:
Пример входящего маппинга ассоциации
<associationType>
<name>userMembership</name>
<subject>
<objectType>
<kind>account</kind>
<intent>default</intent>
</objectType>
<association>
<ref>ri:group</ref>
<inbound>
<name>account-group-inbound</name>
<strength>strong</strength>
<expression>
<associationSynchronization> (1)
<objectRef> (2)
<correlator/>
<mapping>
<expression>
<shadowOwnerReferenceSearch/> (3)
</expression>
<target>
<path>targetRef</path> (3)
</target>
</mapping>
</objectRef>
<synchronization>
<reaction>
<situation>unmatched</situation>
<actions>
<addFocusValue/>
</actions>
</reaction>
<reaction>
<situation>matched</situation>
<actions>
<synchronize/>
</actions>
</reaction>
</synchronization>
</associationSynchronization>
</expression>
</inbound>
</association>
</subject>
</associationType>
1 — Это означает, что мы собираемся синхронизировать значения ассоциаций в фокусный объект.
2 — Значение ассоциации имеет (потенциально) много элементов. Здесь мы говорим, что собираемся обработать ссылку на объект. (Для этой конкретной ассоциации существует только одна, поэтому нет необходимости указывать ее имя.)
3 — Это означает, что мы собираемся взять значение ассоциации объекта (обычно группы), найти его владельца в IDM (обычно роль) и поместить его ссылку на элемент назначения targetRef.
Основной элемент маппинга (shadowOwnerReferenceSearch) отражает associationFromLink оценщика, используемого для исходящих маппингов. Основное отличие от направления передачи наружу, однако, заключается в части synchronization. Давайте объясним.
Синхронизация ассоциации работает следующим образом:
Прежде всего, в настоящее время это ограничено назначениями. Таким образом,
associationSynchronizationоценщик всегда нацелен на задания фокусировки. Если вы хотите сопоставить ассоциацию с другим элементом, вам необходимо использовать другой оценочный калькулятор.После получения значения ассоциации оценщик пытается определить, какому назначению соответствует это значение. Это фактически очень похоже на процесс корреляции учетных записей с объектами фокуса. Поэтому конфигурация также аналогична. В приведенном выше примере
correlatorэлемент используется для обозначения ссылки на объект (или, точнее, соответствующего элемента фокуса -targetRef) в качестве коррелятора. Эквивалентная, хотя и более многословная, конфигурация выглядела бы так:Пример явного указания корреляции
<associationSynchronization> <objectRef> <mapping> <!-- ... --> </mapping> </objectRef> <correlation> <correlators> <items> <item> <ref>targetRef</ref> (1) </item> </items> </correlators> </correlation> <synchronization> <!-- ... --> </synchronization> </associationSynchronization>1 — Это обозначает
targetRefкак элемент, используемый для корреляции.После завершения корреляции возможны три результата:
не найдено подходящих назначений (
unmatchedситуация синхронизации),найдено подходящее назначение (
matchedситуация синхронизации),не найдено подходящего назначения, но есть соответствующее косвенное значение членства в роли (
indirectlyMatchedситуация синхронизации).
Соответствующее действие синхронизации выбирается на основе конфигурации. В настоящее время доступны следующие действия:
addFocusValue: создается новое назначение, основанное на значении ассоциации. Используется для ситуацииunmatched.synchronize: существующее назначение обновляется на основе значения ассоциации. Используется для ситуацииmatched.
Могут возникнуть ситуации, когда ранее существовавшее значение ассоциации больше не существует. Как входная схема определяет, следует ли сохранить назначение, которое было (предположительно) создано из этого значения, или нет? Она использует тот же механизм, что и другие сопоставления, нацеленные на многозначные элементы: диапазоны. По умолчанию метаданные происхождения используются для определения того, какие назначения были созданы этой конкретной схемой сопоставления; и стандартным поведением является их удаление после прекращения схемы сопоставления производить их в качестве своего вывода.
Толерантность к существующим значениям ассоциаций#
Давайте вернемся к вопросу о том, как IDM узнает, какие значения ассоциаций, присутствующие на ресурсе, следует оставить, а какие удалить, если они не предоставляются фактическими выходными маппингами.
Традиционно существует флаг tolerant, который управляет этим поведением для атрибутов. Этот же флаг присутствует для ассоциаций и устанавливается следующим образом:
Установка толерантности к ассоциациям
<associationType>
<name>userGroupMembership</name>
<subject>
<objectType>
<!-- ... -->
</objectType>
<association>
<ref>ri:group</ref>
<!-- ... -->
<tolerant>false</tolerant>
</association>
</subject>
</associationType>
Как и для атрибутов, значение по умолчанию равно true, что означает, что допускаются дополнительные значения. Приведенный выше пример устанавливает допуск до false, так что любые дополнительные значения ассоциации удаляются.
Однако допуск может быть переопределен для каждого отдельного значения ассоциации. В настоящее время это поддерживается для простых ассоциаций и управляется меткой объекта(ами), присутствующей на объекте ассоциации объекта, например, группе.
Например, предположим, что у группы guests есть метка тени Unmanaged, поскольку она в данный момент управляется самим ресурсом.
Метка для «неуправляемых» теней
<mark xmlns="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
oid="00000000-0000-0000-0000-000000000805">
<name>Unmanaged</name>
<documentation>
Marks a shadow that is tolerated by IDM but not managed by it.
IDM should not create, modify, nor delete such objects (at the low level).
IDM should not execute outbound mappings on such objects.
IDM should not manage membership of these objects (if applicable; e.g., for groups).
</documentation>
<!-- ... -->
<objectOperationPolicy>
<!-- ... -->
<synchronize>
<!-- ... -->
<membership>
<!-- ... -->
<tolerant>true</tolerant>
</membership>
</synchronize>
</objectOperationPolicy>
</mark>
Также предположим, что допуск для ассоциации установлен на false.
Когда значение ассоциации, указывающее на группу guests, присутствует в ресурсе, но не предоставляется ни одной внешней схемой (которая отключается меткой Unmanaged в любом случае), оно допускается, потому что значение true в метке объекта переопределяет значение false, установленное в ассоциации.
Допуск, дельты и согласование#
IDM может удалять значения ассоциаций даже при включенной настройке tolerant. Причина заключается в том, что большинство операций IDM основаны на дельтах. Например, если пользовательский интерфейс используется для добавления или удаления назначения, создается дельта, которая отправляется в качестве параметра операции. В этом случае мы знаем, что изменилось. Поэтому мы можем легко добавлять и удалять членство в привилегиях. Мы можем сделать это даже в том случае, если привилегия установлена на терпимую. Мы можем делать это потому, что знаем, что последнее назначение, которое «вызвало» эту группу, было только что удалено.
Но ситуация другая для согласования и перерасчета. Например, в случае изменения определения роли. На самом деле существует две операции: изменение роли, а затем согласование пользователя. Эти операции независимы. Поэтому для второй операции нет дельты. IDM не знает, что изменилось в роли. Поэтому он не может использовать ту же логику для удаления пользователя из привилегии. Немного другая логика используется при согласовании. Логика, которая не основана на дельтах (потому что их нет). И в этом случае флаг толерантности важен. Если он установлен на true, то IDM не будет удалять дополнительные значения из атрибута или дополнительных привилегий. Если установлено значение false, то IDM удалит их.
Для того чтобы эти операции работали правильно даже во время согласования, важно установить свойство tolerant. Пожалуйста, убедитесь, что у вас ассоциация настроена на нетолерантную в разделе schemaHandling определения ресурса.
Также, пожалуйста, убедитесь, что ваши маппинги имеют силу strong. Соответствия, которые имеют «нормальную» силу, по своей сути основаны на дельтах, и они обычно не обрабатываются при согласовании вообще. Для «нормальных» сопоставлений последняя модификация побеждает. Но при согласовании у нас нет представления о том, какая была последней модификацией - та ли, что на ресурсе, или та, что в IDM. Поэтому мы предпочитаем консервативный подход и скорее поддерживаем статус-кво.
Маппинги атрибутов ссылок#
Мы описали маппинги для ассоциаций. В случае атрибутов-ссылок, они являются всего лишь средством реализации ассоциаций, ими не предполагается управлять напрямую: ни в графическом интерфейсе (может быть, за исключением чрезвычайных ситуаций), ни через маппинги.
Ассоциации/ссылки против атрибутов#
Некоторые развертывания IDM могут столкнуться с дилеммой, следует ли использовать ассоциации (основанные на ссылочных атрибутах) или просто обычные атрибуты. Например, если есть читаемый и изменяемый groups простой атрибут для учетных записей, мы можем задаться вопросом, должны ли мы управлять им как простым многозначным атрибутом без определения какой-либо ссылки или ассоциации над ним. Однако существуют два аргумента в пользу ассоциаций/ссылок:
Ассоциации и ссылки умны. Ссылки знают, что их значения должны представлять группы; тогда как простые атрибуты видят просто обычные строки, не зная, что они представляют, например, имена групп. Пользовательский интерфейс IDM может использовать эту информацию из ссылочного атрибута для перечисления всех доступных групп, когда пользователь хочет добавить новые значения ссылочных атрибутов (или ассоциаций). Затем пользователь просто выбирает значение(я) из списка. Нет необходимости вводить имя группы вручную.
Ссылки объект-предмет очень трудно моделировать как простые атрибуты. В этом случае атрибут, который необходимо изменить, фактически находится в другом объекте. IDM пытается изолировать операции до одного объекта (или набора связанных объектов). Поэтому моделирование ссылок объект-предмет с использованием простых атрибутов может быть очень сложным. Симулированные (или родные соединителю) ссылки делают это очень простым.