Fluxo OAuth de código de autorização para os suplementos do SharePoint

Observação

Este artigo supõe que você esteja familiarizado com a Criação de suplementos do SharePoint que usam autorização de baixo nível de confiança e com os conceitos e princípios por trás do OAuth. Saiba mais sobre OAuth em OAuth.net e Protocolo de autorização da Web (oauth).

Importante

O Controle de Acesso do Azure (ACS), um serviço do Azure Active Directory (Azure AD) será desativado em 7 de novembro de 2018. Essa desativação não afeta o modelo do Suplemento do SharePoint que usa o nome de host https://accounts.accesscontrol.windows.net (que não é afetado por ela). Para saber mais, confira Impacto da desativação do Controle de Acesso do Azure para Suplementos do SharePoint.

Em alguns cenários, um suplemento pode solicitar permissão para acessar recursos do SharePoint em tempo real; ou seja, um suplemento pode solicitar permissão para acessar dinamicamente recursos do SharePoint no tempo de execução, e não no momento da instalação do suplemento. Esse tipo de suplemento não precisa ser iniciado nem instalado no SharePoint. Por exemplo, pode ser um suplemento de dispositivo nativo, um suplemento iniciado de qualquer site ou um Suplemento do Office iniciado de um aplicativo do Office que deseja acessar recursos no SharePoint em tempo real.

Observação

Esse tipo de suplemento só pode ser executado por usuários que têm permissões para gerenciar os recursos que o suplemento quer acessar. Por exemplo, se um suplemento solicita apenas permissão de leitura para um site, um usuário que tem direitos de leitura, mas não de gerenciamento do site não pode executar o suplemento.

Para poder chamar o SharePoint, esse tipo de suplemento deve primeiro ser registrado por meio do Painel do Vendedor ou na página AppRegNew.aspx. Saiba mais sobre como registrar suplementos por meio do Painel do Vendedor ou em AppRegNew.aspx em Registrar os Suplementos do SharePoint.

Depois que você registrar seu suplemento, ele será uma entidade de segurança e terá uma identidade exatamente como usuários e grupos. Essa identidade é considerada como entidade de segurança de suplemento. Como usuários e grupos, uma entidade de segurança de um suplemento tem certas permissões. Saiba mais sobre entidades de segurança de suplemento em Registrar Suplementos do SharePoint.

Ao registrar o suplemento você obtém uma ID do cliente, um segredo do cliente, o domínio do suplemento e o URI de redirecionamento da entidade de segurança do suplemento. Essas informações são registradas com o servidor de autorização, o Serviço de Controle de Acesso (ACS) do Microsoft Azure.

Fluxo OAuth de código de autorização para suplementos que solicitam permissões em tempo real

Esta seção resume o fluxo de autenticação e autorização OAuth para um suplemento do SharePoint que solicita permissões em tempo real. O fluxo se chama Fluxo de Código de Autorização. A sequência descreve como um suplemento não iniciado no SharePoint pode acessar os recursos do SharePoint.

Observação

O fluxo envolve uma série de interações entre seu suplemento, o SharePoint, o servidor de autorização (que é o ACS) e o usuário final no tempo de execução. Portanto, o fluxo requer o SharePoint Online ou um farm do SharePoint conectado à Internet para que possa se comunicar com o ACS. Os farms do SharePoint que não estão conectados à Internet devem usar o sistema de autorização de alta confiança.

É preciso haver um aplicativo ou serviço Web hospedado separadamente do SharePoint. Mesmo que o suplemento seja de dispositivo, ele precisa ter um aplicativo Web ou uma URL de serviço que possa ser registrada no ACS, mesmo se o componente da Web não for usado para mais nada.

Para simplificar, este artigo pressupõe que o suplemento é um aplicativo Web chamado Contoso.com. O aplicativo usa o modelo de objeto do cliente do SharePoint (CSOM) ou as APIs REST do SharePoint para fazer chamadas ao SharePoint. Quando o aplicativo tenta acessar o SharePoint pela primeira vez, o SharePoint solicita um código de autorização do ACS que possa enviar para o aplicativo Contoso.com. Em seguida, o aplicativo usa o código de autorização para solicitar um token de acesso do ACS. Depois que tiver o token de acesso, o aplicativo Contoso.com o inclui em todas as suas solicitações para o SharePoint.

Exemplo detalhado do fluxo

Digamos que a Contoso forneça um serviço de impressão de fotos online. Um usuário quer imprimir algumas fotos. O usuário deseja dar consentimento para que o serviço de impressão de fotos da Contoso acesse e imprima fotos de um conjunto de bibliotecas de fotos que o usuário mantém em um site do SharePoint Online, o fabrikam.sharepoint.com.

