Поток кода авторизации OAuth для надстроек SharePoint

Примечание.

В этой статье предполагается, что вы знакомы с созданием надстроек SharePoint, использующих авторизацию с низким уровнем доверия, а также с концепциями и принципами OAuth. Дополнительные сведения об OAuth см. на сайте OAuth.net и в описании протокола веб-авторизации (OAuth).

Важно!

Служба контроля доступа Azure (ACS), которая входит в состав Azure Active Directory (Azure AD), будет упразднена 7 ноября 2018 г. Это исключение не влияет на модель надстройки SharePoint, которая использует имя хоста https://accounts.accesscontrol.windows.net (на которое это изменение не влияет). Дополнительные сведения см. в статье Влияние упразднения службы контроля доступа Azure на надстройки SharePoint.

В некоторых случаях надстройка может запрашивать разрешение на доступ к ресурсам SharePoint во время работы (динамически), а не во время установки. Этот тип надстройки не нужно запускать или даже устанавливать на SharePoint. Например, надстройка может быть встроена в устройство, запущена с какого-либо веб-сайта или из приложения Office, и ей может требоваться доступ к ресурсам SharePoint во время выполнения.

Примечание.

Этот тип надстройки может быть запущен только пользователями с разрешениями "Управление" на всех ресурсах, к которым надстройка запрашивает доступ. Например, если надстройка запрашивает у веб-сайта только разрешение на чтение, пользователь, у которого для веб-сайта есть права на "чтение", но не "управление", не может запускать надстройку.

Чтобы иметь возможность звонить в SharePoint, надстройки этого типа должны быть сначала зарегистрированы через панель инструментов продавца или страницу AppRegNew.aspx. Для получения дополнительной информации о регистрации надстроек через панель инструментов продавца или AppRegNew.aspx см. раздел Регистрация надстроек SharePoint.

После того, как вы зарегистрировали свою надстройку, она становится участником безопасности и идентифицируется, как пользователи и группы. Это удостоверение называется субъектом надстройки. Как и у пользователей и групп, у субъекта надстройки есть определенные разрешения. Дополнительные сведения о субъектах надстроек см. в статье Регистрация надстроек SharePoint.

После регистрации надстройки вы получите идентификатор и секрет клиента, домен надстройки и URI перенаправления для субъекта надстройки. Эти сведения регистрируются на сервере авторизации — службе контроля доступа Microsoft Azure (ACS).

Поток OAuth кода авторизации для надстроек, запрашивающих разрешения во время выполнения

В этом разделе представлена сводка потока проверки подлинности и авторизации OAuth для надстроек SharePoint, запрашивающих разрешения во время работы. Поток называется потоком кода авторизации. В этой последовательности описывается, как надстройка, которая не запускается из SharePoint, может получать доступ к ресурсам в SharePoint.

Примечание.

Поток включает ряд взаимодействий между надстройкой, SharePoint, сервером авторизации (ACS) и пользователем во время работы. Таким образом, в этом потоке необходима ферма SharePoint Online или SharePoint, подключенная к Интернету, для взаимодействия с ACS. На фермах SharePoint, не подключенных к Интернету, следует использовать систему авторизации с высоким уровнем доверия.

Необходимы приложение или служба, размещенные отдельно от SharePoint. Даже если надстройка привязана к устройству, ей необходим URL-адрес веб-приложения или службы, который можно зарегистрировать в ACS, даже если веб-компонент не используется для других целей.

Для простоты в этой статье предполагается, что надстройка представляет собой веб-приложение под названием Contoso.com. Приложение использует клиентскую объектную модель SharePoint (CSOM) или интерфейсы REST API SharePoint для отправки вызовов среде SharePoint. Когда приложение впервые пытается получить доступ к среде SharePoint, последняя запрашивает из ACS код авторизации, который можно отправить приложению Contoso.com. Затем приложение использует этот код авторизации, чтобы запросить маркер доступа из ACS. Получив маркер доступа, приложение Contoso.com включает его во все свои запросы к SharePoint.

