Дополнительные советы по устранению неполадок приложений с высоким уровнем доверия в SharePoint 2013
Исходная статья опубликована в пятницу, 2 ноября 2012 г.
Привет! Я разработчик приложений, и мне нравится моя работа. Но порой я просто выхожу из себя, когда мне приходится искать причину очередной ошибки типа "Поставщик этого маркера не является надежным поставщиком" в новом приложении SharePoint. Чтобы помочь вам сохранить нервы (и рассудок) в порядке, я буду вести здесь список проблем, которые ищу в первую очередь при возникновении этой ошибки. По мере того, как я буду находить новые способы ее вызова и устранения, я буду обновлять эту запись и сообщать об этом ниже.
Важно помнить, что когда я говорю "приложение с высоким уровнем доверия", это означает, что вы НЕ используете службу ACS в качестве посредника доверия для своего приложения SharePoint. Вместо этого вы создаете маркер OAuth и подписываете его с помощью собственного сертификата. Я знаю, что весь этот процесс подробно описан в одной из статей, поэтому я не буду здесь повторяться. Я буду считать, что вы прочитали ее, опробовали процедуру на практике, и у вас все получилось. Итак, вот несколько случаев, когда, как я заметил, происходит эта ошибка.
- Добавление в список SPTrustedRootAuthority. Когда вы используете сертификат для подписи маркеров OAuth, вам нужно создать доверенный корневой центр с помощью командлета New-SPTrustedRootAuthority. Так же, как и в SharePoint 2010, где использовался командлет New-SPTrustedIdentityTokenIssuer, вам нужно добавить сертификат для подписи маркера и все остальные сертификаты в цепочке в список доверенных центров SharePoint. Для этого вы можете использовать процедуру, которую я описал в следующей записи блога: https://blogs.technet.com/b/speschka/archive/2010/02/13/root-of-certificate-chain-not-trusted-error-with-claims-authentication.aspx. Просто пропустите инструкции по экспорту сертификата из AD FS — предполагаю, что вы уже создали сертификат для приложения с высоким уровнем доверия каким-либо иным способом, например с помощью общедоступного корневого ЦС, такого как GoDaddy, VeriSign и т. д., самозаверяющего сертификата или сертификата, выданного доменом.
- В идентификаторе клиента используются прописные буквы. Как я уже говорил в другой записи блога, НЕ используйте прописные буквы при добавлении ИД клиента в файл AppManifest.xml приложения или файл web.config веб-приложения, если вы создаете резидентное решение. Подробнее см. в следующей записи: https://blogs.technet.com/b/speschka/archive/2012/07/28/an-important-tip-about-client-id-values-for-s2s-apps-in-sharepoint-2013.aspx.
- Поставщик маркера не настроен в качестве посредника доверия. Эту проблему я также описал в другой записи блога: https://blogs.technet.com/b/speschka/archive/2012/09/27/another-apps-for-sharepoint-tip-with-the-error-quot-the-issuer-of-the-token-is-not-a-trusted-issuer-quot.aspx. Суть ее в том, что при вызове командлета New-SPTrustedSecurityTokenIssuer нужно включить флаг -IsTrustBroker.
- ОБНОВЛЕНИЕ!: В файле web.config отсутствует ключ IssuerId. Для использования функции посредника доверия в SharePoint 2013 ваше приложение должно знать идентификатор IssuerId посредника доверия при создании маркера JWT, который оно отправляет в SharePoint. Для этого оно ищет в файле web.config свойство приложения с именем IssuerId. Это свойство находится в том же месте в файле web.config, что и свойства ClientId, ClientSecret и т. д. Выглядит оно следующим образом: <add key="IssuerId" value="e9134021-0180-4b05-9e7e-0a9e5a524965"/>.
- ОБНОВЛЕНИЕ!: Использование предварительной RTM-версии средств Office для Visual Studio. В коде предварительной RTM-версии на самом деле есть небольшая ошибка, которая исправлена во второй предварительной версии. Код, который отправляет маркер авторизации в SharePoint, не ищет элемент IssuerId в файле web.config. Вместо этого он отправляет другое значение. Что он отправляет и почему, не важно. Что действительно важно — это то, что вы можете решить эту проблему в этой версии средств, всегда используя значение IssuerId для SPTrustedSecurityTokenIssuer в ключе ClientId файла web.config. Как только вы получите вторую предварительную версию, сразу установите ее и измените значение ClientId на уникальный идентификатор GUID, созданный и зарегистрированный вами (с помощью командлета Register-SPAppPrincipal, как описано ниже). Идентификаторы ClientId не должны совпадать, так как они определяют приложения, которые подписали маркер OAuth, и используются в различных компонентах пользовательского интерфейса SharePoint. Если вам потребуется устранить какую-либо неполадку или провести аудит, одинаковые значения могут создать трудности.
Есть еще одна связанная проблема, о которой стоит упомянуть: допустим, вы, казалось бы, избежали этой ошибки, но затем получаете ошибку отказа в доступе, когда пытаетесь получить контент с сайта SharePoint в резидентном приложении. Причина может заключаться в следующем.
- Значение ClientId в файле AppManifest.xml вашего приложения SharePoint не соответствует значению ClientId в файле web.config резидентного приложения. Мы вносим улучшения в средства Visual Studio, которые должны устранить эту проблему в дальнейшем.
Почти столь же важный вопрос — как понять причину этой ошибки, когда она происходит? Если бы это было так просто, я бы не выходил из себя и не испытывал желания разбить монитор. Вот лучшие средства для решения этой проблемы, которые мне пока удалось найти. Опять таки, со временем я постараюсь расширить этот список.
- Журналы ULS — неизменный любимчик. Просто не передать, как приятно в погожий денек открыть журналы ULS и просто изумиться их размеру. Ладно, это шутка. А если серьезно, то сделайте следующее — последовательно выберите "Центр администрирования", "Наблюдение" и "Настройка средств сбора данных диагностики". Разверните категорию "SharePoint Foundation" и выберите следующие элементы: "Проверка подлинности для приложения", "Авторизация приложений" и "Проверка подлинности на основе утверждений". Установите для них уровень ведения журнала и трассировки "Подробно" и сохраните изменения. После этого попробуйте запустить приложение повторно. Чтобы увидеть, как поступает и обрабатывается запрос, воспользуйтесь одним из множества средств просмотра журналов ULS. Это неплохой способ получить представление о проблемах с проверкой подлинности в вашем приложении.
- Fiddler — еще одно любимое средство, которое очень полезно в таких ситуациях. Чаще всего вам будет встречаться ошибка отказа в доступе с кодом 401 (в том числе и в случае, если поставщик маркера не является доверенным). Если вы откроете последний кадр в запросе, а затем перейдете на вкладку "Headers" (Заголовки) в кадре ответа, вы увидите файл cookie WWW-Authenticate, который выглядит примерно так: Bearer realm="8a96481b-6c65-4e78-b2ef-a446adb79b59",client_id="00000003-0000-0ff1-ce00-000000000000",trusted_issuers="<e9134021-0180-4b05-9e7e-0a9e5a524965@8a96481b-6c65-4e78-b2ef-a446adb79b59,00000003-0000-0ff1-ce00-000000000000@8a96481b-6c65-4e78-b2ef-a446adb79b59>" . Что же из этого следует? Из этого следует, что значение ClientId должно быть e9134021-0180-4b05-9e7e-0a9e5a524965, а занчение области — 8a96481b-6c65-4e78-b2ef-a446adb79b59. Значение ClientId проверить довольно легко — его можно найти в файлах AppManifest.xml и web.config для резидентного приложения. Крайне маловероятно, что область окажется неправильной, но вы всегда можете проверить это с помощью следующих команд PowerShell:
$spurl ="https://foo"
$spsite = Get-SPSite $spurl
$realm = Get-SPAuthenticationRealm -ServiceContext $spsite
$realm
На экран будет выведена ваша область. Наконец, вы можете проверить, создан ли элемент appPrincipal для используемого идентификатора ClientId. Для этого выполните следующую команду PowerShell, используя полученные ранее сведения из заголовка WWW-Authenticate:
Get-SPAppPrincipal -NameIdentifier <e9134021-0180-4b05-9e7e-0a9e5a524965@8a96481b-6c65-4e78-b2ef-a446adb79b59> -Site https://foo
Если произойдет ошибка или вы не получите результатов, это означает, что допустимый элемент SPAppPrincipal отсутствует и вам нужно создать его с помощью PowerShell. Для полноты картины приведу пример:
$clientId = "создаваемый вами GUID"
$spurl ="https://foo"
$spsite = Get-SPSite $spurl
$realm = Get-SPAuthenticationRealm -ServiceContext $spsite
$fullAppIdentifier = $clientId + <'@'> + $realm
$appPrincipal = Register-SPAppPrincipal -NameIdentifier $fullAppIdentifier -Site $spsite.OpenWeb() -DisplayName "Мое приложение"
На этом мои советы по устранению неполадок приложений с высоким уровнем доверия на сегодня исчерпаны. Если у меня будет появляться что-то новенькое, то я буду обновлять эту запись блога.
Это локализованная запись блога. Исходная статья доступна по ссылке More TroubleShooting Tips for High Trust Apps on SharePoint 2013