Visão geral do OAuth

O aplicativo de impressão de fotos está registrado, de modo que tem uma ID do cliente, um segredo do cliente e um URI de redirecionamento. O URI de redirecionamento que a Contoso disponibilizou ao registrar o suplemento é https://contoso.com/RedirectAccept.aspx. As informações de ID e segredo do cliente são armazenadas no arquivo web.config do aplicativo de impressão de fotos. Veja a seguir um exemplo de como a ID e o segredo do cliente são inseridos no arquivo web.config.

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

Etapas do fluxo de Código de Autorização

A seguir apresentamos as etapas do fluxo de Código de Autorização.

Dica

Estas etapas se referem a métodos no arquivo TokenHelper.cs. Esse código gerenciado não é compilado, de modo que não há tópicos de referência para ele. No entanto, o próprio arquivo é totalmente comentado com descrições de cada classe, parâmetro de membro e valor de retorno. É recomendável ter uma cópia aberta para consultar à medida que você lê estas etapas.

Etapa 1: o cliente abre um aplicativo e o direciona para um site do SharePoint para dados

Fluxo OAuth de três estágios – etapa 1

Um usuário navega até o site de impressão de fotos da Contoso, onde a interface de usuário indica que o usuário pode imprimir fotos mantidas em qualquer site do SharePoint Online.

Neste exemplo, a URL é https://contoso.com/print/home.aspx

O suplemento de impressão de fotos solicita que o usuário insira a URL da coleção de fotos. O usuário insere uma URL que aponta para o site do SharePoint Online: https://fabrikam.sharepoint.com/

Etapa 2: o suplemento redireciona para a URL de autorização do site do SharePoint

Fluxo OAuth de três estágios – etapa 2

Quando o usuário seleciona o botão para obter as fotos, o suplemento de impressão de fotos da Contoso redireciona o navegador para https://fabrikam.sharepoint.com/; trata-se de uma resposta de redirecionamento HTTP 302.

Se você está usando o Microsoft .NET, Response.Redirect é uma das várias maneiras de redirecionar pelo código. Com o arquivo TokenHelper.cs no projeto, seu código pode chamar o método GetAuthorizationUrl sobrecarregado (usando a sobrecarga com três argumentos). Esse método cria a URL de redirecionamento OAuthAuthorize.aspx para você. Ou seu código pode criar a URL manualmente.

Por exemplo, se você escolher chamar o método GetAuthorizationUrl para criar a URL de redirecionamento OAuthAuthorize.aspx, usando o TokenHelper.cs em seu projeto, o código será o seguinte:

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

Se você observar a sobrecarga de três parâmetros do método GetAuthorizationUrl no TokenHelper.cs, verá que o segundo parâmetro é de escopo de permissão, que é uma lista de permissões delimitada por espaço nas solicitações de suplemento em formato abreviado. Para saber mais sobre escopos de permissão, consulte Aliases de escopo de permissão e o uso da página OAuthAuthorize.aspx.

O terceiro parâmetro deve ter o mesmo URI de redirecionamento usado quando o suplemento foi registrado. Saiba mais sobre registro em Registrar suplementos do SharePoint. A cadeia de caracteres retornada é uma URL que inclui os parâmetros da cadeia de caracteres de consulta. Se preferir, é possível criar manualmente a URL de redirecionamento OAuthAuthorize.aspx. Por exemplo, a URL para a qual o suplemento de impressão de fotos da Contoso redireciona o usuário nesse caso é (quebras de linha para facilitar a leitura):

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

Como mostra o exemplo, o suplemento de impressão de fotos da Contoso envia a ID do cliente OAuth e o URI de redirecionamento para o site da Fabrikam como parâmetros de cadeia de caracteres de consulta. Veja a seguir um exemplo da solicitação GET com valores de exemplo de cadeia de caracteres de consulta. A URL de destino real é uma única linha.

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

Se você quiser uma caixa de diálogo pop-up de consentimento separada, adicione o parâmetro de consulta IsDlg=1 à criação da URL, como mostrado aqui: /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

Fluxo OAuth de três estágios – etapa 3

Se o usuário ainda não estiver conectado ao site do SharePoint Online da Fabrikam, será solicitado a entrar. Quando o usuário estiver conectado, o SharePoint renderizará uma página HTML de consentimento. A página de consentimento solicita que o usuário conceda (ou negue) ao suplemento de impressão de fotos da Contoso as permissões solicitadas pelo suplemento. Nesse caso, o usuário estaria concedendo o acesso de leitura do complemento à biblioteca de imagens do usuário na Fabrikam.

