MicroProfile 2.0下OpenAPI3全局多Header安全如何配置为AND逻辑
实际场景
当前正在将OpenAPI v2迁移至OpenAPI 3,使用MicroProfile 2.0,通过对应插件从代码生成OAS文档。现有多类请求头需作为授权校验规则,最初尝试逐接口添加校验规则的方式重复度极高,因此选择在JaxRSConfiguration文件中通过@SecurityScheme定义这些请求头规则,并将其作为全局安全配置添加到@OpenAPIDefinition中,示例配置如下:
@OpenAPIDefinition( info = @Info(...), security = { @SecurityRequirement(name = "Header1"), @SecurityRequirement(name = "Header2") }, components = @Components( securitySchemes = { @SecurityScheme(apiKeyName = "Header1", ...), @SecurityScheme(apiKeyName = "Header2", ....) } ), ... )
这种写法可正常生成文档,但生成的安全配置为OR逻辑(即仅需满足其中一个Header校验即可),与业务要求的AND逻辑(需同时满足两个Header校验)不符,对应生成的YAML配置为:
security: - Header1: [] - Header2: []
之前的尝试路径存在明显限制:
- 原计划在
@OpenAPIDefinition的security配置中使用@SecurityRequirementsSet实现逻辑调整,但该注解无法直接用于MicroProfile 2.0版本的全局security配置 - 可在单个接口或资源类层级使用该注解,但仍存在重复配置的问题
核心需求是在全局层级实现多Header安全校验的AND逻辑配置,避免重复编写注解。
OpenAPI 3 安全逻辑核心判定规则
根据OpenAPI 3的标准定义,安全校验的逻辑判定规则非常明确:
- 顶层
security字段是一个安全要求数组,数组内不同条目之间为OR关系——只要满足任意一个条目的要求,即可通过校验 - 同一个安全要求条目内定义的多个安全方案为AND关系——必须满足条目里列出的所有安全方案,才可通过校验
要实现双Header的AND校验效果,最终需要生成的YAML结构必须满足:所有需要同时校验的Header全部放在同一个安全要求条目下,不能拆成独立的数组项,即正确结构如下:
security: # 数组仅包含1个条目,条目下同时列出两个Header,代表需同时校验 - Header1: [] Header2: []
MicroProfile 2.0 适配实现方案
MicroProfile 2.0对应的OpenAPI注解实现中,@SecurityRequirement注解的设计为每个实例仅能绑定一个安全方案名称,因此直接在@OpenAPIDefinition中书写两个@SecurityRequirement时,会被拆分为两个独立的数组条目,自然生成OR逻辑配置。可通过以下两种无重复配置的方式实现全局AND逻辑的安全规则:
方案1:通过OASModelReader SPI修正全局模型
- 编写实现
org.eclipse.microprofile.openapi.spi.OASModelReader接口的类,重写模型构建逻辑 - 在构建逻辑中,先加载注解扫描生成的基础OpenAPI模型,手动修改全局security配置,把需要同时校验的多个Header合并为同一个安全要求对象
示例代码:public class GlobalSecurityModelReader implements OASModelReader { @Override public OpenAPI buildModel() { // 获取注解扫描生成的基础OpenAPI模型 OpenAPI baseModel = OASConfigReader.getAnnotatedModel(); // 构建包含两个Header的AND逻辑安全要求 SecurityRequirement andRequirement = new SecurityRequirement() .addScheme("Header1", Collections.emptyList()) .addScheme("Header2", Collections.emptyList()); // 覆盖全局security配置 baseModel.setSecurity(Collections.singletonList(andRequirement)); return baseModel; } } - 按照SPI规范,在
META-INF/services目录下创建对应接口的配置文件,写入该实现类的全限定名,插件启动时会自动加载修正后的模型。
方案2:通过MicroProfile配置属性覆盖全局配置
MicroProfile OpenAPI支持通过microprofile-config.properties配置文件直接覆盖OpenAPI模型的任意节点,无需修改代码注解,直接在配置文件中写入对应配置即可生成AND逻辑的安全规则:
mp.openapi.extensions.smallrye.security[0].Header1=[] mp.openapi.extensions.smallrye.security[0].Header2=[]
这种方式会把两个Header的要求绑定到security数组的第0个元素下,完全符合OpenAPI的AND逻辑判定规则,全局生效无需逐接口重复配置。
注:
@SecurityRequirementsSet注解是MicroProfile 3.0及以上版本新增的能力,在MicroProfile 2.0版本中不支持全局层级使用,上述两种方案可完美适配2.0版本的能力边界。
内容的提问来源于stack exchange,提问作者Tommy

