суббота, 2 мая 2015 г.

Упрощение Single Sign On в Office 365

На просторах Интернета можно найти множество инструкций по настройке Single Sign On в Office 365. Вот один из хороших примеров:

https://technet.microsoft.com/en-us/magazine/jj631606.aspx

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

image

Я считаю, это не очень удобно для пользователя, и к счастью, я нашел обходной путь для этого.

Мы можем указать определенный Url в качестве домашней страницы браузера с помощью групповой политики. Например, если мы хотим направить пользователя на узел SharePoint, как https://sapozhkovtest.sharepoint.com, а суффикс upn (домен пользователя) sapozhkov.net, тогда нам нужно указать следующий адрес в качестве страницы по умолчанию с помощью групповой политики:

https://login.microsoftonline.com/?whr=sapozhkov.net&wreply=https:%2f%2fsapozhkovtest%2esharepoint%2ecom

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

Проблема: учетные записи не синхронизируются из AD в SharePoint multitenant User Profile Service Application

Столкнулся с такой проблемой на проекте.

В AD у заказчика вложенные OU для каждой дочерней организации:

Domain
   Customers
      Customer1
         Users
            User1
            User2
      Customer2
         Users
            User3
            User4

SharePoint build: 15.0.4693.1000

Profile service создан с использованием ключа -PartitionMode, т.е. база данных поделена на разделы. Каждая организация(SiteSubscription) имеет свой раздел.

Специальная команда PowerShell для создания раздела запущена для каждой организации:

Add-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU ‘Customer1’

Коннектор синхронизации создан и OU “Customers” выбран.

 

Полная синхронизация выполняется без единой ошибки, в центре администрирования все выглядит обещающе:

MOSS
Stage SharePoint Server import
Additions 3311
Updates 46
Unchanged 0
.............................
Successes 3357
Failures 0
Start Time 4/30/2015 11:00:03 PM
End Time 4/30/2015 11:01:58 PM

Несмотря на это ни один профиль не создан. ULS чист, как и журнал приложений и miisclient. Абсолютно.

Я начал подозревать несколько вероятных источников проблемы, и решил провести несколько экспериментов. И хотя это заняло приличное время, я думаю, оно не потрачено зря, т.к. теперь Вам не придется тратить время. Просто можете ознакомиться с описанием экспериментов, сделанных мной.

Тест 1. Грубая попытка

Моими первыми подозрениями были:

  1. SharePoint проверяет только название непосредственно родительского OU, когда распределяет пользователей по разделам.
  2. SharePoint сравнивает OU, указанное для SiteSubscription с OU, отдельно отмеченное при настройке коннектора синхронизации
  3. После того, как учетная запись импортирована в SharePoint но не приписана к определенному разделу, при следующих синхронизациях в любом случае учетная запись будет игнорирована, т.к. на стороне AD не произошло изменений учетной записи, т.е. нечего реплицировать.

Я сделал 2 изменения:

  1. Удалил коннектор и создал новый, выделив отдельно OU каждой организации. Т.е. я отметил “Customer1”, “Customer2”, и т.д., вместо того, чтобы выделить один родительский “Customers” целиком, как я делал в прошлый раз, когда синхронизация провалилась.
  2. Выполнил следующую PowerShell команду для привязки прямого родительского OU с пользователями:
    Set-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU ‘Users’

Затем я запустил полную синхронизацию.

В результате я получил всех пользователей из всех OU “Users” в одном разделе (к которому я и применил команду).

Чтобы просмотреть количество профилей, привязанных к каждому SiteSubscription, я использовал следующий PowerShell скрипт:

Foreach ( $sub in ( Get-SPSiteSubscription ) )
{
    $sub
    $serviceContext = Get-SPServiceContext -SiteSubscription $sub
    $profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager( $serviceContext );
    $profileManager.Count
}

Вывод:

SharePoint сравнивает только название прямого родителя при фильтрации пользователей.

Тест 2. Поиск корректной привязки

Теперь я решил найти способ привязки точно заданного OU “Users” к кажому подписчику. Т.е. каждому SiteSubscription должен быть назначен определенный OU “Users”.

Но для начала мне нужно было удалить профили, созданые на предыдущем этапе:

Remove-SPSiteSubscriptionProfileConfig -id <SiteSubscription>

Далее я начал применять различные формы указания на OU:

'Customer1\Users'
'Customer1/Users'
'Customer1*'
'Users,OU=Customer1’
'DomainName/Customers/Customer1/Users'
'*Customer1'

Например,

Set-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU 'Customer1\Users’

Я указал данные значения для разных подписчиков и снова запустил полную синхронизацию.

Ни одного профиля не было создано.

Вывод (предварительный):

Единственный известный способ связывания OU с SiteSubscription это указывать атрибут “name” OU. Например, “Users”.

Тест 3. Очистка

Да, эта правда была не из тех, которую я предпочитал, но меня никто не спросил.

Раз я уже начал эксперименты, я решил получить чуть больше результатов.

Вот очередное подозрение, которое я захотел развеять:

Возможно, пользователи не были созданы в предыдущем тесте (даже с любыми мыслимыми формулировками OU) по простой причине: Они не были изменены и нет изменений, которые требуется реплицировать в профили SharePoint.

Я снова связал одного из подписчиков с OU “Users”:

Set-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU ‘Users’

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

Вывод:

Нет необходимости заново создавать коннектор при изменении привязки OU. Достаточно запустить полную синхронизацию.

Тест 4. Что отмечать

Единственное, что осталось выяснить: есть ли зависимость от уровня OU, который отмечен в коннекторе синхронизации.

В последних тестах были специально отмечены OU организаций, такие как “Customer1”, “Customer2” и т.д. Я изменил коннектор и отметил только родительский OU, “Customers”.

Так же мне пришлось снова удалить профили с использованием команд Remove-SPSiteSubscriptionProfileConfig и Add-SPSiteSubscriptionProfileConfig.

Полный импорт снова создал все профили в заданном разделе.

Вывод:

Не имеет значения как выбирать OU в коннекторе – один родительский OU или все дочерние. То же самое для multitenat приложения службы профилей.

Further investigation

Теперь, когда я стал более уверенным в том что для фильтрации учетных записей используется только название непосредственного родительского OU, я смог найти похожие истории в Интернете:

Тут Патрик нашел SQL-процедуру в базах данных SharePoint которая выполняет эту “умную” привязку:

https://rompenpatrick.wordpress.com/2011/09/16/error-during-profile-import-completed-export-error-ma-extension-error/

И в этой статье есть ссылка на форум, который сообщяет

The developent team (Microsoft support) canned the fix. This functionality will not be part of the CU2 updates or any future updates. They thought it worked as designed.

По-русски это означает, что разработчики Microsoft законсервировали фикс. Они считают, что все работает так как было задумано.

https://social.msdn.microsoft.com/Forums/office/en-US/e2ac0ff2-0255-4874-9410-5294228a4ece/multi-tenant-user-profile-sync-issue?forum=sharepointgeneralprevious

Решение

Пока что нет. Я не нашел пока что хорошего решения в сложившейся ситуации. Такое поведение означает что мы должны реструктурировать AD. И честно говоря, это врядли возможно, т.к. заказчик использует внешнюю систему управления структурой AD и объектами. Я надеюсь, что я еще вернусь к этому посту и обновлю его хэппи эндом. В другой раз. Спасибо за чтение!

P.S.

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