Etapa 4: o SharePoint solicita um código de autorização de curta duração do ACS

Fluxo OAuth de três estágios – etapa 4

O site da Fabrikam no SharePoint Online solicita ao ACS para criar um código de autorização de curta duração (aproximadamente 5 minutos) exclusivo para essa combinação de usuário e suplemento. O ACS envia o código de autorização para o site da Fabrikam.

Etapa 5: o site do SharePoint Online redireciona para o URI de redirecionamento registrado do aplicativo, passando o código de autorização para o suplemento

Fluxo OAuth de três estágios – etapa 5

O site da Fabrikam no SharePoint Online redireciona o navegador de volta à Contoso por meio da resposta HTTP 302. A criação de URL para esse redirecionamento usa o URI de redirecionamento especificado quando o suplemento de impressão de fotos foi registrado. Também inclui o código de autorização como uma cadeia de caracteres de consulta.

A URL de redirecionamento é estruturada da seguinte forma: https://contoso.com/RedirectAccept.aspx?code=[authcode]

Etapa 6: o suplemento usa o código de autorização para solicitar um token de acesso do ACS, que valida a solicitação, invalida o código de autorização e, em seguida, envia tokens de acesso e atualização ao suplemento

Fluxo OAuth de três estágios – etapa 6

A Contoso recupera o código de autorização do parâmetro de consulta e o inclui, com a ID e o segredo do cliente, em uma solicitação ao ACS para um token de acesso.

Se você está usando código gerenciado e o CSOM do SharePoint, o arquivo TokenHelper.cs, o método que fará a solicitação ao ACS é GetClientContextWithAuthorizationCode. Nesse caso, o código é semelhante ao seguinte (em authCode que é uma variável à qual o código de autorização foi atribuído):

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

Se você examinar o arquivo TokenHelper.cs, o segundo parâmetro do método GetClientContextWithAuthorizationCode é targetPrincipalName. Esse valor é sempre a constante 00000003-0000-0ff1-ce00-000000000000 em um suplemento que está acessando o SharePoint. Se você rastrear a hierarquia de chamadas de GetClientContextWithAuthorizationCode, ela obtém a ID e o segredo do cliente do arquivo web.config.

O ACS recebe a solicitação da Contoso e valida a ID do cliente, o segredo do cliente, o URI de redirecionamento e o código de autorização. Se todos forem válidos, o ACS invalida o código de autorização (ele pode ser usado apenas uma vez) e cria um token de atualização e um token de acesso, que são retornados à Contoso. O aplicativo da Contoso pode armazenar em cache esse token de acesso para reutilização em solicitações posteriores. Por padrão, os tokens de acesso são válidos por cerca de 12 horas.

Cada token de acesso é específico para a conta de usuário determinada na solicitação original de autorização e concede acesso apenas aos serviços especificados nessa solicitação. Seu suplemento deve armazenar o token de acesso com segurança. O aplicativo da Contoso também pode armazenar em cache o token de atualização. Por padrão, os tokens de atualização são válidos por seis meses. O token de atualização pode ser resgatado para um novo token de acesso do ACS sempre que o token de acesso expirar.

Saiba mais sobre tokens em Gerenciamento de tokens de segurança nos Suplementos do SharePoint de baixo nível de confiança hospedados pelo fornecedor.

Etapa 7: o suplemento agora pode usar o token de acesso para solicitar dados do site do SharePoint, que ele pode exibir para o usuário

Fluxo OAuth de três estágios – etapa 7

A Contoso inclui o token de acesso para fazer uma chamada da API REST ou uma solicitação CSOM para o SharePoint, transmitindo o token de acesso OAuth no cabeçalho HTTP Authorization. O SharePoint retorna as informações solicitadas pela Contoso.

Saiba mais sobre como essa solicitação é feita em Gerenciamento de tokens de segurança nos Suplementos do SharePoint de baixo nível de confiança hospedados pelo fornecedor.

Aliases de escopo de permissão e a página OAuthAuthorize.aspx

Esta seção pressupõe que você esteja familiarizado com o artigo Permissões de suplemento no SharePoint. A Tabela 1 mostra os mesmos URIs do escopo de solicitação de permissão do suplemento que são mostrados neste artigo, exceto por uma coluna adicional (Alias de escopo) e o direito FullControl (controle total), que não está disponível na coluna Direitos disponíveis, porque um suplemento que solicita permissão para acessar os recursos do SharePoint em tempo real não pode solicitar o direito FullControl.

