[英]'oneOf' not working as expected - json validation must fail but it is passing
我正在尝试编写一个模式来验证AWS IAM安全组不得指定传入的IP地址“0.0.0.0/0”可以连接到端口22。
我正在使用oneOf运算符并定义两组属性,我的直觉是如果两个属性都满足,JSON模式应该会失败,但事实并非如此。
示例JSON -
{
"ipPermissions": [
{
"toPort": -1,
"fromPort": -1,
"ipRanges": [
"10.0.0.0/16"
]
},
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"0.0.0.0/0"
],
"ipProtocol": "tcp"
}
]
}
上面的JSON 应该失败,因为ipPermission[1]
对象是 -
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"0.0.0.0/0"
],
"ipProtocol": "tcp"
}
作为ipRanges
具有值0.0.0.0/0
当toPort
是22
以下JSON文档应通过验证 -
{
"ipPermissions": [
{
"toPort": 22,
"fromPort": -1,
"ipRanges": [
"10.0.0.0/16"
]
},
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"somethingElse"
],
"ipProtocol": "tcp"
}
]
}
因为ipPermissions
index [0]对象的toPort
值为22
但ipRanges[0]
值为10.0.0.0/16
,而不是0.0.0.0/0
以下JSON不应通过验证 -
{
"ipPermissions": [
{
"toPort": 22,
"fromPort": -1,
"ipRanges": [
"10.0.0.0/16"
]
},
{
"toPort": 22,
"fromPort": 53,
"ipRanges": [
"somethingElse",
"0.0.0.0/0"
],
"ipProtocol": "tcp"
}
]
}
as ipPermissions[1].ipRanges[1]
值是0.0.0.0/0
我的JSON架构 -
{
"$schema": "http://json-schema.org/draft-04/schema#",
"required": [
"ipPermissions"
],
"properties": {
"ipPermissions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"oneOf": {
"ipRanges": {
"type": "array",
"items": {
"type": "string",
"value": "0.0.0.0/0"
}
},
"toPort": {
"type": "integer",
"minimum": 23
}
}
}
}
}
}
}
这个有点复杂,所以我使用definitions
将其分解,以便更容易理解。
一般策略是首先定义属性,然后使用anyOf
, oneOf
, allOf
, not
和/或dependencies
分别添加复杂约束。 在这种情况下,我采用的方法是定义一个与您要禁止的情况相匹配的模式,如果该模式匹配not
使用验证失败。
这是验证“toPort”是否为“22”且“ipRanges”数组是否包含“0.0.0.0/0”的模式。 不幸的是,JSON Schema没有一个contains
关键字(还),所以我们必须做一些布尔逻辑体操来表达这种约束。
我们不能直接约束数组包含“0.0.0.0/0”,但我们可以创建一个禁止“0.0.0.0/0”在数组中的模式。 如果此类模式在数组中不存在“0.0.0.0 \\ 0”时有效,则任何未验证的JSON必须至少包含一个“0.0.0.0/0”实例。
这描述了禁止用于实现contains
约束的“0.0.0.0/0”的数组。
{
"type": "object",
"required": ["ipPermissions"],
"properties": {
"ipPermissions": {
"type": "array",
"items": { "$ref": "#/definitions/ipPermission" }
}
},
"definitions": {
"ipPermission": {
"type": "object",
"properties": {
"toPort": { ... },
"fromPort": { ... },
"ipRanges": { ... },
"ipProtocol": { ... }
}
"not": { "$ref": "#/definitions/port-22-and-0.0.0.0-0"}
},
"port-22-and-0.0.0.0-0": {
"type": "object",
"properties": {
"toPort": { "enum": [22] },
"ipRanges": { "$ref": "#/definitions/array-contains-0.0.0.0-0" }
},
"required": ["toPort", "ipRanges"]
},
"array-contains-0.0.0.0-0": {
"not": { "$ref": "#/definitions/array-without-0.0.0.0-0" }
},
"array-without-0.0.0.0-0": {
"type": "array",
"items": {
"not": { "enum": ["0.0.0.0/0"] }
}
}
}
}
您需要在架构中添加“必需”节点。 但是,在这种情况下,它还需要指定N个允许节点中的一个:
{
"$schema":"http://json-schema.org/draft-04/schema#",
"required":[
"ipPermissions"
],
"properties":{
"ipPermissions":{
"type":"array",
"items":{
"type":"object",
"properties":{
"oneOf":{
"ipRanges":{
"type":"array",
"items":{
"type":"string",
"value":"0.0.0.0/0"
}
},
"toPort":{
"type":"integer",
"minimum":23
}
}
},
"oneOf":[
{
"required":[
"ipRanges"
]
},
{
"required":[
"toPort"
]
}
]
}
}
}
}
这将使用ipRanges节点或toPort节点验证实例,但不能同时验证两者,例如:
{
"ipPermissions":[
{
"toPort":-1,
"fromPort":-1
},
{
"fromPort":53,
"ipRanges":[
"0.0.0.0/0"
],
"ipProtocol":"tcp"
}
]
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.