Подробный пример потока

Допустим, компания Contoso предоставляет услуги фотопечати в Интернете. Пользователю нужно распечатать фотографии. Для этого он должен предоставить службе Contoso разрешение на доступ к фотографиям из библиотек на сайте SharePoint Online fabrikam.sharepoint.com и их печать.

Обзор OAuth

Приложение для фотопечати зарегистрировано, поэтому у него есть идентификатор и секрет клиента, а также URI перенаправления. URI перенаправления, предоставленный компанией Contoso при регистрации надстройки, — https://contoso.com/RedirectAccept.aspx. Идентификатор и секрет клиента хранятся в файле web.config приложения для фотопечати. Ниже представлен пример того, как идентификатор и секрет клиента вводятся в файле web.config.

<configuration>
  <appSettings>
    <add key="ClientId" value="c78d058c-7f82-44ca-a077-fba855e14d38 "/>
    <add key="ClientSecret" value="SbALAKghPXTjbBiLQZP+GnbmN+vrgeCMMvptbgk7T6w= "/>
  </appSettings>
</configuration>

Шаги потока кода авторизации

Ниже приведены шаги в потоке кода авторизации.

Совет

Эти шаги относятся к методам в файле TokenHelper.cs. Этот управляемый код не скомпилирован, поэтому для него нет справочных разделов. Однако сам файл подробно прокомментирован с описанием каждого класса, параметра члена и возвращаемого значения. Вы можете открыть его копию для справки при чтении следующих инструкций.

Этап 1. Клиент открывает приложение, а затем переходит на сайт SharePoint для получения данных

Трехсторонний поток OAuth — Шаг 1

Пользователь открывает веб-сайт фотопечати Contoso. В его пользовательском интерфейсе указывается, что пользователь может печатать фотографии, хранящиеся на любом сайте SharePoint Online.

В этом примере используется URL-адрес https://contoso.com/print/home.aspx.

Надстройка для фотопечати предлагает пользователю ввести URL-адрес коллекции фотографий. Пользователь вводит URL-адрес, указывающий на сайт SharePoint Online: https://fabrikam.sharepoint.com/.

Этап 2. Надстройка перенаправляется на URL-адрес авторизации сайта SharePoint

Трехсторонний поток OAuth — Шаг 2

Когда пользователь нажимает кнопку для получения фотографий, надстройка фотопечати Contoso перенаправляет браузер на URL-адрес https://fabrikam.sharepoint.com/. Это отклик HTTP 302 Redirect.

Если вы используете Microsoft .NET, Response.Redirect - это один из нескольких способов перенаправления из вашего кода. Используя файл TokenHelper.cs в вашем проекте, ваш код может вызывать перегруженный метод GetAuthorizationUrl (используя перегрузку с тремя аргументами). Этот метод создает URL перенаправления OAuthAuthorize.aspx для вас. Или ваш код может вручную создать URL.

Например, если вы решите вызвать метод GetAuthorizationUrl для создания URL перенаправления OAuthAuthorize.aspx для вас, используя TokenHelper.cs в вашем проекте, код будет следующим:

Response.Redirect(
  TokenHelper.GetAuthorizationUrl(
    sharePointSiteUrl.ToString(),
    "Web.Read List.Write",
    "https://contoso.com/RedirectAccept.aspx"
  )
);

Если вы посмотрите на трех-параметрическую перегрузку метода GetAuthorizationUrl в TokenHelper.cs, вы увидите, что вторым параметром является параметр области полномочий, который представляет собой разделенный пробелами список разрешений, которые надстройка запрашивает в сокращенном формате. Дополнительные сведения об областях разрешений см. в разделе Псевдонимы областей разрешений и использование страницы OAuthAuthorize.aspx.