Os valores listados na coluna Alias de escopo são versões abreviadas de seus equivalentes na coluna URI de escopo. Os aliases podem ser usados somente por suplementos que solicitam permissão para acessar recursos do SharePoint em tempo real. (Os valores de URI de escopo são usados no manifesto de suplemento de suplementos que são iniciados do SharePoint. Esses suplementos solicitam permissões durante a instalação do suplemento.)

Os aliases de escopo são usados somente no contexto de uso da página de redirecionamento OAuthAuthorize.aspx. Como mostrado na etapa 2 do fluxo OAuth descrita na seção anterior, quando o suplemento está usando o código gerenciado, os aliases são usados ao chamar o método GetAuthorizationUrl de TokenHelper.cs em seu projeto. Este é outro exemplo:

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

O valor de parâmetro scope, Web.Read List.Write, é um exemplo de como você solicitaria permissões usando os aliases de escopo. O parâmetro scope é um conjunto de escopo de permissão e solicitações de direito delimitado por espaços.

Se você não está usando código gerenciado, os aliases de escopo são usados no campo de escopo na URL de redirecionamento. Por exemplo:

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

Observação

Obtenha uma descrição dos escopos em Permissões de suplemento no SharePoint.

Tabela 1. URIs de escopo de solicitação de permissão de suplemento do SharePoint e seus aliases correspondentes

URI de escopo Alias de escopo Direitos disponíveis
https://sharepoint/content/sitecollection Site Ler, gravar, gerenciar
https://sharepoint/content/sitecollection/web Web Ler, gravar, gerenciar
https://sharepoint/content/sitecollection/web/list List Ler, gravar, gerenciar
https://sharepoint/content/tenant AllSites Ler, gravar, gerenciar
https://sharepoint/bcs/connection None (nenhum, recurso incompatível no momento) Ler
https://sharepoint/search Search QueryAsUserIgnoreAppPrincipal
https://sharepoint/projectserver ProjectAdmin Gerenciar
https://sharepoint/projectserver/projects Projects Ler, gravar
https://sharepoint/projectserver/projects/project Project Ler, gravar
https://sharepoint/projectserver/enterpriseresources ProjectResources Ler, gravar
https://sharepoint/projectserver/statusing ProjectStatusing SubmitStatus
https://sharepoint/projectserver/reporting ProjectReporting Ler
https://sharepoint/projectserver/workflow ProjectWorkflow Elevar
https://sharepoint/social/tenant AllProfiles Ler, gravar, gerenciar
https://sharepoint/social/core Social Ler, gravar, gerenciar
https://sharepoint/social/microfeed Microfeed Ler, gravar, gerenciar
https://sharepoint/taxonomy TermStore Ler, gravar

URIs de redirecionamento e um exemplo de página de redirecionamento

O URI de redirecionamento usado pelos suplementos que solicitam permissão em tempo real é o URI para o qual o SharePoint redireciona o navegador após atribuir consentimento (com o código de autorização incluído como um parâmetro de consulta). A Etapa 2 do fluxo OAuth fornece um exemplo em que o URI é codificado em uma chamada para o método GetAuthorizationUrl. Como alternativa, um suplemento do ASP.NET também pode armazenar o URI de redirecionamento no arquivo web.config conforme mostrado neste exemplo:

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

O valor pode ser recuperado com uma chamada para WebConfigurationManager.AppSettings.Get("RedirectUri").

O ponto de extremidade no RedirectUri obtém o código de autorização do parâmetro de consulta e o utiliza para obter um token de acesso, que pode ser usado para acessar o SharePoint. Normalmente, o ponto de extremidade é a mesma página, método controlador ou método da Web que tentou acessar o SharePoint originalmente. No entanto, pode ser uma página ou um método que apenas recebe o token de autorização e, em seguida, redireciona para outra página ou método. A página ou o método especial pode passar o token de autorização ou armazená-lo em cache. (Ele tem uma vida útil de cerca de 5 minutos.) Como alternativa, ele pode usar o token de autorização para obter um token de acesso para armazenar em cache.

Importante

O RedirectUri deve ser o mesmo ponto de extremidade listado quando você criou o aplicativo na página AppRegNew.aspx.

