Служба преобразования утверждений в маркеры безопасности windows

  • Remove From My Forums
  • Вопрос

  • Коллеги, добрый день!

    Планируем SharePoint 2016 сразу под продакшн. Для начала 300 пользователей. Правильно ли будет развернуть SQL Server 2014 и сервер SharePoint 2016 (single farm)?Будет ли проблема с масштабированием в дальнейшем?Допустим
    с разграничением ролей на серверах?

    • Изменено

      24 августа 2016 г. 8:49

Ответы

  • Добрый день,

    цитата:

    (single farm)?     
    Такой роли нет!!!

    В принципе нет ничего страшного установить SQL14  и сервер SharePoint2016 (с настраиваемой ролью)  на одной железке. Только памяти чуток более 24гб, а лучше 32.

    Ув. antsv,

    нет ничего хуже, в плане деградации производительности SharePoint, чем размещение SharePoint+SQL на одном сервере. Это для пробы, тестов, девелопмента можно так поступить, если ресурсов не хватает, и то для SP2010-2013…

    Если ставить сразу в продакшен, то железный сервер SQL + VM AD + VM SP !!!

    Да, конечно, поэкспериментировать то можно, у меня на ноутбуке 3 VM машины одновременно крутятся на Hyper-V и нормально — ADC (WS2008R2) + SQL Server 2014 (WS2012R2) + SP2013 (WS2012R2), но это все на Core i7,
    16Gb RAM, SSD диск.

    При размещении всего на одном сервере упретесь не в кол-во RAM, а в IOPS дисковой подсистемы!


    MS,MCTS,MCP,MCPD: SharePoint Developer 2010

    • Предложено в качестве ответа
      Maxim Shusharin
      26 августа 2016 г. 13:25
    • Помечено в качестве ответа
      Иван ПродановMicrosoft contingent staff, Moderator
      30 августа 2016 г. 5:36

  • (single farm)?      Такой роли нет!!!

    В принципе нет ничего страшного установить SQL14  и сервер SharePoint2016 (с настраиваемой ролью)  на одной железке. Только памяти чуток более 24гб, а лучше 32.

    Поскольку Шарик штука легко масштабируемая…….

    А по том по мере необходимости добавить WFE, app,  кэш и сервер поиска.

    Роль

    Выполняемые службы

    Настраиваемая

                                                            
                       

       

    • Вебприложение
      Microsoft     SharePoint Foundation

       

       

    • Входящая
      почта Microsoft     SharePoint Foundation

       

       

    • Поиск SharePoint Server

       

       

    • Распределенный кэш

       

       

    • Служба контроллера узла поиска

       

       

    • Служба параметров сайтов и запросов     поиска

       

       

    • Служба таймера рабочих процессов     Microsoft SharePoint Foundation

       

       

    • Центр администрирования

       

    Распределенный кэш

                              

       

    • Вебприложение
      Microsoft     SharePoint Foundation

       

       

    • Распределенный кэш

       

       

    • Служба преобразования утверждений в     маркеры безопасности Windows

       

    Сервер переднего плана

                                                               
                                                           
                                                           
          

       

       

       

    • Access
      Services

       

       

       

       

    • PerformancePoint Service

       

       

       

       

    • Веб-приложение Microsoft SharePoint     Foundation

       

       

       

       

    • Веб-служба управляемых метаданных

       

       

       

       

    • Служба Secure Store

       

       

       

       

    • Служба баз данных Access 2010

       

       

       

       

    • Служба графики Visio

       

       

       

       

    • Служба машинного перевода

       

       

       

       

    • Служба подключения к бизнес-данным

       

       

       

       

    • Служба преобразования утверждений в     маркеры безопасности Windows

       

       

       

       

    • Служба приложения сервера Project     Server

       

       

       

       

    • Служба профилей пользователей

       

       

       

       

    • Служба управления приложениями

       

       

    Приложение

                                                            
                                                            
                

       

    • Word Automation Services

       

       

    • Веб-приложение Microsoft SharePoint Foundation

       

       

    • Веб-служба управляемых метаданных

       

       

    • Входящая почта Microsoft SharePoint     Foundation

       

       

    • Служба Secure Store

       

       

    • Служба машинного перевода

       

       

    • Служба подключения к бизнес-данным

       

       

    • Служба преобразования PowerPoint

       

       

    • Служба преобразования утверждений в     маркеры безопасности Windows

       

       

    • Служба приложения сервера Project     Server

       

       

    • Служба профилей пользователей

       

       

    • Служба таймера рабочих процессов     Microsoft SharePoint Foundation

       

       

    • Служба управления приложениями

       

    Поиск

                                        

       

    • Поиск SharePoint Server

       

       

    • Служба контроллера узла поиска

       

       

    • Служба параметров сайтов и запросов     поиска

       

       

    • Служба преобразования утверждений в     маркеры безопасности Windows

       

    • Изменено
      antsv
      24 августа 2016 г. 11:54
    • Предложено в качестве ответа
      antsv
      25 августа 2016 г. 10:05
    • Помечено в качестве ответа
      Иван ПродановMicrosoft contingent staff, Moderator
      30 августа 2016 г. 5:37

  • Remove From My Forums
  • Question

  • I am trying to implement windows integrated authentication for report’s data sources in SP2010 integrated SSRS installation for multi-tenant web application.
    So I used claims authentication mode for main web application and kerberos constrained delegation for all service applications. And I stucked with windows authentication mode for SSRS 2008 r2 integration in Sharepoint 2010 and windows integrated authentication
    in data sources. I get an error when I am trying to open a report: «Cannot impersonate user for data source ‘DataSource1’. (rsErrorImpersonatingUser)
    This data source is configured to use Windows integrated security. Windows integrated security is either disabled for this report server or your report server is using Trusted Account mode. (rsWindowsIntegratedSecurityDisabled)».
    As far as I know it is incompatibility of SSRS 2008 r2 with claims authentication model of Sharepoint 2010 (http://msdn.microsoft.com/en-us/library/ff487970%28v=SQL.105%29.aspx). But I can’t move to stored credentials in data sources cause security reason. Next
    I tryed CTP1 version of SQL Server «Denali» and I got the same error.
    It is really sad and frustrating result. Do anyone have any ideas about how does it can be implemented? 

Answers

  • Hello,

    Referring to the artcile,

    Claims Authentication and Reporting Services

    http://msdn.microsoft.com/en-us/library/ff487970(v=SQL.105).aspx

    As of now, we support windows claim only (Reporting Services 2008 R2) for the web app scenario, with kerberos and constrained delegation for SSRS Service.

    From the link above,

    Windows Authentication

    Claims Based Authentication

    Yes. The Reporting Services proxy will fallback to use Trusted Account authentication.

    Have you tried using the conversion services to have the claim tokens converted to windows token, as discussed here:

    Configure forms-based authentication for a claims-based Web application (SharePoint Server 2010)

    http://technet.microsoft.com/en-us/library/ee806890.aspx

    Does this help?

    Thanks.


    Meer Al — MSFT

    • Proposed as answer by

      Sunday, September 11, 2011 2:37 PM

    • Marked as answer by
      Margriet Bruggeman
      Monday, April 23, 2012 12:35 PM

Search code, repositories, users, issues, pull requests…

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Cтатья «Экспресс-курс по изучению WIF», опубликованная в предыдущем номере журнала, в которой содержится обзор возможностей платформы Windows Identity Foundation (WIF), стала прологом этой новой рубрики, посвященной проблемам безопасности на основе утверждений и федеративной безопасности

. В материалах рубрики я буду исходить из того, что читатели, по меньшей мере, знакомы с участниками и потоком коммуникации в модели федеративной безопасности. В этой статье я хочу уделить основное внимание конкретному сценарию, связанному с активной интеграцией с клиентами Windows и службами Windows Communication Foundation (WCF): с кэшированием маркеров и совместным их использованием несколькими посредниками, или proxy, с целью сокращения циклов обращения к службе Security Token Service (STS).

Сценарий кэширования маркеров

Вы неизбежно столкнетесь с такими ситуациями, когда возникает необходимость повторного использования или кэширования маркеров безопасности в клиентах Windows. На рисунке 1 представлена картина сценария, в котором посредник для CustomersService подтверждает права доступа в службе STS и получает маркер, передаваемый в дальнейшем OrdersService и ReportingService.

Рисунок 1. Совместное использование несколькими посредниками маркеров, выданных службой STS

Цель состоит в том, чтобы при инициализации нескольких посредников для ряда федеративных служб, то есть использующей стороны, или Relying Party (RP), запрос на ввод учетных данных направлялся пользователю не более одного раза. Следует также избегать ненужных обращений к STS с запросами на маркер безопасности для нескольких посредников. Полезно избегать дополнительных обращений к STS и при воссоздании proxy, если время использования канала истекает либо он выходит из строя.

Конкретное содержание утверждений в маркере не относится напрямую к теме статьи, однако стоит отметить, что, поскольку маркеры создаются для определенной использующей стороны (RP), они могут совместно применяться всеми службами RP лишь при соблюдении следующих условий:

  • службы RP должны пользоваться одним и тем же сертификатом службы;
  • служба STS должна иметь данные, касающиеся всех релевантных адресов RP, используемых в атрибуте AppliesTo маркера Request for Security Token (RST), и обладать возможностью выдачи маркера с утверждениями, которые будут полезны во всех службах использующей стороны;
  • когда маркеры выдаются для одной службы RP, они могут быть приняты другой службой лишь в том случае, если эта первая служба допускает применение маркеров, которые могут содержать элемент AudienceUri, указывающий на одну из оставшихся служб RP.

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

ClientCredentials и выданные маркеры

Каждый посредник (канал) экспонирует свойство ClientCredentials, которое используется с целью предоставления данных, необходимых для подтверждения прав доступа к службе. К примеру, перед первым обращением к службе можно указать свойства Windows, UserName или ClientCertificate типа ClientCredentials. Синтаксис указания учетных данных UserName иллюстрируется следующим кодом:

CustomersProxy proxy =
   new CustomersProxy ();
proxy.ClientCredentials.UserName.
   UserName = this.Username;
proxy.ClientCredentials.UserName.
   Password = this.Password;

При организации федеративной безопасности соответствующие учетные данные Windows, UserName или ClientCertificate устанавливаются в том случае, если предполагается, что оконечные точки STS будут подтверждать полномочия пользователей, обладающих одним из этих типов учетных данных (не будем забывать, что существуют и другие варианты аутентификации, такие как HttpDigest или еще одно свойство IssuedToken от связанной службы STS). Кроме того, тип ClientCredentials экспонирует свойство IssuedToken, которое предоставляет данные об использующей права доступа службе STS, такие как ее адрес и обязательные требования. Эти сведения можно инициализировать программным путем; однако, когда вы генерируете proxy в соответствии с моими разъяснениями, данная информация инициализируется федеративной связывающей конструкцией. На рисунке 2 показано, как запрашивается выданный маркер.

Рисунок 2. Запрос на выданный маркер с помощью IssuedSecurityTokenProvider

Посредник имеет ссылку на экземпляр ClientCredentials и предоставляет учетные данные пользователя, необходимые для подтверждения прав доступа к STS. Среда выполнения запускает метод CreateSecurityTokenManager () свойства ClientCredentials для создания класса SecurityTokenManager, а точнее — класса ClientCredentials­SecurityTokenManager. Тип Security­TokenManager отвечает за инициализацию, аутентификацию и сериализацию маркеров. В данном сценарии нам нужно переопределить процедуру инициализации маркеров. Тип SecurityTokenManager содержит реализацию для Create­SecurityTokenProvider (), обеспечивающую формирование соответствующего поставщика маркеров, который берет на себя поставку маркеров для всех исходящих вызовов. В данном случае класс IssuedSecurityTokenProvider используется для запроса выданного маркера от службы STS, указанного в конструкции ClientCredentials. В дальнейшем с помощью этого маркера осуществляется вызов службы.

Свойство IssuedToken конструкции ClientCredentials представляет собой экземпляр типа IssuedToken­ClientCredential. Этот тип имеет свойство CachedIssuedTokens, позволяющее управлять кэшированием маркеров. По умолчанию данному свойству задается значение true; это означает, что маркеры будут храниться в кэше до истечения срока их действия и повторно использоваться для обращения к службе, что избавляет от необходимости неоднократной проверки прав доступа к STS. Таким образом снижается уровень непроизводительных расходов для отдельного proxy, но возможности использовать этот кэшированный маркер в нескольких посредниках такой механизм не предоставляет. Для реализации упомянутой возможности вы можете создать пользовательский классс IssuedSecurityTokenProvider, который будет извлекать маркер из кэша общего доступа (если требуемый маркер существует), избегая вызова STS для каждого proxy.

Кэширование выданных маркеров для нескольких посредников

Чтобы создать кэш совместно используемых маркеров на клиенте, вы можете сформировать пользовательский класс IssuedSecurity­TokenProvider, который не будет обращаться к службе STS с запросом на маркер, не проверив предварительно локальный кэш маркеров. Для установки настраиваемого класса IssuedSecurityTokenProvider потребуется также создать настраиваемые типы ClientCredentials­SecurityTokenManager и Client­Credentials. Настраиваемый тип Client­Credentials может совместно использоваться различными посредниками, если требования конструкции идентичны, и это приведет оба proxy к одному настраиваемому классу IssuedSecurityTokenProvider, а значит, и к одному кэшированному маркеру, если таковой существует в кэше маркеров. Алгоритм данного сценария показан на рисунке 3.

Рисунок 3. Использование CachedClientCredentials двумя посредниками

Ниже приводится краткая справка по вновь созданным типам.

  • SecurityTokenCache: настраиваемый тип, содержащий ссылку SecurityToken и генерирующий событие в случае изменения маркера, с тем чтобы клиентское приложение могло ответить в случае интереса к такому изменению.
  • CachedClientCredentials: настраиваемый тип ClientCredentials, который содержит ссылку на Security­TokenCache и переопределяет CreateSecurityToken­Manager () с целью создания настраиваемого CachedClient­CredentialsSecurityTokenManager.
  • CachedClientCredentialsSecurity­TokenManager: настраиваемый тип ClientCredentialsSecurity­TokenManager, который содержит ссылку на SecurityTokenCache и переопределяет CreateSecurity­TokenProvider () с целью создания настраиваемого типа Cached­IssuedSecurityTokenProvider.
  • CachedIssuedSecurityTokenProvider: настраиваемый тип IssuedSecurityTokenProvider, который содержит ссылку на SecurityTokenCache и переопределяет GetTokenCore (), с тем чтобы задать механизм получения выданного маркера посредством возвращения выданного маркера, если он действителен, а если нет — посредством обращения к STS за новым маркером и обновления кэша.

Еще одно возможное представление алгоритма, продемонстрированного на рисунке 3, показано на рисунке 4.

Рисунок 4. Для каждого proxy применяется новая конструкция CachedClientCredentials, при этом по-прежнему используется кэш маркеров

На мой взгляд, это более целесообразный способ совместного использования кэша маркеров двумя посредниками с помощью одной и той же только что представленной настраиваемой объектной модели. В рассматриваемом случае каждый посредник получает новый экземпляр CachedClientCredentials, CachedClientCredentialsSecurity­TokenManager и CachedIssuedSecurity­TokenManager и один и тот же экземпляр SecurityTokenCache. Это чуть более чистая реализация, поскольку, по сути, дела различные proxy совместно используют выданный маркер, а не другие настройки конструкции. И хотя они могут быть одними и теми же для всех proxy, обращающихся к группе служб RP, вероятно, было бы правильнее всего вычленять те элементы, которые могут отличаться друг от друга.

В следующем разделе я прокомментирую код, реализующий данный сценарий.

SecurityTokenCache

Механизм создания настраиваемого кэша маркеров безопасности можно представлять по-разному. Возможно, вы работаете с весьма сложным клиентским приложением, которое обращается ко многим группам служб и предполагает кэширование выданных маркеров для каждой группы. А может быть, вам приходится иметь дело с приложением, которое обращается к нескольким связанным службам RP, и каждая из них может использовать выданный маркер. Как показывает мой опыт, второй сценарий встречается чаще, поэтому я позаботилась о том, чтобы реализация оставалась очень простой. В листинге 1 показан код настраиваемого SecurityTokenCache, включающий метод проверки маркера на истечение срока действия.

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

  • Клиентское приложение обеспечивает формирование стольких экземпляров SecurityTokenCache, сколько ему необходимо с учетом числа выданных маркеров, требуемых для формирования связанных групп proxy. Обычно речь идет об одном экземпляре.
  • Возможно, клиентскому приложению потребуется информация о времени обновления маркера с помощью CachedIssuedSecurity­TokenProvider для генерирования события TokenUpdated всякий раз, когда такое обновление происходит.

При формировании этого типа он предоставляется типу Cached­ClientCredentials.

CachedClientCredentials

Тип CachedClientCredentials обеспечивает формирование настраиваемого класса SecurityTokenManager, который, в свою очередь, формирует настраиваемый класс IssuedSecurityTokenProvider для данного сценария. Рассматриваемая реализация типа CachedClientCredentials показана в листинге 2. Она содержит ссылку на SecurityTokenCache и передает ее, так что после формирования настраиваемого типа CachedClientCredentialsSecurity­Token­Manager последний имеет к нему доступ. Переопределение Create­Security­Token­Manager () — ключевой элемент данной настраиваемой реализации. Он показан во фрагменте А листинга 2.

Этот клиентский код создаст новый тип CachedClientCredentials и передаст его в исходный тип ClientCredentials для сохранения настроек, инициализированных в ходе конструкции. В листинге 3 представлен код, обеспечивающий формирование кэша маркеров, создание proxy, удаление исходной функции ClientCredentials, создание новой функции CachedClient­CredentialsBehavior, передающей кэш маркеров и исходную функцию, и создание учетных данных UserName с целью передачи учетных данных и вызова STS.

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

CachedClientCredentials SecurityTokenManager

Как уже отмечалось, тип Cached­Client­Credentials создает настраиваемый класс SecurityToken­Manager,

а именно класс CachedClient­Credentials­SecurityToken­Manager. Ключевое звено данной реализации — переопределение Create­Security­TokenProvider (), который возвращает в среду выполнения новый CachedIssuedSecurity­TokenProvider. Данная реализация представлена в листинге 4.

Одна из характерных особенностей этой реализации состоит в том, что настраиваемый поставщик создается лишь в том случае, если поставщиком является IssuedSecurityTokenProvide. Отметим, что CachedIssuedSecurity­TokenProvider передается (в виде ссылки) экземпляру CachedClient­Credentials, чтобы он имел доступ к сохраненному в кэше маркеру.

CachedIssuedSecurityToken Provider

Часть листинга CachedIssued­SecurityTokenProvider представлена в листинге 5. Я опустила «шум», связанный с реализацией ICommunicationObject и IDisposable. Основная задача решается при переопределении GetTokenCore (). Код проверяет кэш на наличие действующего маркера безопасности, и, если таковой имеется, возвращает его. Если же действующий маркер не существует, вызывается базовая функция по считыванию, и кэш маркеров обновляется. Маркер считается действующим, если значение его свойства ValidTo больше текущего времени UTC.

Совместное использование Cached­ClientCredentials и обновление клиентских утверждений

Рисунок 4 иллюстрирует ситуацию, когда каждый proxy имеет собственную ссылку CachedClientCredentials, но все они используют один и тот же SecurityTokenCache. В листинге 6 показан код, позволяющий создать такую ситуацию через инициализацию каждого экземпляра CachedClientCredentials с помощью одного и того же экземпляра SecurityTokenCache. Кроме того, этот код иллюстрирует сбор утверждений о клиентах и подключение события TokenUpdated, с тем чтобы утверждения о клиентах обновлялись при считывании нового маркера.

При первоначальной загрузке приложения и инициализации каждого proxy первый proxy, который попытается осуществить вызов, получит маркер и введет информацию в кэш для последующего использования совместно с другим proxy.

Время жизни сеансов и маркеров

Я уже рассказывала о том, как организовать совместное использование маркера на клиенте с несколькими proxy, и предложила свой подход к проблеме синхронизации утверждений о клиентской стороне с новейшим маркером. Но есть еще один вопрос, который может представлять сложность при работе со сценариями федеративной безопасности; речь идет о тайм-ауте защищенного сеанса и о поврежденных каналах.

Всякий раз, когда существует транспортный сеанс, он переводится в режим ожидания на сервере в период неактивности канала. Кроме того, любое не перехваченное исключение, попадающее в службу, вызывает отказ канала службы, в результате чего использование proxy становится невозможным. Любопытно, что пользователю необязательно знать о тайм-аутах или исключениях при подключении — он может предпочесть, чтобы приложение создало новый канал, обеспечивающий продолжение работы с приложением. Как видно из реализации, описанной выше, при наличии недействительного маркера будет произведено еще одно обращение к STS с целью получения вновь выданного маркера. Но что будет происходить в двух других сценариях?

Если говорить о тайм-ауте сеанса, клиент, возможно, не будет иметь о нем представления до тех пор, пока не попытается обратиться к службе, — в этот момент обращение завершится с ошибкой. Поскольку удостовериться, что ошибка вызова была связана с тайм-аутом, возможности нет, нам нужно, чтобы попытка вызова была повторена после воссоздания proxy. Если повторная попытка завершается неудачей, значит, мы имеем дело с более серьезной проблемой, связанной с передачей данных. Но если попытка успешна, выдается новый маркер, кэш обновляется, обновляются утверждения о клиентах, пользовательский интерфейс восстанавливается, и оказывается, что все прекрасно в этом лучшем из миров.

Если исключение создается службой и это исключение не является исключением CommunicationException, пользователю необходимо предъявить сообщение об ошибке, но следующая попытка использовать proxy закончится неудачей, так как канал находится в аварийном состоянии. Пользователю необязательно знать об этом, так как его уже проинформировали об инициирующем исключении, которое вызвало сбой в работе канала. Итак, при сбое в работе канала нам необходимо воссоздать proxy, и тогда следующий вызов будет выполнен надлежащим образом. И опять все к лучшему в этом лучшем из миров.

Данный вопрос рассматривается здесь лишь в самом общем виде, поскольку я описала его более подробно в отдельной «белой книге» и в нескольких кратких веб-трансляциях, опубликованных по адресу http://wcfguidanceforwpf.codeplex.com. Кроме того, я написала программу — генератор proxy ExceptionHandlingWCFProxy­Generator (http://wcfproxygenerator.codeplex.com), автоматически создающую специальный базовый класс proxy, который решает упомянутые вопросы и дает возможность оградить пользователя от ненужных исключений. Дополнительное достоинство состоит в том, что тот же proxy помогает нам воссоздавать и получать вновь выданный маркер в случае сбоя канала.

Поддержка сценариев CardSpace

Мне пришлось написать дополнение к типу ClientCredentials, чтобы обеспечить поддержку кэширования выданных маркеров при выполнении сценариев CardSpace. Я предусмотрела переопределение GetInfoCardSecurityToken (), ибо в случаях, когда proxy конфигурируется для вызова CardSpace, этот компонент вызывается вместо IssuedSecurityTokenProvider. Реализация представлена в листинге 7.

Кэширование маркеров: полезный прием

Я остановилась на теме кэширования выданных маркеров для сценариев, в которых будет задействовано несколько proxy из клиентских приложений Windows в сценарии с использованием федеративной схемы организации безопасности. Используя метод кэширования маркеров в ситуациях, где это возможно, вы избежите ненужных обращений к STS и сможете применять более эффективный механизм аутентификации. Более подробные сведения относительно средств клиентов Windows, связанных с обеспечением безопасности на основе утверждений и федеративной безопасности, можно найти на claimsbasedwpf.codeplex.com.

Ресурсы для данной статьи размещены по адресу: www.dasblonde.net/downloads/wif/cachingissuedtokens.zip.

Мишель Бустаманте (mlb@idesign.net) — главный архитектор компании IDesign, региональный директор Microsoft в Сан-Диего и обладатель сертификата Microsoft MVP for Connected Systems. Ведет блог по адресу www.dasblonde.net

Листинг 1. Реализация SecurityTokenCache

public class SecurityTokenCache
{
    private SecurityToken _Token;
    public SecurityToken Token
    {
        get
        {
            return _Token;
        }
        set
        {
            _Token = value;
            if (TokenUpdated != null)
            {
                TokenUpdated(this, null);
            }
        }
    }
    public bool IsValidToken()
    {
        if (this._Token == null)
            return false;
         return (DateTime.UtcNow <=
            this._Token.ValidTo.
            ToUniversalTime());
    }

    public event EventHandler TokenUpdated;
}

Листинг 2. Реализация CachedClientCredentials

public class CachedClientCredentials: ClientCredentials
{
    public SecurityTokenCache TokenCache { get; private set; }
    public CachedClientCredentials(SecurityTokenCache
 tokenCache): base()
    {
        this.TokenCache = tokenCache;
    }
    public CachedClientCredentials(SecurityTokenCache
 tokenCache, ClientCredentials clientCredentials)
        : base(clientCredentials)
    {
        this.TokenCache = tokenCache;
    }
    public CachedClientCredentials(CachedClientCredentials
 clientCredentials): base(clientCredentials)
    {
        this.TokenCache = clientCredentials.TokenCache;
    }
    public override System.IdentityModel.Selectors.Security-
TokenManager CreateSecurityTokenManager()
    {
Начало фрагмента А
        return new CachedClientCredentialsSecurityTokenManager
((CachedClientCredentials)this.Clone());
Конец фрагмента А
    }
    protected override ClientCredentials CloneCore()
    {
        return new CachedClientCredentials(this);
    }
}

Листинг 3. Инициализация типа CachedClientCredentials

this.TokenCache = new SecurityTokenCache();
this._Proxy = new CustomersServiceProxy();
ClientCredentials oldCreds = this._Proxy.Endpoint.Behaviors.
Remove();
CachedClientCredentials newCreds = new CachedClientCredentials
(this.TokenCache, oldCreds);
this._Proxy.Endpoint.Behaviors.Add(newCreds);
this._Proxy.ClientCredentials.UserName.UserName
 = this.Username;
this._Proxy.ClientCredentials.UserName.Password
 = this.Password;
this._Proxy.Open();

Листинг 4. Реализация CachedClientCredentialsSecurityTokenManager

public class CachedClientCredentialsSecurityTokenManager :
 ClientCredentialsSecurityTokenManager
{
    public CachedClientCredentialsSecurityTokenManager
(CachedClientCredentials clientCredentials):
base(clientCredentials)
    {
    }
    public override System.IdentityModel.Selectors.Security-
TokenProvider
CreateSecurityTokenProvider(System.IdentityModel.Selectors.
SecurityTokenRequirement
tokenRequirement)
    {
        IssuedSecurityTokenProvider provider
 = base.CreateSecurityTokenProvider(tokenRequirement) as
IssuedSecurityTokenProvider;
        if (provider == null)
            return base.CreateSecurityTokenProvider
(tokenRequirement);
        CachedIssuedSecurityTokenProvider cachedProvider = new
CachedIssuedSecurityTokenProvider(provider,
 (CachedClientCredentials)this.ClientCredentials);
            return cachedProvider;
        }
}

Листинг 5. Реализация CachedIssuedSecurityTokenProvider

public class CachedIssuedSecurityTokenProvider:
 IssuedSecurityTokenProvider, ICommunicationObject,
IDisposable
{
    private CachedClientCredentials ClientCredentials
 { get; set; }
    private IssuedSecurityTokenProvider InnerProvider
 {get; set;}
    public CachedIssuedSecurityTokenProvider
(IssuedSecurityTokenProvider provider,
CachedClientCredentials clientCredentials):base()
    {
        this.InnerProvider = provider;
        this.ClientCredentials = clientCredentials;
        this.CacheIssuedTokens = provider.CacheIssuedTokens;
        this.IdentityVerifier = provider.IdentityVerifier;
        this.IssuedTokenRenewalThresholdPercentage =
provider.IssuedTokenRenewalThresholdPercentage;
        this.IssuerAddress = provider.IssuerAddress;
        this.IssuerBinding = provider.IssuerBinding;

        foreach (IEndpointBehavior item in
 provider.IssuerChannelBehaviors)
            this.IssuerChannelBehaviors.Add(item);
        this.KeyEntropyMode = provider.KeyEntropyMode;
        this.MaxIssuedTokenCachingTime
 = provider.MaxIssuedTokenCachingTime;
        this.MessageSecurityVersion
 = provider.MessageSecurityVersion;
        this.SecurityAlgorithmSuite
 = provider.SecurityAlgorithmSuite;
        this.SecurityTokenSerializer
 = provider.SecurityTokenSerializer;
        this.TargetAddress = provider.TargetAddress;
        foreach (XmlElement item in
 provider.TokenRequestParameters)
            this.TokenRequestParameters.Add(item);
    }
    protected override System.IdentityModel.Tokens.
SecurityToken GetTokenCore(TimeSpan timeout)
    {
        SecurityToken securityToken = null;
        if (this.ClientCredentials.TokenCache.IsValidToken())
        {
            securityToken = this.ClientCredentials.
TokenCache.Token;
        }
        else
        {
            securityToken = this.InnerProvider.GetToken
(timeout);
            this.ClientCredentials.TokenCache.Token =
 securityToken;
        }
        return securityToken;
    }
}

Листинг 6. Подключение кэша маркеров к посредникам

this.TokenCache = new SecurityTokenCache();
customersProxy = new CustomersServiceProxy();
ClientCredentials oldCreds = customersProxy.Endpoint.
Behaviors.Remove();
CachedClientCredentials newCreds = new CachedClientCredentials
(this.TokenCache, oldCreds);
customersProxy.Endpoint.Behaviors.Add(newCreds);
customersProxy.ClientCredentials.UserName.UserName =
 this.Username;
customersProxy.ClientCredentials.UserName.Password =
 this.Password;
ordersProxy = new OrdersServiceProxy();
ClientCredentials oldCreds = ordersProxy.Endpoint.Behaviors.
Remove();
newCreds = new CachedClientCredentials(this.TokenCache,
 oldCreds);
ordersProxy.Endpoint.Behaviors.Add(newCreds);
ordersProxy.ClientCredentials.UserName.UserName =
 this.Username;
ordersProxy.ClientCredentials.UserName.Password =
 this.Password;

Листинг 7. Переопределение GetInfoCardSecurityToken()

  protected override System.IdentityModel.Tokens.SecurityToken
 GetInfoCardSecurityToken(bool
requiresInfoCard, CardSpacePolicyElement[] chain,
 SecurityTokenSerializer tokenSerializer)
{
            SecurityToken securityToken = null;
            if (this.TokenCache.IsValidToken())
            {
                securityToken = this.TokenCache.Token;
            }
            else
            {
                try
                {
                    securityToken = base.GetInfoCardSecurity-
Token(requiresInfoCard, chain, tokenSerializer);
                    this.TokenCache.Token = securityToken;
                }
                catch (UserCancellationException cancelEx)
                {
                    throw new Exception(«Login cancelled
 by user.», cancelEx);
                }
             }
            return securityToken;
}

У меня есть существующее приложение asp.net mvc (Pivotal) с собственным механизмом аутентификации. Я хочу использовать это в качестве службы маркеров безопасности для Windows Identity Foundation, чтобы другие связанные веб-приложения могли использовать Pivotal для аутентификации.

Документы WIF утверждают, что веб-приложение можно использовать в качестве службы STS, но не приводят примеров. Я не могу найти в Интернете ничего, что относится к текущим версиям.net/WIF. Я использую VS 2017, .net 4.52, C# и MVC 5. Приведенные мной примеры относятся к VS2012 и не работают в VS2017.

Существуют ли руководства или примеры, которые могут помочь?

2018-02-22 00:55

1
ответ

Полностью согласен с «не катайся сам», но если хочешь, отнеси это.

Затем конвертируйте 3,5 в 4,5.


user9922

25 фев ’18 в 18:58
2018-02-25 18:58

2018-02-25 18:58

  • Служба репозитория состояний windows 10 грузит процессор
  • Служба поддержки пользователей блютуз windows 10 параметр задан неверно
  • Служба отвечающая за блютуз windows 10
  • Служба регистрации ошибок windows что это за служба
  • Служба подсистемы печати работает неправильно windows 10