Использование службы Secure Store в настраиваемом поставщике утверждений с SharePoint 2010
Недавно, используя службу Secure Store (SSS) в настраиваемом поставщике утверждений, над которым я работал, я заметил необычный прием. Это действительно интересный сценарий, так как я делал то, что многих интересует, — настраиваемое расширение утверждений. Мне было нужно подключить удаленный источник данных, чтобы я мог запросить определенные дополнительные сведения о каждом пользователе, а затем использовать их, чтобы определить, расширять ли утверждения или нет.
В качестве общей рекомендации по использованию источников данных в настраиваемых поставщиках утверждений важно помнить, что сборка настраиваемого поставщика утверждений будет удерживаться в памяти процессом STS SharePoint. Это позволяет заметно упростить получение "сведений" — будь это набор данных, набор учетных данных и т. д., храня их в переменной уровня класса и делая их доступными для использования до следующего вызова IISRESET. Большим ограничением является то, что не все ресурсы фермы SharePoint могут быть доступны, когда создан экземпляр настраиваемого поставщика утверждений, и именно в этом мораль сегодняшнего рассказа.
В данном конкретном случае я хотел получить данные из SSS в конструкторе для своего настраиваемого поставщика утверждений для дальнейшего использования. В моем случае я создавал WindowsIdentity из домена, используя одностороннее доверие, чтобы я мог использовать его для создания контекста олицетворения, обладающего разрешениями на запрос к удаленному каталогу Active Directory. Проблема возникла, когда я попытался выполнить что-то с моей ссылкой на SSS в конструкторе, — ВСЕГДА истекало время ожидания. Неважно, какой метод вызывался для SSS, вызов всегда заканчивался неудачей через 60 секунд с ошибкой времени ожидания.
Для исправления было достаточно просто вынести код из конструктора. Тот же самый код, вызываемый из моего переопределения метода FillClaimsForEntity, прекрасно работал. Это решение, полученное методом проб и ошибок, оказалось действительно удачным, поэтому, как мне кажется, стоит поделиться этим советом.
Возможно, стоит упомянуть и о другом подходе, который я вынес из этого способа решения данной конкретной проблемы (вход в удаленный домен и олицетворение).
Как описано выше, так как сборка остается загруженной в процессе STS, можно сохранить актуальные данные в переменных уровня класса. Так как мне, очевидно, не хотелось снова и снова входить в удаленный домен всякий раз, когда мне нужно обратиться к нему, я создал переменную уровня класса для моего удостоверения WindowsIdentity. Этот подход работает примерно так:
- Проверяю, получил ли я уже учетные данные SSS
- Если нет, выполняю код, который:
- Возвращает учетные данные из SSS
- Использует интерфейс LogonUser API для входа в удаленный домен, используя учетные данные, полученные из SSS
- Создаю экземпляр переменной WindowsIdentity, чтобы хранить в ней учетные данные удаленного пользователя
- Если нет, выполняю код, который:
- Проверяю, содержит ли моя переменная WindowsIdentity значение null или нет
- Если нет, выполняю код, который:
- Создает новый экземпляр WindowsImpersonationContext из WindowsIdentity.Impersonate()
- Запрашиваю удаленный домен
- Вызываю отмену (Undo) для моего экземпляра WindowsImpersonationContext
- Если нет, выполняю код, который:
Кажется, что этот шаблон работает хорошо и почти с той же скоростью, какую я мог из этого выжать. И вот что получается в результате — НЕ нужно вызывать Impersonate() для своего экземпляра WindowsIdentity, а затем НЕ вызывайте отмену (Undo) для полученного контекста WindowsImpersonationContext. Если не отменить олицетворение, то по моему опыту сайт больше не будет отображаться. Добавьте вызов Undo обратно, и все начнет работать снова.
Это локализованная запись блога. Исходная статья доступна по адресу: Using Secure Store Service in a Custom Claims Provider with SharePoint 2010