Veja a seguir um exemplo do código por trás desse tipo de página em um aplicativo ASP.NET. Observe o seguinte sobre este código:

  • Ele usa o arquivo TokenHelper.cs que é gerado pelo Office Developer Tools para Visual Studio.
  • O código presume que haja um parâmetro de consulta "código" contendo um código de autorização. Isso é seguro porque a página só é chamada pelo SharePoint e apenas quando ela está passando um código de autorização.
  • Ele usa o objeto de contexto de cliente CSOM para acessar o SharePoint, mas pode também ter simplesmente armazenado em cache esse objeto no servidor e redirecionado para outra página.
  • O método GetClientContextWithAuthorizationCode usa o código de autorização para obter um código de acesso. Em seguida, cria um objeto de contexto do cliente do SharePoint e modifica o manipulador do objeto para o evento ExecutingWebRequest para que o manipulador inclua o token de acesso em todas as solicitações para o SharePoint. O token de acesso é, na verdade, armazenado em cache dentro do objeto.
  • O método GetClientContextWithAuthorizationCode envia a URL de redirecionamento de volta ao ACS no parâmetro rUrl, mas o ACS o usa como uma forma de identificação no caso do código de autorização ter sido roubado. O ACS não o usa para redirecionar novamente, então esse código não realiza um loop indefinidamente redirecionando a si mesmo.
  • O código não apresenta instruções para lidar com um token de acesso expirado. Depois que o objeto de contexto do cliente é criado, ele continua usando o mesmo token de acesso. Ele não usa o token de atualização. Essa é uma estratégia apropriada para suplementos usados apenas em sessões que duram menos tempo do que um token de acesso.

Para obter um exemplo mais complexo que usa o token de atualização para obter um novo token de acesso, consulte a próxima seção.

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>");
    }
  }
}

Exemplo de código por trás da amostra para uma página que acessa o SharePoint

Veja a seguir um código por trás de uma página Default.aspx. Essa página supõe um cenário em que a página padrão seja a página inicial para o suplemento e também seja a URL de redirecionamento registrada para o suplemento. Observe o seguinte sobre este código:

  • Primeiro, o método Page_Load verifica se há um código de autorização na cadeia de caracteres de consulta. Haverá um se o navegador tiver sido redirecionado para a página pelo SharePoint. Se houver um, o código o usa para obter um novo token de atualização, que ele armazena em um cache que dura por várias sessões.

  • Em seguida, o método verifica se há um token de atualização no cache.

    • Se não houver, ele obtém um informando ao SharePoint as permissões necessárias (permissão para gravar no escopo da Web) e pedindo ao SharePoint um código de autorização. O usuário é solicitado a conceder a permissão e, se for concedida, o SharePoint recebe o código de autorização do ACS e o envia novamente como um parâmetro de consulta em um redirecionamento para essa mesma página.
    • Se houver um token de atualização em cache, o método o usa para obter um token de acesso diretamente do ACS. Como no exemplo no final da seção anterior deste artigo, o token de acesso é usado para criar um objeto de contexto de cliente do SharePoint. Usar um token de atualização em cache para obter um token de acesso diretamente do ACS evita a chamada de rede adicional para o SharePoint no início da sessão, para que os usuários que executem novamente o suplemento durante a vida útil do cache do token de atualização tenham uma inicialização mais rápida.
  • Como no exemplo no final da seção anterior, esse código não apresenta instruções para lidar com um token de acesso expirado. Depois que o objeto de contexto do cliente é criado, ele continua usando o mesmo token de acesso. Uma forma de se proteger contra um token de acesso expirado é armazenar o token de acesso e de atualização em cache. Você modificaria o código a seguir para chamar o método GetAccessToken somente se não houvesse um token de acesso não expirado no cache.

    No entanto, embora seja aceitável armazenar o token de atualização em cache no cliente (em um cookie, por exemplo), o token de acesso deve estar apenas em um cache do lado do servidor, por motivos de segurança. O token de atualização é criptografado e só pode ser descriptografado pelo ACS. Porém o token de acesso é meramente codificado (com codificação de Base 64) e pode ser decodificado com facilidade por um ataque man-in-the-middle.

  • A classe TokenCache, que é chamada nesse código, está definida mais adiante nesta seção.

Código por trás de uma página 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>");
        }
      }
    }
  }
}

Veja a seguir um exemplo de código para um módulo de cache de token que o código de amostra anterior chama. Ele usa cookies como cache. Há outras opções de cache. Saiba mais em Gerenciamento de tokens de segurança nos Suplementos do SharePoint de baixo nível de confiança hospedados pelo fornecedor.

Exemplo de código para um módulo de cache de token

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);
      }
    }
  }
}

Confira também