Набор средств интеграции утверждений, Azure и SharePoint (часть 2)

Набор средств интеграции утверждений, Azure и SharePoint (часть 2)

Это вторая публикация из пяти в серии материалов, посвященных набору CASI Kit (Claims, Azure and SharePoint Integration — утверждения, Azure и интеграция с SharePoint). Часть 1 содержит общий обзор всей платформы и решения, в ней также описываются вопросы, которые предполагается рассмотреть в серии записей блога. В этой записи блога основное внимание будет уделяться схеме используемого мною подхода.

1. Использование пользовательского приложения WCF в качестве внешнего приложения для данных и контента.

2. Реализация для него поддержки утверждений.

3. Внесение некоторых дополнительных изменений, которые позволяют переместить его в облако Windows Azure.

Использование WCF

Главной предпосылкой создания платформы CASI Kit является то, что для всех данных приложений в качестве внешнего приложения используется приложение WCF. Как и в случае со всеми пользовательскими приложениями, вам, как разработчику, потребуется его создать. Для реализации этой части проекта практически не требуется специальных знаний по SharePoint — с этим справится любой разработчик .NET, умеющий создавать приложение WCF с помощью Visual Studio. Если конечной задачей является разместить эту службу WCF в Windows Azure, то я настоятельно рекомендую с помощью пакета средств разработки Windows Azure загрузить шаблоны для создания приложений Azure и приступить к разработке приложения WCF для Azure с самого начала. Здесь стоит отметить одно важное ограничение в текущей версии набора CASI Kit. Набор CASI фактически поддерживает отправку в методы WCF в качестве параметров только базовых типов данных .NET. Поэтому со строками, логическими значениями, целыми числами и датами не будет никаких проблем, однако передать в качестве параметра пользовательский класс не получится. Тем не менее, если это необходимо, я рекомендую создать параметр в качестве строкового и десериализовать его в XML-код перед вызовом метода WCF, а затем выполнить обратную сериализацию в экземпляр объекта в коде WCF. Кроме этого других серьезных ограничений, кажется, нет, однако я думаю, по мере широкого распространения и использования этого набора довольно скоро сформируется список пожеланий. Небольшое замечание по ходу — на сегодняшний день этот набор представляет "версию 1.0" воплощения моих собственных идей о том, как можно объединить все эти вещи, и он предназначен для решения базовых сценариев, о которых я размышлял и которые показались мне важными. Я не сомневаюсь, что когда народ начнет его использовать, появится множество вариантов по его улучшению.

Реализация поддержки утверждений

После создания приложения WCF следующим этапом является реализация поддержки утверждений. Здесь я сам ничего говорить не буду, только укажу на великолепную запись блога из четырех частей, в которой Эрик Уайт (Eric White) из рабочей группы Office описывает интеграцию утверждений SharePoint в приложение WCF. Предполагая, что вы уже создали свою службу WCF, я бы начал со второй части записей блога Эрика по адресу http://blogs.msdn.com/b/ericwhite/archive/2010/05/13/determining-caller-identity-within-a-wcf-web-service.aspx. Кроме того, вам НЕОБХОДИМО продолжить знакомство с этой серией и выполнить действия из ее третьей части, расположенной по адресу http://blogs.msdn.com/b/ericwhite/archive/2010/06/18/establishing-trust-between-a-wcf-web-service-and-the-sharepoint-2010-security-token-service.aspx , начиная с раздела, озаглавленного Процедура: создание доверительных отношений между веб-службой и SharePoint Server. Вам потребуется выполнить все действия с этого момента и далее, которые по сути состоят из копирования отпечатка сертификата для подписи маркера службы SharePoint STS и некоторых других данных в файл web.config для приложения WCF. Я не стану повторять шаги, связанные с SSL, из части 3, поскольку использование самозаверяющего сертификата будет не слишком эффективно при размещении приложения в Windows Azure. При отсутствии других вариантов вам придется этим заняться, но в целом следует все же запланировать получение необходимого SSL-сертификата от соответствующего центра авторизации для приложения WCF для Windows Azure. Примечание. НЕ НУЖНО выполнять действия из части 4 записи блога Эрика. После выполнения описанных выше действий у вас появится работающее приложение WCF с поддержкой утверждений SharePoint. В заключительной части этой записи блога я покажу дополнительные действия, которые нужно выполнить для перемещения этого приложения в Windows Azure.

