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
.srhpré-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.
// 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 = truedesabilita completamente a vinculação. Ela existe para cenários controlados; mantenha-afalseem 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:
- exista uma concessão para o token,
- não tenha expirado (tempo de vida da concessão = o
TimeOutdo documento), - o ID da sessão ASP.NET da requisição corresponda ao que abriu o documento,
- se o abridor estava autenticado, a reivindicação
NameIdentifierdo 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.
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) eAddSession(), e chameapp.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
CloseDocumentquando 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?