Использование службы Secure Store в настраиваемом поставщике утверждений с SharePoint 2010

Недавно, используя службу Secure Store (SSS) в настраиваемом поставщике утверждений, над которым я работал, я заметил необычный прием. Это действительно интересный сценарий, так как я делал то, что многих интересует, — настраиваемое расширение утверждений. Мне было нужно подключить удаленный источник данных, чтобы я мог запросить определенные дополнительные сведения о каждом пользователе, а затем использовать их, чтобы определить, расширять ли утверждения или нет.

В качестве общей рекомендации по использованию источников данных в настраиваемых поставщиках утверждений важно помнить, что сборка настраиваемого поставщика утверждений будет удерживаться в памяти процессом STS SharePoint. Это позволяет заметно упростить получение "сведений" — будь это набор данных, набор учетных данных и т. д., храня их в переменной уровня класса и делая их доступными для использования до следующего вызова IISRESET. Большим ограничением является то, что не все ресурсы фермы SharePoint могут быть доступны, когда создан экземпляр настраиваемого поставщика утверждений, и именно в этом мораль сегодняшнего рассказа.

В данном конкретном случае я хотел получить данные из SSS в конструкторе для своего настраиваемого поставщика утверждений для дальнейшего использования. В моем случае я создавал WindowsIdentity из домена, используя одностороннее доверие, чтобы я мог использовать его для создания контекста олицетворения, обладающего разрешениями на запрос к удаленному каталогу Active Directory. Проблема возникла, когда я попытался выполнить что-то с моей ссылкой на SSS в конструкторе, — ВСЕГДА истекало время ожидания. Неважно, какой метод вызывался для SSS, вызов всегда заканчивался неудачей через 60 секунд с ошибкой времени ожидания.

Для исправления было достаточно просто вынести код из конструктора. Тот же самый код, вызываемый из моего переопределения метода FillClaimsForEntity, прекрасно работал. Это решение, полученное методом проб и ошибок, оказалось действительно удачным, поэтому, как мне кажется, стоит поделиться этим советом.

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

Как описано выше, так как сборка остается загруженной в процессе STS, можно сохранить актуальные данные в переменных уровня класса. Так как мне, очевидно, не хотелось снова и снова входить в удаленный домен всякий раз, когда мне нужно обратиться к нему, я создал переменную уровня класса для моего удостоверения WindowsIdentity. Этот подход работает примерно так:

  1. Проверяю, получил ли я уже учетные данные SSS
    1. Если нет, выполняю код, который:
      1. Возвращает учетные данные из SSS
      2. Использует интерфейс LogonUser API для входа в удаленный домен, используя учетные данные, полученные из SSS
      3. Создаю экземпляр переменной WindowsIdentity, чтобы хранить в ней учетные данные удаленного пользователя
  2. Проверяю, содержит ли моя переменная WindowsIdentity значение null или нет
    1. Если нет, выполняю код, который:
      1. Создает новый экземпляр WindowsImpersonationContext из WindowsIdentity.Impersonate()
      2. Запрашиваю удаленный домен
      3. Вызываю отмену (Undo) для моего экземпляра WindowsImpersonationContext

Кажется, что этот шаблон работает хорошо и почти с той же скоростью, какую я мог из этого выжать. И вот что получается в результате — НЕ нужно вызывать Impersonate() для своего экземпляра WindowsIdentity, а затем НЕ вызывайте отмену (Undo) для полученного контекста WindowsImpersonationContext. Если не отменить олицетворение, то по моему опыту сайт больше не будет отображаться. Добавьте вызов Undo обратно, и все начнет работать снова.

Это локализованная запись блога. Исходная статья доступна по адресу: Using Secure Store Service in a Custom Claims Provider with SharePoint 2010