Sessões & Segurança

Sessões de documento e controle de acesso

Um token Doconut é poderoso: quem o apresenta poderia solicitar todas as páginas do documento se não estivesse vinculado à sessão de abertura. Esta página explica o que uma sessão contém, quanto tempo ela dura e as verificações que UseDoconut() habilita por padrão.

O que uma sessão de documento contém

  • o visualizador de formato carregado (a instância do motor de documento que contém o documento analisado),
  • estado por página — rotação, inversões e dados de anotação que o usuário aplica no widget,
  • o índice de busca opcional, construído de forma preguiçosa na primeira busca (ou carregado de um arquivo .srh pré-construído quando as páginas são servidas a partir de armazenamento compartilhado),
  • a marca d'água da sessão proveniente de DocOptions.Watermark.

Tempo de vida

As sessões expiram em uma janela deslizante: DocOptions.TimeOut minutos (padrão 60), redefinida a cada solicitação que apresenta o token. Quando uma sessão é removida — por expiração ou por CloseDocument(token) — seu callback de remoção descarta o motor de documento e libera a memória associada imediatamente.

csharp
// Uma sessão de curta duração para uma visualização única
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });

Uma solicitação com um token expirado recebe uma imagem de erro contendo Document session not found. Please re-open document. — o cliente deve reabrir para obter um token novo.

Vinculação de token incorporada

Com UnsafeMode = false (o padrão), OpenDocumentAsync vincula o novo token à sessão ASP.NET da requisição HTTP que o abriu, gravando um marcador secure-{token} nessa sessão. O middleware Doconut então se recusa a servir páginas para qualquer outra sessão de navegador:

  • Navegador/sessão diferente apresentando um token roubado → imagem de erro You Are Not Authorized To View This Page.
  • Middleware de sessão não registrado → HTTP 500 Session middleware not configured. Call UseSession() before UseDoconut().

É por isso que o Quick Start insiste em AddSession() + app.UseSession() antes do ramo Doconut. Duas consequências práticas:

  • O cliente deve enviar o cookie de sessão ASP.NET com as solicitações de página. Configurações cross-origin que removem cookies (ou um cliente API sem jar de cookies) falharão na verificação — isso é a funcionalidade em ação, não um bug.
  • options.UnsafeMode = true desabilita completamente a vinculação. Ela existe para cenários controlados; mantenha-a false em produção em um único nó.

Observe a grafia. A biblioteca .NET Standard anterior chamava essa propriedade de UnSafeMode e ela era passada ao middleware; aqui ela é UnsafeMode e é definida uma única vez dentro de AddDoconut().

A vinculação de token é controlada exclusivamente por este interruptor global UnsafeMode — ele está ativado por padrão (UnsafeMode = false) e se aplica a todas as sessões. Não há opção de desativação por documento; definir UnsafeMode = true desativa a vinculação globalmente.

Concessões de acesso e usuários autenticados

Quando UnsafeMode está false, UseDoconut() insere o middleware de acesso ao documento automaticamente antes do middleware de página. Não o registre uma segunda vez. Quando uma requisição traz um token, ele procura a concessão de acesso registrada quando o documento foi aberto e autoriza somente se todas as seguintes condições forem atendidas:

  1. exista uma concessão para o token,
  2. não tenha expirado (tempo de vida da concessão = o TimeOut do documento),
  3. o ID da sessão ASP.NET da requisição corresponda ao que abriu o documento,
  4. se o abridor estava autenticado, a reivindicação NameIdentifier do usuário da requisição também corresponda.

Falhas retornam 403 — como uma imagem PNG de erro para solicitações de página/miniatura, como texto simples caso contrário. A mensagem e a chave de consulta do token vêm de DocumentSecurityOptions (TokenQueryKey, padrão "token"; UnauthorizedMessage, padrão "You Are Not Authorized To View This Page."). Configure essas opções através do DI do ASP.NET Core antes de construir o aplicativo. Se o estado da sessão não estiver disponível, o middleware falha fechado com HTTP 500: ASP.NET Session is required for Doconut document security.

csharp
builder.Services.Configure<Doconut.Security.DocumentSecurityOptions>(options =>
{
    options.TokenQueryKey = "token";
    options.UnauthorizedMessage = "You Are Not Authorized To View This Page.";
});

O middleware central de página então verifica o marcador de sessão secure-{token} antes de servir o documento. Com UnsafeMode = true, UseDoconut() pula o middleware de acesso e a verificação do marcador central também é desativada.

Segurança em vários nós

Tokens vinculados à sessão assumem que o nó que serve uma página também viu a requisição que abriu o documento. Essa suposição não se sustenta quando vários nós servem os mesmos documentos a partir de armazenamento compartilhado: uma solicitação de página pode chegar a um nó que nunca viu a abertura, e a verificação por sessão a rejeita.

A solução não é deixar os documentos desprotegidos. Use tickets de acesso assinados através de AddDoconutDistributedDocumentSecurity(...), que substitui a verificação de sessão por uma credencial que cada nó pode verificar independentemente. O arranjo completo está em Implantações Distribuídas.

Revogação

CloseDocument(token) não apenas libera memória — ele também remove o marcador secure-{token} e revoga a concessão de acesso, de modo que um token fechado fica inativo em ambas as camadas de segurança imediatamente.

Lista de verificação para produção

  • Mantenha UnsafeMode = false (o padrão) em um único nó — este interruptor global é o que vincula tokens às sessões.
  • Registre AddDistributedMemoryCache() (aplicações MVC e Razor Pages já o possuem) e AddSession(), e chame app.UseSession() antes do ramo do middleware Doconut.
  • Certifique-se de que a política de cookies de sessão permite que as solicitações do widget carreguem o cookie (SameSite, HTTPS).
  • Use CloseDocument quando o usuário sair do documento — memória e segurança se beneficiam.
  • Nunca registre ou compartilhe tokens; trate-os como credenciais de curta duração.
  • Servindo a partir de armazenamento compartilhado? Mude para tickets de acesso assinados em vez de aceitar documentos desprotegidos.

Esta página foi útil?