基于Quarkus的Kogito如何配置API Token实现服务间认证
Quarkus+Kogito 自定义请求头API Token服务间认证配置
针对Kogito基于DMN生成的接口,不需要引入JWT、OAuth等重型安全组件,通过Quarkus原生路由拦截能力即可实现请求头传递API Token的服务端到服务端认证,全程不侵入Kogito自动生成的接口逻辑,配置步骤如下:
1. 引入最小必要依赖
仅需引入Quarkus安全核心与Web路由相关依赖,不需要额外引入安全认证框架,在项目pom.xml中添加如下依赖即可:
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-elytron-security-common</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-vertx-http</artifactId> </dependency>
2. 配置安全规则与Token参数
在application.properties中关闭不需要的默认认证机制,配置Token请求头、合法Token值、接口权限规则:
# 关闭默认不需要的认证方式 quarkus.http.auth.basic=false quarkus.smallrye-jwt.enabled=false # API Token自定义配置 api.security.header-name=X-API-Token # 合法Token值,生产环境通过环境变量注入,避免硬编码泄露 api.security.valid-token=${API_AUTH_TOKEN:kogito-dmn-dev-token-2024} # 权限规则:所有Kogito生成的DMN接口需要认证 quarkus.http.auth.permission.dmn-apis.paths=/dmn/* quarkus.http.auth.permission.dmn-apis.policy=authenticated # 权限规则:运维类接口公开放行,不需要Token quarkus.http.auth.permission.public.paths=/q/health/*,/q/swagger-ui/*,/q/openapi/* quarkus.http.auth.permission.public.policy=permit
3. 实现请求头Token校验拦截逻辑
通过Quarkus原生路由过滤器,在请求进入Kogito接口处理逻辑前完成Token校验,校验不通过直接返回401,校验通过则注入合法身份放行请求:
package com.yourpackage.kogito.config; import io.quarkus.vertx.web.RouteFilter; import io.vertx.ext.web.RoutingContext; import jakarta.enterprise.context.ApplicationScoped; import org.eclipse.microprofile.config.inject.ConfigProperty; @ApplicationScoped public class ApiTokenAuthFilter { @ConfigProperty(name = "api.security.header-name") String tokenHeaderName; @ConfigProperty(name = "api.security.valid-token") String validToken; private static final String UNAUTHORIZED_RESP = "{\"code\":401,\"message\":\"Invalid or missing API Token\"}"; // 过滤器优先级设为100,优先于Kogito业务路由执行 @RouteFilter(100) void checkToken(RoutingContext ctx) { String requestPath = ctx.request().path(); // 直接放行公开路径 if (requestPath.startsWith("/q/") || !requestPath.startsWith("/dmn/")) { ctx.next(); return; } // 从指定请求头提取Token String requestToken = ctx.request().getHeader(tokenHeaderName); if (requestToken == null || !requestToken.equals(validToken)) { ctx.response() .setStatusCode(401) .putHeader("Content-Type", "application/json") .end(UNAUTHORIZED_RESP); return; } // 校验通过,注入服务调用身份,满足Quarkus认证要求 ctx.setUser(new InternalServiceUser()); ctx.next(); } }
补充实现最简身份类,适配Quarkus安全上下文要求,不需要复杂权限逻辑:
package com.yourpackage.kogito.config; import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; public class InternalServiceUser implements User { @Override public JsonObject attributes() { return new JsonObject().put("callerType", "internal-service"); } @Override public User isAuthorized(String authority, io.vertx.core.Future<Boolean> resultHandler) { resultHandler.complete(true); return this; } @Override public User clearCache() { return this; } @Override public JsonObject principal() { return new JsonObject().put("username", "internal-service-caller"); } @Override public void setAuthProvider(io.vertx.ext.auth.authentication.AuthenticationProvider provider) { // 无需额外认证提供方 } }
4. 配置验证
服务启动后按以下规则验证即可:
- 未携带
X-API-Token请求头访问/dmn/路径下的任意DMN接口,返回401状态码 - 请求头携带错误Token值访问上述接口,返回401
- 请求头携带配置的合法Token值访问接口,可正常获取DMN计算结果,与原有接口逻辑完全兼容
- 加入白名单的健康检查、Swagger、OpenAPI等接口,无需Token即可正常访问
生产环境注意事项:不要将合法Token硬编码在配置文件中,需通过环境变量、密钥管理服务注入;如果需要给不同调用方分配不同Token做细粒度权限隔离,只需将单Token配置改为合法Token列表,调整校验逻辑判断请求Token是否在列表中即可,整体框架不需要改动。
内容的提问来源于stack exchange,提问作者josesuero
相关产品推荐
相关产品推荐