Третьим параметром должен быть тот же URI перенаправления, который использовался при регистрации надстройки. Дополнительные сведения о регистрации см. в статье Регистрация надстроек SharePoint. Возвращаемая строка представляет собой URL-адрес, включающий параметры строки запроса. При желании вы можете вручную создать URL перенаправления OAuthAuthorize.aspx. Например, URL-адрес, на который надстройка для фотопечати Contoso перенаправляет пользователя в этом случае, (разрывы строк добавлены для удобства чтения):

https://fabrikam.sharepoint.com/_layouts/15/OAuthAuthorize.aspx?
    client_id=client_GUID
    &scope=app_permissions_list
    &response_type=code
    &redirect_uri=redirect_uri

Как видно из примера, надстройка для фотопечати Contoso отправляет идентификатор клиента OAuth и URI перенаправления на сайт Fabrikam в качестве параметров строки запроса. Ниже представлен образец запроса GET с примерами значений в строке запроса. Фактический целевой URL-адрес представляет собой одну строку.

GET /_layouts/15/OAuthAuthorize.aspx?client_id=c78d058c-7f82-44ca-a077-fba855e14d38&scope=list.read&response_type=code&redirect_uri=https%3A%2F%2Fcontoso%2Ecom%2Fredirectaccept.aspx HTTP/1.1
Host: fabrikam.sharepoint.com

Чтобы использовать для подтверждения отдельное всплывающее диалоговое окно, можно добавить параметр запроса IsDlg=1 в URL-адрес, как показано здесь: /oauthauthorize.aspx?IsDlg=1&client_id=c78d058c-7f82-44ca-a077-fba855e14d38&scope=list.read&response_type=code&redirect_uri=https%3A%2F%2Fcontoso%2Ecom%2Fredirectaccept.aspx.

Трехсторонний поток OAuth — Шаг 3

Если пользователь еще не вошел на сайт Fabrikam SharePoint Online, ему предлагается войти в систему. Если пользователь вошел, то в SharePoint отображается HTML-страница подтверждения. На странице согласия пользователю предлагается предоставить надстройке для фотопечати Contoso запрашиваемые разрешения (или отказать ей). В данном случае пользователь предоставляет надстройке доступ на чтение к библиотеке изображений пользователя на сайте Fabrikam.

Этап 4. SharePoint запрашивает временный код авторизации у службы контроля доступа

Трехсторонний поток OAuth — Шаг 4

Сайт SharePoint Online компании Fabrikam запрашивает у службы контроля доступа создание кратковременного (приблизительно 5 минут) кода авторизации, который является уникальным для этой комбинации пользователя и надстройки. ACS отправляет код авторизации на сайт Fabrikam.

Этап 5. Сайт SharePoint Online перенаправляется на зарегистрированный URI перенаправления надстройки, передавая ей код авторизации

Трехсторонний поток OAuth — Шаг 5

Сайт Fabrikam в SharePoint Online перенаправляет браузер в надстройку Contoso с помощью отклика HTTP 302. Конструкция URL для этого перенаправления использует URI перенаправления, который был указан при регистрации надстройки для фотопечати. Он также содержит код авторизации в виде строки запроса.

URL-адрес перенаправления имеет следующую структуру: https://contoso.com/RedirectAccept.aspx?code=[authcode].

Этап 6. Надстройка использует код авторизации, чтобы запросить маркер доступа у службы контроля доступа, которая проверяет запрос, прекращает действие кода авторизации и отправляет маркеры доступа и обновления надстройке

Трехсторонний поток OAuth — Шаг 6

Contoso получает код авторизации из параметра запроса и включает его вместе с идентификатором и секретом клиента в запрос маркера доступа, отправляемый службе контроля доступа.

Если вы используете управляемый код и SharePoint CSOM, файл TokenHelper.cs, метод, который делает запрос к ACS, - это GetClientContextWithAuthorizationCode. В этом случае код выглядит следующим образом (где authCode — это переменная, которой назначен код авторизации):

