Система разрешений в новой архитектуре приложений в SharePoint 2013 (о которых я писал ранее) до сих пор вызывает много вопросов. Попробую прояснить некоторые из них:

Введение

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

В FullTrust возможно повышение привилегий путем создания объекта SPSite с токеном более привилегированного пользователя (SPUserToken.SystemAccount). Код с повышенными привилегиями может делать всё (вообще всё). Поэтому любое решение или опасно, или почти бесполезно. Еще одна проблема повышения привилегий – невозможно отследить какой пользователь и какие действия вызвали изменения, потому что везде будет один и тот же пользователь даже для разных решений.

App Principals

Для решения проблем обозначенных выше, приложения решили сделать участниками системы безопасности (principal), также как и пользователей. Это означает что у каждого приложения есть свой App Principal, которому назначаются права.

Пользователь сопоставляется со своим principal в процессе аутентификации, то есть при передаче логина\пароля (или токена) от пользователя к SharePoint.

А как же происходит аутентификация приложений, ведь нету логинов и паролей у приложений...

Этот процесс описывает простая схема:

image

Схема не совсем точная, но в общем описывает процесс правильно.

Если не вдаваться в детали, то выполняются такие условия:

  1. Если пользователь аутентифицирован и происходит запрос к AppWeb, то используется App Principal + User Principal (внутренняя аутентификация).
  2. Если пользователь не аутентифицирован, но в запросе указан access token (внешняя аутентификация), то
    • Если в access token указан user identity, то то используется App Principal + User Principal.
    • Если в access token не указан user identity, то то используется App Principal  с App Only-Policy.
  3. Во всех остальных случаях аутентификация для приложения не происходит.

Внутренняя аутентификация

Скриншот манифеста свежесозданного SharePoint-hosted app, обратите внимание на элемент AppPrincipal.

image

Внутренняя аутентификация называется так, потому что все процессы аутентификации приложения происходят внутри SharePoint. Вам для этого не надо ничего писал и\или настраивать (только DNS для AppWeb).

Внутренняя аутентификация используется именно для SharePoint-hosted app и JavaScript кода. В других случаях сложно повторить условия для внутренней аутентификации. Чтобы нельзя было обойти внутреннюю аутентификацию и проверку прав приложения AppWeb создается на уникальном домене. Это позволяет блокировать JavaScipt обращения, используя same origin policy, которая встроена в браузер.

Есть еще возможность размещать клиентский JavaScript внешнем сайте, и он будут обращаться к AppWeb и будет работать аутентификация приложения.

Внешняя аутентификация

Если же поменять тип приложения на Provider-hosted , то можно увидеть такой манифест:

image

В элементе AppPrincipal появилось RemoteWebApplication. ClientId="*" заменяется на идентификатор приложения при отладке или публикации.

access token должен содержать идентификатор приложения, чтобы SharePoint мог привязать AppPrincipal. Для формирования Access token используется oauth или s2s trust. Оба доступны только в серверном коде внешнего приложения и не доступны в клиентском JavaScript.

Основная проблема в том, что нельзя одновременно указать внутреннюю и внешнюю аутентификацию. То есть нормально обращаться к SharePoint сможет или серверный код на внешнем сайте или JavaScript на AppWeb. Учитывая что многие стандартные компоненты SharePoint используют JSOM, то они не будут работать при внешней аутентификации. Это делает AppWeb почти бесполезным для Provider-hosted приложений.

OAuth

OAuth это протокол (правильнее сказать фреймворк), который описывает протоколы и сценарии аутентификации приложений в вебе. В Office 365 используется схема с тремя действующими лицами:

  • Приложение
  • Access Control Service (ACS)
  • SharePoint

SharePoint и приложение доверяют ACS, SharePoint не доверяет приложению напрямую (и правильно делает :) ).

Процесс аутентификации выглядит так:

  1. Пользователь нажимает на плитку приложения.
  2. SharePoint запрашивает у ACS так называемый context token по ClientId приложения и отдает context token клиенту (браузеру). Context token подписан с помощью ClientSecret, который известен ACS и приложению.
  3. Браузер делает POST запрос на адрес приложения и передает context token.
  4. Приложение проверяет context token с помощью ClientSecret и извлекает refresh token.
  5. Далее по refresh token приложение может получить access token от ACS и обращаться с ним к SharePoint.

