Skip to content

方法路由与业务鉴权 ​

本章介绍方法路由、业务鉴权拦截器及其配置方式。tio-boot 使用 Java 8 编译,tio-boot-admin 使用 Java 21 编译;Java 版本与 Maven 组件版本是两回事。

1. 本地构建顺序 ​

先在 t-io 根目录使用 JDK 8 执行,再在 tio-boot-admin 根目录使用 JDK 21 执行:

powershell
mvn install -Dgpg.skip=true -Dmaven.javadoc.skip=true

t-io 是包含 tio-http-common、tio-http-server、tio-boot 等模块的 reactor,相关模块应使用一致的版本并安装到本地仓库,不能只更新业务项目中的版本号。上述命令只安装到本地仓库,跳过发布签名和 Javadoc 打包,不执行 deploy。

业务工程使用 Java 21,并使 tio-boot-admin-web 依赖与本地安装的框架版本保持一致。检查依赖树,避免显式固定的旧版 tio-http-server 抢占新版本。

powershell
mvn dependency:tree -Dincludes=nexus.io
mvn test

2. 按方法注册路由 ​

java
HttpRequestRouter router = TioBootServer.me().getRequestRouter();
router.get("/api/items", request -> Resps.json(request, "list"));
router.post("/api/items", request -> Resps.json(request, "created"));
router.add(HttpMethod.DELETE, "/api/items/{id}", request -> {
  String id = request.getParam("id");
  return Resps.json(request, id);
});

需要导入 nexus.io.tio.http.common.HttpMethod、nexus.io.tio.http.server.router.HttpRequestRouter、nexus.io.tio.http.server.util.Resps、nexus.io.tio.boot.server.TioBootServer。

  • 同一路径可同时注册 GET 与 POST;重复注册同一 (method, path) 会抛出 IllegalArgumentException。
  • 旧 add(path, handler) 仍表示 ANY,重复注册仍覆盖。新接口优先于 ANY;迁移后应删除同一接口的旧 ANY 注册,避免其他方法通过兼容回退进入业务。
  • 方法不支持时返回 405 和 Allow;路径不存在时返回 404。
  • HEAD 优先使用显式 HEAD,其次 GET,身份策略继承选中的路由;编码器不发送内存/文件响应体。
  • 自动 OPTIONS 对已知方法路由返回 204 与 Allow;显式 OPTIONS Handler 优先。CORS 预检另外由 CORS 配置处理。
  • 框架生成的 405 没有业务 JSON 包装,前端必须检查 HTTP 状态,不能假定所有响应都有 code。

详细匹配与兼容规则见 分发与路由优先级。

3. 路由声明策略,拦截器执行鉴权 ​

核心框架不内置 PUBLIC / USER / ADMIN 业务枚举。业务可以通过 metadata 声明策略:

java
router.add(HttpMethod.POST, "/api/items", handler,
    java.util.Collections.singletonMap("app.access", "user"));

HttpRequestInterceptor 新增默认方法:

java
default HttpResponse doBeforeRoute(HttpRequest request, RequestLine line,
    HttpResponse response, RouteMatch match) throws Exception {
  return null;
}

普通 Handler 匹配成功后,match.getRoute().getMetadata() 是实际选中方法的策略。Groovy、Function、Controller 的回调中 match 为 null;这些路由继续使用既有权限配置,不能臆测它们具有 Handler 的 metadata。旧 doBeforeHandler 保持在匹配前执行,doAfterHandler 保留原有按路径规则调用的行为。

业务拦截器的职责:

  1. 按选中路由读取策略;对所负责的业务前缀,缺失策略应拒绝访问。
  2. 公开路由直接返回 null;用户路由验证用户 Token;后台路由验证管理员 Token 和后台账号权限。
  3. 成功后写入 TioRequestContext.setIdentity(new RequestIdentity(userId, "app-user", tenantId))。该方法同时设置兼容的 request.userId。RequestIdentity 位于 nexus.io.tio.boot.token,也可直接使用旧 setUserId。
  4. 失败返回明确的 401/403 响应;成功返回 null 后执行 Handler。

RequestIdentity 只保存已验证身份,不验证 Token。UserTokenInterceptor、TokenPredicate 仍可用于已有的匹配前鉴权。资源归属、租户条件、状态流转、额度和扣费事务继续由 Service 检查。

4. 拦截器组合 ​

java
HttpInteceptorConfigure config = TioBootServer.me().getHttpInteceptorConfigure();
if (config == null) config = new HttpInteceptorConfigure();
HttpInterceptorModel model = new HttpInterceptorModel();
model.setName("app-business-auth");
model.addBlockUrl("/api/app/**");
model.setInterceptor(businessInterceptor);
config.add(model);
TioBootServer.me().setHttpInteceptorConfigure(config);

配置类型位于 nexus.io.tio.boot.http.interceptor。为模型设置稳定名称;同名注册用于替换同一个逻辑拦截器。未命名模型会获得不同的生成名称,不再因 null 键互相覆盖。

TioAdminInterceptorConfiguration 使用名称 tio-admin-token,加入现有配置;重复调用替换该管理员模型,不删除其他业务模型。原有六个标准配置调用保持不变,无需再次创建连接池或注册 ApiTable。

model.setMethods(HttpMethod.POST, HttpMethod.DELETE) 可限制模型作用的方法;未设置表示所有方法。方法过滤先于该模型的 URL 白名单/黑名单。URL 白名单仍是该模型内的路径规则,不应把公开 GET 路径加入全方法白名单后误放行 POST。

为业务前缀跳过管理员认证时,必须同时注册业务拦截器。不要放行 /api/table/**。

5. 验证迁移 ​

  • 同一路径 GET 公开、POST 要求登录:匿名 GET 成功,匿名 POST 为 401。
  • 用户 Token 不能访问后台接口;管理员 Token 不能当作普通用户身份使用。
  • 错误方法为 405 且包含 Allow;未知路径为 404;HEAD 不包含响应体。
  • 启用 CORS 时,浏览器预检成功且实际写请求仍须鉴权。
  • 拦截器短路和异常路径结束后,线程上的请求上下文已清理;after 阶段仍可读取身份。
  • 数据库 SQL 仍由用户手动执行。升级框架不会自动建表、修改业务数据或安装 Redis、ES、Sa-Token。

单数据源业务直接调用静态 Db,Store 无需持有或注入 DbPro;事务和 JSONB 用法见 Db 与 PostgreSQL 业务实践。

MIT Licensed