TokenHelper.GetClientContextWithAuthorizationCode(
  "https://fabrikam.sharepoint.com/",
  "00000003-0000-0ff1-ce00-000000000000",
  authCode,
  "1ee82b34-7c1b-471b-b27e-ff272accd564",
  new Uri(Request.Url.GetLeftPart(UriPartial.Path))
);

Если вы посмотрите на файл TokenHelper.cs, второй параметр метода GetClientContextWithAuthorizationCode - это targetPrincipalName. В надстройках, получающих доступ к SharePoint, его значение всегда равно 00000003-0000-0ff1-ce00-000000000000. При трассировке иерархии вызовов из метода GetClientContextWithAuthorizationCode вы увидите, что он получает идентификатор и секрет клиента из файла web.config.

ACS получает запрос от Contoso, а затем проверяет идентификатор и секрет клиента, URI перенаправления и код авторизации. Если они действительны, ACS делает код авторизации недействительным (его можно использовать только один раз) и создает маркеры обновления и доступа, а затем отправляет их надстройке Contoso. Приложение Contoso может кэшировать этот маркер доступа для использования в последующих запросах. По умолчанию срок действия маркеров доступа составляет около 12 часов.

Каждый маркер доступа связан с учетной записью, указанной в исходном запросе авторизации, и предоставляет доступ только к тем службам, которые указаны в этом запросе. Надстройка должна надежно хранить этот маркер доступа. Приложение Contoso также может кэшировать маркер обновления. По умолчанию токены обновления действительны в течение шести месяцев. По истечении срока действия старого маркера доступа от ACS вы можете получить новый с помощью маркера обновления.

Дополнительные сведения о маркерах см. в статье Обработка маркеров безопасности в надстройках SharePoint с низким уровнем доверия, размещенных у поставщика.

Этап 7. Теперь с помощью маркера доступа надстройка может запрашивать данные с сайта SharePoint, а затем показывать их пользователю

Трехсторонний поток OAuth — Шаг 7

Contoso включает маркер доступа для вызова REST API или запроса CSOM к SharePoint, передавая маркер доступа OAuth в заголовке HTTP Authorization. SharePoint возвращает сведения, запрашиваемые надстройкой Contoso.

Дополнительные сведения о том, как отправляется этот запрос, см. в статье Обработка маркеров безопасности в надстройках SharePoint с низким уровнем доверия, размещенных у поставщика.

Псевдонимы области разрешений и страница OAuthAuthorize.aspx

В этом разделе предполагается, что вы знакомы со статьей Разрешения надстройки в SharePoint. В таблице 1 показаны те же URI области запроса на разрешение надстройки, которые показаны в этой статье, за исключением того, что у нее есть один дополнительный столбец (псевдоним области), а право FullControl недоступно в столбце Доступные права, поскольку надстройка, которая запрашивает разрешение на доступ к ресурсам SharePoint на лету, не может запрашивать право FullControl.

Значения, указанные в столбце Псевдоним области, представляют собой сокращенные версии их аналогов из столбца URI области. Псевдонимами могут пользоваться только надстройки, запрашивающие разрешение на доступ к ресурсам SharePoint во время выполнения. (Значения URI области используются в манифесте надстройки надстроек, запускаемых из SharePoint. Эти надстройки запрашивают разрешения во время установки надстройки.)

Псевдонимы области используются только в контексте использования страницы перенаправления OAuthAuthorize.aspx. Как показано в шаге 2 потока OAuth, описанного в предыдущем разделе, когда надстройка использует управляемый код, псевдонимы используются при вызове методаGetAuthorizationUrlTokenHelper.cs в вашем проекте. Ниже представлен еще один пример.

Response.Redirect(TokenHelper.GetAuthorizationUrl(
    sharePointSiteUrl.ToString(),
    "Web.Read List.Write ",
    "https://contoso.com/RedirectAccept.aspx ")
);