Описание на MSDN: http://msdn.microsoft.com/en-us/library/office/fp142382.aspx

Параметры ClientId и ClientSecret вы получаете при регистрации в Office Store или при добавлении нового app principal на странице /_layouts/15/appregnew.aspx.

Важные моменты:

  •  Context token передается приложению POST запросом. При переходе н другую страницу в приложении context token не сохранится. Само приложение должно это делать. В Visual Studio 2013 включили класс SharePointContext, который управляет сохранением токенов в сессии.
  • Из-за использования POST нельзя реализовать OAuth на клиентском JavaScript. Даже не пытайтесь.
  • SharePoint и ACS напрямую не обращается к вашему приложению, кроме случаев использования Remote Event Receiver или Workflow. Поэтому SharePoint абсолютно все равно где и на чем работает ваше приложение. Это например позволяет отлаживать облачные приложения на локальной машине.

OAuth полагается на SSL, так как все токены передаются незащищенными от перехвата. Любое приложение SharePoint для Office 365 должно иметь SSL сертификат.

Как я писал ранее, в onprem по-умолчанию не работает OAuth и используется его расширение S2STrust. Можно интегрировать onprem ферму с тенантом office365, тогда появится возможность устанавливать provider-hosted приложения из маркета. Подробнее тут: http://msdn.microsoft.com/en-us/library/office/dn155905.aspx

S2S Trust

В onprem варианте вместо “трехногого” OAuth используется “двуногий” вариант, называемый Server-to-Server Trust. Суть в том что SharePoint доверяет серверу приложения. Для установления факта доверия в SharePoint должен быть добавлен Trusted Token Issuer, а это требует сертификата. Приложение этим сертификатом подписывает запросы на получение access token пользователя.

В “двуногой” схеме никаких context token и refresh token не используется. Приложение должно само аутентифицировать пользователя и передавать данные о текущем пользователе в SharePont. Да, это позволяет приложению притворяться любым пользователем.

Такие приложения называются приложением с высоким доверием (High trust), в отличие от full trust права приложения все-таки ограничиваются.

Подробнее тут: http://msdn.microsoft.com/en-us/library/office/fp179901.aspx

Права приложений

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

  • Требуемые права задаются в манифесте.
  • Права приложению даются при установке по принципу “все или ничего”.
  • Права приложений не используют иерархию объектов SharePoint.

Вот так выглядит запрос прав манифесте, указываются области и требуемые права:

image

Полный список возможных разрешений: http://msdn.microsoft.com/en-us/library/office/fp142383.aspx

Для вычисления эффективных разрешений права пользователя и права приложения пересекаются. Porvider-hosted app может также получить app-only access token, если в манифесте приложения было указано app-only policy.

image

Надо учитывать что все это работает только для CSOM и REST вызовов. Обычные (устаревшие) веб-сервисы не поддерживают аутентификацию с помощью access token.

Права – основной источник проблем для приложений. Если вы дадите приложению недостаточно прав, то ошибки буду очень непонятными. Иногда сочетание прав для некоторой операции крайне неочевидно, например:

  • Публикация в социальную ленту требует Social Write, Tenant Write, User Profiles Read, если не дадите одно из них вам скажут “Social list not found” или что-то в этом роде.
  • Добавление типов контента на подсайт требует sitecollection read, хотя если вы будете тестировать приложение на корневом сайте, то прав web manage может хватить.

Есть еще возможность запрашивать права “на лету”, но это тема для отдельной статьи. Пока можете прочитать описание на MSDN: http://msdn.microsoft.com/en-us/library/office/jj687470.aspx

Заключение

Большая часть сложностей аутентификации приложений скрыто от глаз программистов, с помощью внутренних механизмов SharePoint и классов хелперов SharePointContext и TokenHelper. Тем не менее надо хорошо понимать внутренние механизмы, особенно разграничения доступа, чтобы успешно создавать приложения.

С появлением модели apps нагрузка на SharePoint разработчиков сильно возросла, надо изучать много новых технологий и подходов, чтобы эффективно применять возможности платформы.

Изучайте, развивайтесь.

Теги : SharePoint 2013, sp2013, apps, SharePoint