. В конечном итоге вы сможете читать правила для заявок, понимать их функции и создавать собственные правила.

Основные положения

Прежде чем перейти к углубленному изучению языка, позволяющего выдавать заявки и работать с ними, ознакомимся с основными понятиями. Заявка – это информация о пользователе из доверенного источника. Доверенный источник гарантирует, что информация является истинной, и что подлинность пользователя тем или иным образом проверена. Поставщик заявки – это источник заявки. Это может быть информация, извлекаемая из хранилища атрибутов (например, Active Directory (AD)), или партнерская служба федерации. Проверяющая сторона – это адресат заявки. Это может быть приложение (например, Microsoft SharePoint) или партнерская служба федерации.

В качестве простого сценария можно рассматривать выполняемую AD FS проверку подлинности пользователя, когда его атрибуты извлекаются из AD, а затем пользователь направляется к нужному приложению. Этот сценарий можно усложнить путем добавления партнерских служб федерации. Однако любой сценарий предполагает получение информации в одном месте и ее отправку в другое место. На приведенном рисунке показан пример взаимоотношений между серверами федерации и приложением.

 

Пример взаимоотношений между серверами федерации и приложением
Рисунок. Пример взаимоотношений между серверами федерации и приложением

Наборы заявок

Наборы заявок необходимо рассматривать в отношении к потоку заявок. Набор входящих заявок составляют входящие заявки. За обработку правил, установленных для заявок, отвечает процессор заявок. Он анализирует набор входящих заявок на наличие соответствий и при необходимости выдает исходящие заявки. Исходящие заявки составляют набор исходящих заявок. Поскольку для поставщиков заявок и проверяющих сторон предусмотрены правила, установленные для заявок, то существуют и наборы заявок, связанные с каждым из них.

  1. Заявки поступают к доверенному поставщику заявок как набор входящих заявок.
  2. Правила, установленные для заявок, обрабатываются, и результат обработки становится частью набора исходящих заявок.
  3. Набор исходящих заявок направляется проверяющей стороне, для которой он становится набором входящих заявок.
  4. Правила, установленные для заявок, обрабатываются, и результат обработки становится частью набора исходящих заявок.

Основной синтаксис языка правил для заявок

Правило для заявок состоит из двух частей: инструкции условия и инструкции выдачи. Если инструкция условия выдает значение «истина», то выполняется инструкция выдачи. В примере правила для заявки на экране 1 на входе – заявка подразделения Contoso, а на выходе – заявка подразделения Adatum с тем же значением. Такие типы заявок – универсальные коды ресурсов (URI) в формате HTTP. URI – это не URL и не должен быть страницей, доступной в сети Интернет.

 

Пример правила для заявки
Экран 1. Пример правила для заявки

Инструкция условия

Когда правило активируется, процессор заявок анализирует все данные в текущем наборе входящих заявок согласно инструкции условия. В инструкции условия может использоваться любое свойство заявки, но наиболее распространенными являются тип и значение заявки. Инструкция условия имеет формат c:[запрос], где переменная c представляет собой текущую заявку в наборе входящих заявок.

Простая инструкция условия

