创建或更新角色映射 API

编辑

创建或更新角色映射 API

编辑

创建和更新角色映射。

请求

编辑

POST /_security/role_mapping/<name>

PUT /_security/role_mapping/<name>

先决条件

编辑
  • 要使用此 API,您必须至少具有 manage_security 集群权限。

描述

编辑

角色映射定义了哪些角色被分配给每个用户。每个映射都有规则来标识用户,以及授予这些用户的角色列表。

通常,角色映射 API 是管理角色映射的首选方法,而不是使用 角色映射文件。创建或更新角色映射 API 不能更新在角色映射文件中定义的角色映射。

此 API 不会创建角色。相反,它将用户映射到现有角色。可以使用 创建或更新角色 API角色文件来创建角色。

有关更多信息,请参阅 将用户和组映射到角色

角色模板

编辑

角色映射最常见的用途是从用户的已知值创建到固定角色名称的映射。例如,LDAP 组 cn=admin,dc=example,dc=com 中的所有用户都应在 Elasticsearch 中被赋予 superuser 角色。roles 字段用于此目的。

对于更复杂的需求,可以使用 Mustache 模板来动态确定应授予用户的角色名称。role_templates 字段用于此目的。

要成功使用角色模板,必须启用相关的脚本功能。否则,所有尝试使用角色模板创建角色映射的操作都会失败。请参阅 允许的脚本类型设置

角色映射 rules 中可用的所有 用户字段 也可在角色模板中使用。因此,可以将用户分配给反映其 username、其 groups 或其身份验证的 realm 名称的角色。

默认情况下,模板的计算结果为单个字符串,该字符串是应分配给用户的角色名称。如果模板的 format 设置为 "json",则模板应生成 JSON 字符串或角色名称的 JSON 字符串数组。

路径参数

编辑
name
(字符串) 标识角色映射的唯一名称。该名称仅用作标识符,以方便通过 API 进行交互;它不会以任何方式影响映射的行为。

请求正文

编辑

以下参数可以在 PUT 或 POST 请求的正文中指定,并且与添加角色映射有关

enabled
(必需,布尔值) 在执行角色映射时,会忽略将 enabled 设置为 false 的映射。
metadata
(对象) 帮助定义哪些角色被分配给每个用户的其他元数据。在 metadata 对象中,以 _ 开头的键保留供系统使用。
roles
(字符串列表) 授予与角色映射规则匹配的用户的角色名称列表。必须指定 rolesrole_templates 中的一个
role_templates
(对象列表) 将进行计算以确定应授予与角色映射规则匹配的用户的角色名称的 Mustache 模板列表。这些对象的格式在下面定义。必须指定 rolesrole_templates 中的一个
rules
(必需,对象) 确定哪些用户应与映射匹配的规则。规则是使用 JSON DSL 表示的逻辑条件。请参阅 角色映射资源

示例

编辑

以下示例将 "user" 角色分配给所有用户

resp = client.security.put_role_mapping(
    name="mapping1",
    roles=[
        "user"
    ],
    enabled=True,
    rules={
        "field": {
            "username": "*"
        }
    },
    metadata={
        "version": 1
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping1",
  roles: ["user"],
  enabled: true,
  rules: {
    field: {
      username: "*",
    },
  },
  metadata: {
    version: 1,
  },
});
console.log(response);
POST /_security/role_mapping/mapping1
{
  "roles": [ "user"],
  "enabled": true, 
  "rules": {
    "field" : { "username" : "*" }
  },
  "metadata" : { 
    "version" : 1
  }
}

在执行角色映射时,会忽略将 enabled 设置为 false 的映射。

元数据是可选的。

成功的调用会返回一个 JSON 结构,显示映射是否已创建或更新。

{
  "role_mapping" : {
    "created" : true 
  }
}

当更新现有映射时,created 设置为 false。

以下示例将 "user" 和 "admin" 角色分配给特定用户

resp = client.security.put_role_mapping(
    name="mapping2",
    roles=[
        "user",
        "admin"
    ],
    enabled=True,
    rules={
        "field": {
            "username": [
                "esadmin01",
                "esadmin02"
            ]
        }
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping2",
  roles: ["user", "admin"],
  enabled: true,
  rules: {
    field: {
      username: ["esadmin01", "esadmin02"],
    },
  },
});
console.log(response);
POST /_security/role_mapping/mapping2
{
  "roles": [ "user", "admin" ],
  "enabled": true,
  "rules": {
     "field" : { "username" : [ "esadmin01", "esadmin02" ] }
  }
}

以下示例匹配针对特定 realm 进行身份验证的用户

resp = client.security.put_role_mapping(
    name="mapping3",
    roles=[
        "ldap-user"
    ],
    enabled=True,
    rules={
        "field": {
            "realm.name": "ldap1"
        }
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping3",
  roles: ["ldap-user"],
  enabled: true,
  rules: {
    field: {
      "realm.name": "ldap1",
    },
  },
});
console.log(response);
POST /_security/role_mapping/mapping3
{
  "roles": [ "ldap-user" ],
  "enabled": true,
  "rules": {
    "field" : { "realm.name" : "ldap1" }
  }
}

