会话与安全
文档会话和访问控制
Doconut 令牌功能强大:如果不绑定到打开会话,任何持有它的人都可以请求文档的每一页。本页解释会话保存了什么、会话的存活时间,以及 UseDoconut() 默认启用的检查。
文档会话保存的内容
每次成功的 OpenDocumentAsync 都会在 IMemoryCache 中创建一个会话:
- 已加载的格式查看器(持有已解析文档的文档引擎实例),
- 每页状态 — 旋转、翻转以及用户在小部件中应用的注释数据,
- 可选的 搜索索引,在首次搜索时惰性构建(或在 Web 农场场景中从预构建的
.srh文件加载), - 会话的 水印 来自
DocOptions.Watermark。
生命周期
会话在 滑动窗口 中过期:DocOptions.TimeOut 分钟(默认 60),每次呈现令牌的请求都会重置。当会话被驱逐——因过期或因 CloseDocument(token) ——其驱逐回调会立即释放文档引擎并释放相关内存。
// 用于一次性预览的短期会话
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });使用已过期令牌的请求会收到显示 Document session not found. Please re-open document. 的错误图片——客户端必须重新打开以获取新的令牌。
内置令牌绑定
使用 UnsafeMode = false(默认),OpenDocumentAsync 将新令牌绑定到打开它的 HTTP 请求的 ASP.NET 会话,通过在该会话中写入 secure-{token} 标记。Doconut 中间件随后拒绝向任何其他浏览器会话提供页面:
- 不同的浏览器/会话呈现被盗令牌 → 错误图片
You Are Not Authorized To View This Page. - 未注册会话中间件 → HTTP 500
Session middleware not configured. Call UseSession() before UseDoconut().
这就是快速入门在 Doconut 分支之前坚持使用 AddSession() + app.UseSession() 的原因。两个实际后果:
- 客户端必须在页面请求中发送 ASP.NET 会话 cookie。跨域设置如果剥离 cookie(或 API 客户端没有 cookie jar)将导致检查失败——这属于功能正常,而非 bug。
options.UnsafeMode = true完全禁用绑定。它用于受控场景(例如服务器到服务器渲染);在生产环境中保持false。
令牌绑定仅由全局 UnsafeMode 开关控制——默认开启(UnsafeMode = false),并适用于每个会话。没有每文档的选择退出;设置 UnsafeMode = true 会全局禁用绑定。
访问授权与已认证用户
当 UnsafeMode 为 false 时,UseDoconut() 会在页面中间件之前自动插入 DocumentAccessMiddleware。不要二次注册它。当请求携带令牌时,它会查找文档打开时记录的 访问授权,仅在以下全部满足时授权:
- 令牌存在授权,
- 授权未过期(授权生命周期 = 文档的
TimeOut), - 请求的 ASP.NET 会话 ID 与打开文档的会话 ID 匹配,
- 如果打开者已认证,请求用户的
NameIdentifier声明也必须匹配。
失败时返回 403 —— 对页面/缩略图请求返回 PNG 错误图片,其他情况返回纯文本。消息和令牌查询键来源于 DocumentSecurityOptions(TokenQueryKey,默认 "token";UnauthorizedMessage,默认 "You Are Not Authorized To View This Page.")。在构建应用之前通过 ASP.NET Core DI 配置这些选项。如果会话状态不可用,中间件会以 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.";
});核心页面中间件在提供文档之前会验证 secure-{token} 会话标记。使用 UnsafeMode = true 时,UseDoconut() 会跳过访问中间件,核心标记检查也会被禁用。
撤销
CloseDocument(token) 不仅释放内存——它还会移除 secure-{token} 标记并撤销访问授权,因此已关闭的令牌会立即在两个安全层面失效。
生产环境检查清单
- 保持
UnsafeMode = false(默认)——此全局开关用于将令牌绑定到会话。 - 注册
AddDistributedMemoryCache()(MVC 和 Razor Pages 应用已默认拥有)和AddSession(),并在 Doconut 中间件分支之前调用app.UseSession()。 - 确保会话 cookie 策略允许小部件的请求携带 cookie(
SameSite,HTTPS)。 - 当用户离开文档时使用
CloseDocument—— 可同时提升内存和安全性。 - 切勿记录或共享令牌;将其视为短期凭证。
此页面对您有帮助吗?