c:[type == «http://contoso.com/department»]

определяет поиск входящих запросов, отвечающих типу http://contoso.com/department, а инструкция условия

c:[type == «http://contoso.com/department», value == «sales»]

определяет поиск входящих запросов, отвечающих типу http://contoso.com/department и имеющих значение sales. Инструкция заявки не является обязательной. Для заявок, рассылаемых всем, достаточно создать инструкцию выдачи.

Инструкция выдачи

Существует два типа инструкции выдачи. Инструкция ADD предусматривает добавление заявки в набор входящих заявок, но не в набор исходящих заявок. Типовое применение инструкции ADD – сохранение данных, которые войдут в последующие правила для заявок. Инструкция ISSUE предусматривает добавление заявки во входящий и исходящий наборы заявок. В примере инструкции ISSUE

=> issue(type = «http://contoso.com/department», value = «marketing»);

выдается заявка, отвечающая типу http://contoso.com/department, со значением marketing. В примере инструкции ADD

=> add(type = «http://contoso.com/partner», value = «adatum»);

добавляется заявка, отвечающая типу http://contoso.com/partner, со значением adatum. Инструкция выдачи может извлекать информацию из заявки, найденной на основе инструкции условия, либо использовать статическую информацию. В примере использования статических данных

c:[type == «http://contoso.com/emailaddress»]
=> issue(type = «http://contoso.com/role», value = «Exchange User»);

ищется входящая заявка, отвечающая типу http://contoso.com/emailaddress. Если такая заявка найдена, то выдается заявка http://contoso.com/role со значением Exchange User. В примере использования статических данных

c:[type == «http://contoso.com/role»]
=> issue(claim = c);

ищется входящая заявка типа http://contoso.com/role. Если такая заявка найдена, то в набор исходящих заявок выдается в точности такая же заявка. В примере извлечения данных из заявки

c:[type == «http://contoso.com/role»]
=> issue(type = «http://adatum.com/role», value = c.Value);

ищется входящая заявка типа http://contoso.com/role. Если такая заявка найдена, то в набор исходящих заявок выдается в точности такая же заявка.

Несколько условий

В инструкции условия можно использовать несколько условий. В этом случае инструкция выдачи активируется только при выполнении всех условий. Каждое новое условие добавляется с помощью оператора &&. В примере

c1:[type == «http://contoso.com/role», value==«Editor»] &&
c2:[type == «http://contoso.com/role», value==«Manager»]
=> issue(type = «http://contoso.com/role», value = «Managing Editor»);

ищется входящая заявка типа http://contoso.com/role со значением Editor и заявка типа http://contoso.com/role со значением Manager. Если процессор заявок находит заявки, отвечающие обоим условиям, то выдается заявка типа http://contoso.com/role со значением Managing Editor.

Значения заявок, фигурирующие в условиях, добавляются с использованием оператора +. В примере

c1:[type == «http://contoso.com/location»] &&
c2:[type == «http://contoso.com/role»]
=> issue(type = «http://contoso/targetedrole», value = c1.Value + «" c2.Value);

ищется входящая заявка типа http://contoso.com/location и другая заявка типа http://contoso.com/role. Если обе таких заявки найдены, то выдается заявка типа http://contoso.com/targetedrole с комбинацией значений входящих заявок.

Групповые функции

До сих пор мы рассматривали правила для заявок, предусматривающие индивидуальную проверку каждой заявки или группы заявок и активацию инструкции всякий раз, когда выполнено заданное условие. Существуют, однако, обстоятельства, когда такой образ действий не эффективен. Например, требуется анализ всего набора заявок и выработка значения инструкции условия на основе результата этого анализа. В таких случаях можно использовать функции EXISTS, NOT EXISTS и COUNT. Функция EXISTS проверяет наличие входящих заявок, удовлетворяющих условию. Если такие заявки существуют, то правило активируется. Функция NOT EXISTS также проверяет наличие входящих заявок, удовлетворяющих условию, но правило активируется, если такие заявки не найдены. Функция COUNT подсчитывает число соответствий заданному условию в наборе входящих сообщений.

В примере функции EXISTS

EXISTS([type ==»http://contoso.com/emailaddress«])
=> issue(type =»http://contoso/role«, value =»Exchange User«);

ищутся входящие заявки типа http://contoso.com/emailaddress. Если хотя бы одна такая заявка найдена, то выдается заявка типа http://contoso.com/role со значением Exchange User. В примере функции NOT EXISTS

NOT EXISTS([type ==»http://contoso.com/location«])
=> add(type =»http://contoso/location«, value =»Unknown«);

ищутся входящие заявки типа http://contoso.com/location. Если ни одной такой заявки не найдено, то выдается заявка типа http://contoso.com/location со значением Unknown. В примере функции COUNT

COUNT([type ==»http://contoso.com/proxyAddresses«]) >= 2
=> issue(type =»http://contoso.com/MultipleEmails«, value =»True«);

ищутся входящие заявки типа http://contoso.com/proxyAddresses. Если найдено две или более таких заявок, то выдается заявка типа http://contoso.com/MultipleEmails со значением True.

Запросы к хранилищам атрибутов

По умолчанию при установке AD FS единственным создаваемым хранилищем атрибутов является AD. Для извлечения данных, используемых в заявках, можно запрашивать серверы LDAP или системы SQL Server. Чтобы использовать другое хранилище атрибутов, нужно сначала его создать, а затем ввести команду установления соединения. Экран 2 иллюстрирует назначение сервера LDAP в качестве хранилища атрибутов.

 

Выбор сервера LDAP в качестве хранилища атрибутов
Экран 2. Выбор сервера LDAP в качестве хранилища атрибутов

Когда хранилище создано, его можно запрашивать из правила для заявки. При использовании сервера LDAP в качестве хранилища атрибутов запрос должен иметь следующий формат:

query =;

Параметр, направляемый в запрос, представлен оператором {0}. При направлении нескольких параметров они должны быть представлены {1}, {2} и т.д. В примере

c:[Type ==»http://contoso.com/emailaddress«]
=> issue(
store =»LDAP STORE«,
types = (»http://contoso.com/attribute1«, "http://contoso.com/attribute2»),
query = «mail={0};attribute1;attribute2»,
param = c.Value
);

при совпадении адреса электронной почты у хранилища LDAP STORE запрашиваются атрибуты ‘attribute1’ и ‘attribute2’ и выдаются две заявки на основе данных, возвращенных в ответ на запрос.

Хранилище атрибутов SQL Server использует тот же основной формат языка правил для заявок; отличается лишь синтаксис запроса. В запросе используется стандартный формат Transact-SQL, а для передачи параметра применяется оператор {0}. В примере

c:[Type == «http://contoso.com/emailaddress»]
=> issue(
store = «SQL STORE»,
types = («http://contoso.com/attribute1», «http://contoso.com/attribute2»),
query = «SELECT attribute1,attribute2 FROM users WHERE email = {0}»,
param = c.Value
);

при совпадении адреса электронной почты у хранилища SQL STORE запрашиваются атрибуты 'attribute1’ и ‘attribute2’ и выдаются два заявки на основе данных, возвращенных в ответ на запрос.

Регулярные выражения

Использование регулярных выражений (RegEx) позволяет находить строки данных и манипулировать ими для получения желаемого результата. Без RegEx все сравнения или замены выполняются при условии точного совпадения. Во многих ситуациях это удобно, но если требуется выполнить поиск или замену на основе сопоставления по шаблону, то можно задействовать RegEx. Регулярное выражение использует поиск по шаблону и позволяет манипулировать данными внутри заявок.

Для выполнения поиска по шаблону двойной знак равенства (==) заменяется на =~, а в инструкции условия используются специальные метасимволы. Если вы не знакомы с RegEx, то следует начать с наиболее распространенных метасимволов. В таблице приведены основные метасимволы RegEx и их функции.

RegExReplace

 

Основные метасимволы RegEx и их функции

Поиск по шаблону RegEx также можно использовать в сценариях замены. Это аналогично алгоритму поиска и замены, реализованному во многих текстовых редакторах, но вместо точных значений здесь используется поиск по шаблону. Чтобы применить это в правиле для заявки, воспользуйтесь функцией RegExReplace() в секторе значения инструкции выдачи.

Функция RegExReplace имеет три параметра.

  • Первый – строка, в которой осуществляется поиск. Обычно требуется найти значение входящей заявки (c.Value), но это может быть и комбинация значений (c1.Value + c2.Value).
  • Второй – шаблон RegEx, который ищется в первом параметре.
  • Третий – строка, которая замещает найденные совпадения.

В примере RegExReplace

c:[type == «http://contoso.com/role»]
=> issue (Type = «http://contoso.com/role», Value = RegExReplace(c.Value, «(?i)director», «Manager»);

осуществляется поиск по всем заявкам роли. Если какая-либо заявка содержит слово Director, RegExReplace заменяет его на Manager. В частности, Director of Finance становится Manager of Finance.

Если преимущества поиска по шаблону RegEx скомбинировать с возможностями, которые обсуждались в статье ранее, то с помощью языка правил для заявок можно решать многие задачи.

Программирование собственных хранилищ атрибутов

AD FS предусматривает возможность подключения к собственному хранилищу атрибутов, если встроенные функциональные средства оказываются недостаточными для достижения актуальных целей. Можно задействовать стандартные коды. NET, например методы toUpper() и toLower(), или извлекать данные из любого источника посредством кода. Это должен быть код библиотеки классов, для которого необходимы ссылки на сборки Microsoft.IdentityModel и Microsoft.IdentityServer.ClaimsPolicy.

Создайте свое правило

Создание собственных правил на языке правил для заявок позволит вам повысить гибкость в выпуске и преобразовании заявок. Ознакомление с синтаксисом потребует некоторых усилий и времени, но по мере приобретения опыта процесс освоения значительно упростится. Для более углубленного изучения этого языка попробуйте составлять собственные правила вместо использования шаблонов.