以下示例匹配用户名是 esadmin 或用户在 cn=admin,dc=example,dc=com 组中的任何用户

resp = client.security.put_role_mapping(
    name="mapping4",
    roles=[
        "superuser"
    ],
    enabled=True,
    rules={
        "any": [
            {
                "field": {
                    "username": "esadmin"
                }
            },
            {
                "field": {
                    "groups": "cn=admins,dc=example,dc=com"
                }
            }
        ]
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping4",
  roles: ["superuser"],
  enabled: true,
  rules: {
    any: [
      {
        field: {
          username: "esadmin",
        },
      },
      {
        field: {
          groups: "cn=admins,dc=example,dc=com",
        },
      },
    ],
  },
});
console.log(response);
POST /_security/role_mapping/mapping4
{
  "roles": [ "superuser" ],
  "enabled": true,
  "rules": {
    "any": [
      {
        "field": {
          "username": "esadmin"
        }
      },
      {
        "field": {
          "groups": "cn=admins,dc=example,dc=com"
        }
      }
    ]
  }
}

当您的身份管理系统(例如 Active Directory 或 SAML 身份提供程序)中的组名称与 Elasticsearch 中角色的名称没有一对一的对应关系时,以上示例很有用。角色映射是您将组名称角色名称链接起来的方式。

如果有多个组,则可以使用组字段的数组语法。这会匹配任何组(而不是所有组)

resp = client.security.put_role_mapping(
    name="mapping4",
    roles=[
        "superuser"
    ],
    enabled=True,
    rules={
        "any": [
            {
                "field": {
                    "username": "esadmin"
                }
            },
            {
                "field": {
                    "groups": [
                        "cn=admins,dc=example,dc=com",
                        "cn=other,dc=example,dc=com"
                    ]
                }
            }
        ]
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping4",
  roles: ["superuser"],
  enabled: true,
  rules: {
    any: [
      {
        field: {
          username: "esadmin",
        },
      },
      {
        field: {
          groups: ["cn=admins,dc=example,dc=com", "cn=other,dc=example,dc=com"],
        },
      },
    ],
  },
});
console.log(response);
POST /_security/role_mapping/mapping4
{
  "roles": [ "superuser" ],
  "enabled": true,
  "rules": {
    "any": [
      {
        "field": {
          "username": "esadmin"
        }
      },
      {
        "field": {
          "groups": [
               "cn=admins,dc=example,dc=com",
               "cn=other,dc=example,dc=com"
            ]
        }
      }
    ]
  }
}

但是,在极少数情况下,您的组名称可能与您的 Elasticsearch 角色名称完全匹配。当您的 SAML 身份提供程序包含其自己的“组映射”功能并且可以配置为在用户的 SAML 属性中发布 Elasticsearch 角色名称时,可能会出现这种情况。

在这些情况下,可以使用将组名称视为角色名称的模板。

注意:仅当您打算为提供的所有组定义角色时,才应这样做。将用户映射到大量不必要或未定义的角色效率低下,并且会对系统性能产生负面影响。如果您只需要映射组的子集,则应使用显式映射来完成此操作。

resp = client.security.put_role_mapping(
    name="mapping5",
    role_templates=[
        {
            "template": {
                "source": "{{#tojson}}groups{{/tojson}}"
            },
            "format": "json"
        }
    ],
    rules={
        "field": {
            "realm.name": "saml1"
        }
    },
    enabled=True,
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping5",
  role_templates: [
    {
      template: {
        source: "{{#tojson}}groups{{/tojson}}",
      },
      format: "json",
    },
  ],
  rules: {
    field: {
      "realm.name": "saml1",
    },
  },
  enabled: true,
});
console.log(response);
POST /_security/role_mapping/mapping5
{
  "role_templates": [
    {
      "template": { "source": "{{#tojson}}groups{{/tojson}}" }, 
      "format" : "json" 
    }
  ],
  "rules": {
    "field" : { "realm.name" : "saml1" }
  },
  "enabled": true
}

tojson Mustache 函数用于将组名称列表转换为有效的 JSON 数组。

由于模板生成 JSON 数组,因此格式必须设置为 json

以下示例匹配特定 LDAP 子树中的用户

resp = client.security.put_role_mapping(
    name="mapping6",
    roles=[
        "example-user"
    ],
    enabled=True,
    rules={
        "field": {
            "dn": "*,ou=subtree,dc=example,dc=com"
        }
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping6",
  roles: ["example-user"],
  enabled: true,
  rules: {
    field: {
      dn: "*,ou=subtree,dc=example,dc=com",
    },
  },
});
console.log(response);
POST /_security/role_mapping/mapping6
{
  "roles": [ "example-user" ],
  "enabled": true,
  "rules": {
    "field" : { "dn" : "*,ou=subtree,dc=example,dc=com" }
  }
}