Обеспечение работы в Windows Azure

Имея работающее приложение WCF для Azure, нужно сделать ряд других вещей, чтобы организовать в нем поддержку маркеров и проверки подлинности на основе утверждений с помощью платформы WIF (Windows Identity Framework) и разместить в облаке Windows Azure. Вот краткий список необходимых действий:

1. Укажите в проекте WebRole (то есть в своем проекте WCF) локальный виртуальный каталог, который будет использоваться для отладки. На мой взгляд это гораздо удобнее, чем использовать сервер разработки VS.NET при работе с сертификатами, чем мы и собираемся заняться. Для этого дважды щелкните свойства проекта WebRole и перейдите на вкладку "Веб". Установите переключатель в положение "Использовать локальный веб-сервер IIS" и нажмите кнопку "Создать виртуальный каталог". После создания виртуального каталога можно закрыть свойства проекта.

2. Добавьте ссылку на Microsoft.Identity в своем проекте WebRole. Вам НЕОБХОДИМО изменить ссылку на Copy Local = true и Specific Version = false. Это нужно, чтобы скопировать сборку WIF в облако вместе с пакетом приложения.

3. Скачайте следующее исправление WCF: http://code.msdn.microsoft.com/KB981002/Release/ProjectReleases.aspx?ReleaseId=4009 для Win2k8 R2, http://code.msdn.microsoft.com/KB971842/Release/ProjectReleases.aspx?ReleaseId=3228 для Win2k8.

4. К своему классу WCF НЕОБХОДИМО добавить следующий атрибут: [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]. Таким образом, этот класс будет выглядеть примерно так:

namespace CustomersWCF_WebRole

{

    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

    public class Customers : ICustomers

    {

5. В элемент behavior, который используется вашей службой, ОБЯЗАТЕЛЬНОнужно включить следующие данные конфигурации: Он исправляет ошибки, которые могут возникать в связи со случайным назначением портов в среде Azure. Чтобы протестировать его в локальном режиме, нужно загрузить исправление, указанное в пункте 3 выше:

      <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

Ниже представлен пример в контексте для файла web.config моей службы WCF:

    <behaviors>

      <serviceBehaviors>

        <behavior name="CustomersWCF_WebRole.CustomersBehavior">

          <federatedServiceHostConfiguration name="CustomersWCF_WebRole.Customers"/>

          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>

          <serviceDebug includeExceptionDetailInFaults="false"/>

          <useRequestHeadersForMetadataAddress>

            <defaultPorts>

              <add scheme="http" port="80" />

              <add scheme="https" port="443" />

            </defaultPorts>

          </useRequestHeadersForMetadataAddress>

        </behavior>

      </serviceBehaviors>