Значение параметра scope, Web.Read List.Write, представляет собой пример запроса разрешений с помощью псевдонимов областей. Параметр scope — это разделенный пробелами набор, состоящий из области разрешений и запрашиваемых прав.

Если вы не используете управляемый код, псевдонимы области используются в поле области в URL перенаправления. Например:

https://fabrikam.sharepoint.com/_layout/15/OAuthAuthorize.aspx?client_id=c78d058c-7f82-44ca-a077-fba855e14d38&scope=list.write&response_type=code&redirect_uri=https%3A%2F%2Fcontoso%2Ecom%2Fredirectaccept.aspx

Примечание.

Описание областей см. в статье Разрешения надстроек в SharePoint.

Таблица 1. URI области запроса разрешения надстройки SharePoint и соответствующие им псевдонимы

URI области Псевдоним области Доступные права
https://sharepoint/content/sitecollection Site Чтение, запись, управление
https://sharepoint/content/sitecollection/web Web Чтение, запись, управление
https://sharepoint/content/sitecollection/web/list List Чтение, запись, управление
https://sharepoint/content/tenant AllSites Чтение, запись, управление
https://sharepoint/bcs/connection Нет (сейчас не поддерживается) Чтение
https://sharepoint/search Search QueryAsUserIgnoreAppPrincipal
https://sharepoint/projectserver ProjectAdmin Управление
https://sharepoint/projectserver/projects Projects Чтение, запись
https://sharepoint/projectserver/projects/project Project Чтение, запись
https://sharepoint/projectserver/enterpriseresources ProjectResources Чтение, запись
https://sharepoint/projectserver/statusing ProjectStatusing SubmitStatus
https://sharepoint/projectserver/reporting ProjectReporting Чтение
https://sharepoint/projectserver/workflow ProjectWorkflow Повышение прав
https://sharepoint/social/tenant AllProfiles Чтение, запись, управление
https://sharepoint/social/core Social Чтение, запись, управление
https://sharepoint/social/microfeed Microfeed Чтение, запись, управление
https://sharepoint/taxonomy TermStore Read, Write

URI перенаправления и пример страницы перенаправления

URI перенаправления, используемый надстройками, который запрашивают разрешения во время выполнения, — это URI, на который SharePoint перенаправляет браузер после предоставления согласия (с кодом авторизации в виде параметра запроса). Шаг 2 потока OAuth дает пример, где URI жестко закодирован в вызове метода GetAuthorizationUrl. Кроме того, надстройка ASP.NET также может хранить URI в файле web.config, как показано в следующем примере:

<configuration>
  <appSettings>
    <add key="RedirectUri" value="https://contoso.com/RedirectAccept.aspx" />
  </appSettings>
<configuration>

Это значение можно получить, вызвав метод WebConfigurationManager.AppSettings.Get("RedirectUri").

Конечная точка в RedirectUri получает код авторизации из параметра запроса и использует его для получения токена доступа, который затем можно использовать для доступа к SharePoint. Как правило, конечной точкой является та же страница (либо метод контроллера или веб-метод), которая изначально пыталась получить доступ к SharePoint. Однако это могут быть страница или метод, которые просто получают маркер авторизации, а затем выполняют перенаправление на другую страницу или в другой метод. Специальные страница или метод могут передать маркер авторизации или кэшировать его. (Срок его службы составляет около 5 минут.) Кроме того, он может использовать токен авторизации для получения токена доступа, который кэшируется.

Важно!

RedirectUri должен быть той же конечной точкой, которая указана при создании приложения на странице AppRegNew.aspx.