以下示例匹配特定 realm 中特定 LDAP 子树中的用户

resp = client.security.put_role_mapping(
    name="mapping7",
    roles=[
        "ldap-example-user"
    ],
    enabled=True,
    rules={
        "all": [
            {
                "field": {
                    "dn": "*,ou=subtree,dc=example,dc=com"
                }
            },
            {
                "field": {
                    "realm.name": "ldap1"
                }
            }
        ]
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping7",
  roles: ["ldap-example-user"],
  enabled: true,
  rules: {
    all: [
      {
        field: {
          dn: "*,ou=subtree,dc=example,dc=com",
        },
      },
      {
        field: {
          "realm.name": "ldap1",
        },
      },
    ],
  },
});
console.log(response);
POST /_security/role_mapping/mapping7
{
  "roles": [ "ldap-example-user" ],
  "enabled": true,
  "rules": {
    "all": [
      { "field" : { "dn" : "*,ou=subtree,dc=example,dc=com" } },
      { "field" : { "realm.name" : "ldap1" } }
    ]
  }
}

规则可能更复杂,并且包括通配符匹配。例如,以下映射匹配满足以下所有条件的用户

  • 专有名称与模式 *,ou=admin,dc=example,dc=com 匹配,或者用户名是 es-admin,或者用户名是 es-system
  • 用户在 cn=people,dc=example,dc=com 组中
  • 用户没有 terminated_date
resp = client.security.put_role_mapping(
    name="mapping8",
    roles=[
        "superuser"
    ],
    enabled=True,
    rules={
        "all": [
            {
                "any": [
                    {
                        "field": {
                            "dn": "*,ou=admin,dc=example,dc=com"
                        }
                    },
                    {
                        "field": {
                            "username": [
                                "es-admin",
                                "es-system"
                            ]
                        }
                    }
                ]
            },
            {
                "field": {
                    "groups": "cn=people,dc=example,dc=com"
                }
            },
            {
                "except": {
                    "field": {
                        "metadata.terminated_date": None
                    }
                }
            }
        ]
    },
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping8",
  roles: ["superuser"],
  enabled: true,
  rules: {
    all: [
      {
        any: [
          {
            field: {
              dn: "*,ou=admin,dc=example,dc=com",
            },
          },
          {
            field: {
              username: ["es-admin", "es-system"],
            },
          },
        ],
      },
      {
        field: {
          groups: "cn=people,dc=example,dc=com",
        },
      },
      {
        except: {
          field: {
            "metadata.terminated_date": null,
          },
        },
      },
    ],
  },
});
console.log(response);
POST /_security/role_mapping/mapping8
{
  "roles": [ "superuser" ],
  "enabled": true,
  "rules": {
    "all": [
      {
        "any": [
          {
            "field": {
              "dn": "*,ou=admin,dc=example,dc=com"
            }
          },
          {
            "field": {
              "username": [ "es-admin", "es-system" ]
            }
          }
        ]
      },
      {
        "field": {
          "groups": "cn=people,dc=example,dc=com"
        }
      },
      {
        "except": {
          "field": {
            "metadata.terminated_date": null
          }
        }
      }
    ]
  }
}

可以使用模板化的角色将每个用户自动映射到他们自己的自定义角色。可以通过 角色 API 或使用 自定义角色提供程序来定义角色本身。

在此示例中,使用 "cloud-saml" realm 进行身份验证的每个用户都将自动映射到两个角色 - "saml_user" 角色以及以 _user_ 为前缀的用户名角色。例如,用户 nwong 将被分配 saml_user_user_nwong 角色。

resp = client.security.put_role_mapping(
    name="mapping9",
    rules={
        "field": {
            "realm.name": "cloud-saml"
        }
    },
    role_templates=[
        {
            "template": {
                "source": "saml_user"
            }
        },
        {
            "template": {
                "source": "_user_{{username}}"
            }
        }
    ],
    enabled=True,
)
print(resp)
const response = await client.security.putRoleMapping({
  name: "mapping9",
  rules: {
    field: {
      "realm.name": "cloud-saml",
    },
  },
  role_templates: [
    {
      template: {
        source: "saml_user",
      },
    },
    {
      template: {
        source: "_user_{{username}}",
      },
    },
  ],
  enabled: true,
});
console.log(response);
POST /_security/role_mapping/mapping9
{
  "rules": { "field": { "realm.name": "cloud-saml" } },
  "role_templates": [
    { "template": { "source" : "saml_user" } }, 
    { "template": { "source" : "_user_{{username}}" } }
  ],
  "enabled": true
}

由于在同一角色映射中不能同时指定 rolesrole_templates,因此我们可以使用没有替换的模板来应用“固定名称”角色。