会话与安全
文档会话和访问控制
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 会将新令牌绑定到发起请求的 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(或没有 Cookie 桶的 API 客户端)会导致检查失败——这属于功能正常,而非 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——既可释放内存,又可提升安全性。 - 切勿记录或共享令牌;应将其视为短期凭证。
此页面对您有帮助吗?