Ниже приведен пример кода такой страницы в приложении ASP.NET. Обратите внимание на следующие особенности этого кода:

  • Он использует файл TokenHelper.cs, созданный средствами разработчика Office для Visual Studio.
  • Код предполагает наличие параметра запроса «код», который содержит код авторизации. Это безопасно, потому что страница вызывается только SharePoint и только при передаче кода авторизации.
  • Он использует объект контекста клиента CSOM для доступа к SharePoint, но он также мог кэшировать этот объект на сервере и перенаправлять на другую страницу.
  • Метод GetClientContextWithAuthorizationCode использует код авторизации для получения кода доступа. Затем он создает объект контекста клиента SharePoint и меняет обработчик события ExecutingWebRequest в этом объекте, чтобы этот обработчик включал маркер доступа во все запросы к SharePoint. Маркер доступа, по сути, кэшируется в объекте.
  • Метод GetClientContextWithAuthorizationCode отправляет URL перенаправления обратно в ACS в параметре rUrl, но ACS использует его как форму идентификации в случае кражи кода авторизации. ACS не использует его для повторного перенаправления, поэтому этот код не зацикливается на бесконечном перенаправлении.
  • В коде не предусмотрена обработка просроченных маркеров доступа. Создав объект контекста клиента, он использует один и тот же маркер доступа. Он вообще не использует токен обновления. Это приемлемо для надстроек, продолжительность сеансов использования которых не превышает срок действия маркера доступа.

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

public partial class RedirectAccept : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
    string authCode = Request.QueryString["code"];
    Uri rUri = new Uri("https://contoso.com/RedirectAccept.aspx");

    using (ClientContext context = TokenHelper.GetClientContextWithAuthorizationCode(
        "https://fabrikam.sharepoint.com/",
        "00000003-0000-0ff1-ce00-000000000000",
        authCode,
        "1ee82b34-7c1b-471b-b27e-ff272accd564".
        rUri))
    {
      context.Load(context.Web);
      context.ExecuteQuery();

      Response.Write("<p>" + context.Web.Title + "</p>");
    }
  }
}

Пример кода страницы, получающей доступ к SharePoint

Ниже приведен код страницы Default.aspx. Эта страница рассчитана на сценарий, в котором страницей по умолчанию является начальная страница надстройки, которая также является зарегистрированным URL-адресом перенаправления для надстройки. Обратите внимание на следующие особенности этого кода:

  • Метод Page_Load сначала проверяет код авторизации в строке запроса. есть один, если браузер был перенаправлен на страницу SharePoint. Если он есть, код использует его для получения нового токена обновления, который кэшируется в долговременном кэше, который сохраняется между сеансами.

  • Затем метод проверяет наличие маркера обновления в кэше.

    • Если его нет, он получает его, сообщая SharePoint необходимые ему разрешения (разрешение на запись в веб-области) и запрашивая у SharePoint код авторизации. Пользователю предлагается предоставить разрешение, и, если оно предоставлено, SharePoint получает код авторизации от ACS и отправляет его обратно в качестве параметра запроса при перенаправлении на эту же страницу.
    • Если есть кэшированный токен обновления, метод использует его для получения токена доступа непосредственно из ACS. Как и в примере в конце предыдущего раздела этой статьи, маркер доступа используется для создания объекта контекста клиента SharePoint. При использовании кэшированного маркера обновления для получения маркера доступа непосредственно из ACS отсутствует необходимость в дополнительном сетевом вызове SharePoint в начале сеанса. По этой причине, если повторно запустить надстройку, пока не истечет срок действия кэша с маркером обновления, то она запустится быстрее.
  • Как и в примере в конце предыдущего раздела, этот код не предусматривает работы с токеном с истекшим сроком доступа. Создав объект контекста клиента, он использует один и тот же маркер доступа. Один из способов защиты от просроченных маркеров доступа — кэшировать не только маркер обновления, но и маркер доступа. Затем следует изменить приведенный ниже код, чтобы он вызывал метод GetAccessToken только при отсутствии действительного маркера доступа к кэше.

    Однако, хотя допустимо, чтобы токен обновления кэшировался на клиенте, например, в файле cookie, токен доступа должен находиться только в кэше на стороне сервера по соображениям безопасности. Маркер обновления шифруется, и расшифровать его может только ACS. Однако маркер доступа только кодируется (в кодировке Base 64), и может быть легко раскодирован путем активного вмешательства в соединение.

  • Класс TokenCache, на который ссылается этот код, будет определен позже в этом разделе.