    </behaviors>

6. Сначала передайте сертификат SSL, который используется для приложения WCF, на портал разработчика Azure. Примечание. В коде базового класса набора CASI Kit прописано использование SSL, поэтому в приложении WCF для Windows Azure НЕОБХОДИМО реализовать поддержку SSL. Следует надеяться, что это ожидаемое требование при передаче потенциально конфиденциальных данных между облачной службой и фермой SharePoint. Затем добавьте сертификат в свойства роли Azure в Visual Studio, дважды щелкнув имя проекта WebRole (в папке Roles). Я обнаружил, что можно спокойно использовать сертификат с подстановочными знаками. Тем не менее вам понадобится сертификат PFX, и при создании PFX-файла обязательно экспортируйте все сертификаты по очереди. Azure развернет их все после загрузки файла на портал разработчика.

7. SSL-сертификат должен быть выдан для сайта "имя_сайта.ваше_DNS-имя.com", хотя все приложения Azure размещаются в домене cloudapp.net. Например, у меня был SSL-сертификат с подстановочными знаками для *.vbtoys.com. На DNS-сервере я создал новую запись CNAME под названием azurewcf.vbtoys.com и связал ее с myAzureApp.cloudapp.net. Поэтому когда я подключаюсь к https://azurewcf.vbtoys.com, мой сертификат работает, поскольку мой запрос и SSL-сертификат относятся к *.vbtoys.com, а DNS-сервер перенаправляет мой запрос на основании записи CNAME, которая указывает на myAzureApp.cloudapp.net.

8. В проекте Azure дважды щелкните имя проекта WebRole (в папке Roles) и задайте следующие свойства:

a. Вкладка "Конфигурация": снимите флажки "Запустить браузер для конечной точки HTTP" и "Запустить браузер для конечной точки HTTPS"

b. Вкладка "Сертификаты": добавьте сертификат, который будет использоваться в протоколе SSL для вашей службы. Например, в своей лаборатории я использую сертификат с подстановочными знаками, выданный моим доменом для всех используемых мною веб-серверов, поэтому здесь я добавил свой сертификат с подстановочными знаками.

c. Вкладка "Конечные точки": установите флажки "HTTP" и "HTTPS" (имена должны быть HttpIn и HttpsIn соответственно). В разделе "HTTPS" в раскрывающемся списке с именем SSL-сертификата теперь должен присутствовать SSL-сертификат, добавленный на шаге b.

9. Если метод WCF возвращает скрипт, тег script должен включать атрибут DEFER для обеспечения правильной работы, когда используется веб-часть из набора CASI Kit или когда ваша функция JavaScript назначает этот атрибут свойству innerHTML в теге. Например, тег script должен выглядеть примерно так: <script defer language='javascript'>

10. Если метод WCF возвращает контент, который включает другие теги форматирования, например <style>, их нужно поместить в оболочку из тега <pre>, иначе они будут неправильно обрабатываться, когда используется веб-часть из набора CASI Kit или когда ваша функция JavaScript назначает этот атрибут свойству innerHTML в теге. Например, возвращаемый контент с тегом style должен выглядеть примерно так: <pre><style>.foo {font-size:8pt;}</style></pre>

Это были действия, необходимые для настройки размещения приложения WCF в Azure; далее приведены дополнительные рекомендации, которые полезно, а иногда (в зависимости от реализации) и необходимо, учитывать:

1. Используйте полное имя при создании адреса конечной точки, в которой используется служба, то есть ИмяКомпьютера.foo.com, а не просто "ИмяКомпьютера". Это позволит более четко выполнить переход к конечному формату размещения в Windows Azure, а также избавиться от ошибок, которые возникают, когда в SSL-сертификате задано использование полных доменных имен.

2. Для работы WSDL-описаний с протоколом SSL МОЖЕТ понадобиться добавить следующий атрибут: httpsGetEnabled="true" в элемент <serviceMetadata httpGetEnabled="true" />. В настоящий момент в SharePoint Designer есть ошибка, которая не позволяет использовать SSL для WSDL.

3. Советы по отладке и подключению к данным см. в моей записи блога по адресу: http://blogs.technet.com/b/speschka/archive/2010/09/19/azure-development-tips-for-debugging-and-connection-strings.aspx.

4. В большинстве случаев предполагается, что пространством имен для вашей службы WCF является http://tempuri.org. Инструкции по его изменению см. в записи блога по адресу http://blogs.infosupport.com/blogs/edwinw/archive/2008/07/20/WCF_3A00_-namespaces-in-WSDL.aspx.

Готовая служба WCF

Если вы выполнили все шаги по настройке, указанные выше, и развернули свое приложение WCF в Windows Azure, то когда пользователь вызывает эту службу WCF с сайта SharePoint, вы также получаете его маркер пользователя со всеми связанными с ним утверждениями. Стоит отметить, что после внесения описанных изменений служба WCF аналогичным образом будет работать локально, поэтому ее довольно просто тестировать, когда нужно проверить некоторые дополнительные изменения до отправки приложения в облако. Наличие такого маркера пользователя позволяет делать некоторые очень интересные вещи при использовании службы WCF. Например, внутри службы WCF можно составить список всех пользовательских утверждений и на его основании принимать решения о предоставлении разрешений любого уровня. Ниже приведен пример, в котором с помощью запроса LINQ к набору пользовательских утверждений определяется, является ли текущий пользователь администратором. Если он является администратором, то в ответе на запрос возвращаются дополнительные сведения.

//поиск удостоверяющих утверждений

IClaimsIdentity ci =

System.Threading.Thread.CurrentPrincipal.Identity as IClaimsIdentity;

if (ci != null)

{

//проверка наличия утверждений перед выполнением следующего кода:

       if (ci.Claims.Count > 0)

       {

       //поиск утверждения администратора домена для группы

var eClaim = from Microsoft.IdentityModel.Claims.Claim c in ci.Claims

              where c.ClaimType ==

"http://schemas.microsoft.com/ws/2008/06/identity/claims/role" &&

                     c.Value == "Domain Admins"

                     select c;

              //проверка получения соответствия

              if (eClaim.Count() > 0)

              //соответствие имеется, поэтому у этого пользователя есть утверждение администратора домена

                     //выполните здесь что-нибудь

}

}

Также очень удобна возможность выдавать требования на разрешения непосредственно в методах WCF. Например, предположим, что имеется метод WCF, который выполняет запрос к хранилищу данных и возвращает список руководителей клиента. Эти данные не должны быть доступны всем сотрудникам, а только менеджерам по продажам. Данное условие можно реализовать просто и элегантно с помощью требования PrincipalPermission в методе:

//список руководителей не должен являться общедоступным,

//его следует отображать только сотрудникам с ролью "Менеджер по продажам"

[PrincipalPermission(SecurityAction.Demand, Role = "Sales Managers")]

public string GetCustomerCEOs()

{

//далее следует ваш код

}

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

Важно понимать, что такие утверждения нельзя подделать. Например, нельзя создать свой домен в лаборатории, добавить в него учетную запись и создать роль "Менеджер по продажам", в которую будет добавлена эта учетная запись. Это не сработает в силу того, что было сделано в процедуре, описанной в блоге Эрика Уайта (см. раздел "Реализация поддержки утверждений" выше). Если вы помните, мы добавили отпечаток сертификата для подписи маркера, который используется службой SharePoint STS. Это значит, что когда утверждение поступает в ваше приложение WCF, оно ищет маркер, подписанный открытым ключом службы SharePoint STS. Подписать его открытым ключом может только служба SharePoint STS, поскольку только у нее имеется закрытый ключ для этого сертификата. Это гарантирует, что использовать службу WSF сможет только пользователь, прошедший проверку подлинности в этой ферме SharePoint, который получит только те утверждения, которые были ему предоставлены во время входа. Кроме того, важно, что сюда относятся не только утверждения, предоставленные пользователям при проверке подлинности в их пользовательском каталоге, но ТАКЖЕ любые дополнительные утверждения, предоставленные им в ходе расширения утверждений в SharePoint с помощью любых настраиваемых поставщиков утверждений. Таким образом, мы получаем по-настоящему интегрированное комплексное решение.

Дальнейшие действия

В следующей записи блога я начну описывать пользовательский базовый класс и веб-часть, которые поставляются вместе с набором CASI Kit и позволяют быстро и легко подключаться к новому приложению WCF для Azure. Кроме того, начиная с этого момента, я буду использовать службу WCF, написанную мной для набора CASI Kit, для демонстрации функциональности этого набора. К этой записи блога я присоединяю CS-файл, который использовался мной для указанной выше службы в данной публикации. Его нельзя будет использовать без изменений, я включил его просто для того, чтобы показать различные содержащиеся в нем методы, тип данных и способ реализации различных функций из этого набора. В следующих записях блога я в основном буду использовать следующие методы: a) GetAllCustomersHtml, b) GetCustomerCEOs и c) GetAllCustomers. Они интересны, потому что a) возвращают HTML-код (который де-факто будет основным типом возвращаемых значений для отображения данных в веб-частях), b) в них используется требование PrincipalPermission и c) в них показывается возврат пользовательского типа класса из приложения WCF и использование этого комплексного типа после возвращения данных обратно в SharePoint с помощью набора CASI Kit.

Это локализованная запись блога. Исходная статья находится по адресу: The Claims, Azure and SharePoint Integration Toolkit Part 2