Кодовый код для страницы Default.aspx

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint.Samples;
using Microsoft.SharePoint.Client;

namespace DynamicAppPermissionRequest
{
  public partial class Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      Uri sharePointSiteUrl = new Uri("https://fabrikam.sharepoint.com/print/");

      if (Request.QueryString["code"] != null)
      {
        TokenCache.UpdateCacheWithCode(Request, Response, sharePointSiteUrl);
      }

      if (!TokenCache.IsTokenInCache(Request.Cookies))
      {
        Response.Redirect(TokenHelper.GetAuthorizationUrl(sharePointSiteUrl.ToString(), "Web.Write"));
      }
      else
      {
        string refreshToken = TokenCache.GetCachedRefreshToken(Request.Cookies);
        string accessToken =
        TokenHelper.GetAccessToken(
                    refreshToken,
                    "00000003-0000-0ff1-ce00-000000000000",
                    sharePointSiteUrl.Authority,
                    TokenHelper.GetRealmFromTargetUrl(sharePointSiteUrl)).AccessToken;

        using (ClientContext context =
                TokenHelper.GetClientContextWithAccessToken(sharePointSiteUrl.ToString(),
                                                            accessToken))
        {
          context.Load(context.Web);
          context.ExecuteQuery();

          Response.Write("<p>" + context.Web.Title + "</p>");
        }
      }
    }
  }
}

Ниже приведен пример кода для модуля кэширования маркера, вызываемого в предыдущем примере кода. Он использует файлы cookie в качестве кэша. Существуют и другие варианты кэширования. Дополнительные сведения см. в статье Обработка маркеров безопасности в надстройках SharePoint с низким уровнем доверия, размещенных у поставщика.

Пример кода для модуля кеширования токена

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.SharePoint.Samples;

namespace DynamicAppPermissionRequest
{
  public static class TokenCache
  {
    private const string REFRESH_TOKEN_COOKIE_NAME = "RefreshToken";

    public static void UpdateCacheWithCode(HttpRequest request,
                                            HttpResponse response,
                                            Uri targetUri)
    {
      string refreshToken =
          TokenHelper.GetAccessToken(
              request.QueryString["code"],
              "00000003-0000-0ff1-ce00-000000000000",
              targetUri.Authority,
              TokenHelper.GetRealmFromTargetUrl(targetUri),
              new Uri(request.Url.GetLeftPart(UriPartial.Path))
          ).RefreshToken;
      SetRefreshTokenCookie(response.Cookies, refreshToken);
      SetRefreshTokenCookie(request.Cookies, refreshToken);
    }

    internal static string GetCachedRefreshToken(HttpCookieCollection requestCookies)
    {
      return GetRefreshTokenFromCookie(requestCookies);
    }

    internal static bool IsTokenInCache(HttpCookieCollection requestCookies)
    {
      return requestCookies[REFRESH_TOKEN_COOKIE_NAME] != null;
    }

    private static string GetRefreshTokenFromCookie(HttpCookieCollection cookies)
    {
      if (cookies[REFRESH_TOKEN_COOKIE_NAME] != null)
      {
        return cookies[REFRESH_TOKEN_COOKIE_NAME].Value;
      }
      else
      {
        return null;
      }
    }

    private static void SetRefreshTokenCookie(HttpCookieCollection cookies, string refreshToken)
    {
      if (cookies[REFRESH_TOKEN_COOKIE_NAME] != null)
      {
        cookies[REFRESH_TOKEN_COOKIE_NAME].Value = refreshToken;
      }
      else
      {
        HttpCookie cookie = new HttpCookie(REFRESH_TOKEN_COOKIE_NAME, refreshToken);
        cookie.Expires = DateTime.Now.AddDays(30);
        cookies.Add(cookie);
      }
    }
  }
}

См. также