Link Search Menu Expand Document Documentation Menu

SAML

安全插件通过 SAML 单点登录支持用户身份验证。安全插件实现了 SAML 2.0 协议的 Web 浏览器 SSO 配置文件。

此配置文件旨在用于 Web 浏览器。它不是一种通用的用户对安全插件进行身份验证的方式,因此其主要用例是支持 OpenSearch Dashboards 单点登录。

Docker 示例

我们提供了一个功能齐全的示例,可以帮助您了解如何在 OpenSearch Dashboards 中使用 SAML。

  1. 访问 demos 仓库的 saml-demo 分支,并将其下载到您选择的文件夹。如果您不熟悉如何使用 GitHub,请参阅 OpenSearch 入门指南以获取说明。

  2. 导航到 demo 文件夹
    $ cd <path-to-demos-folder>/demo
    
  3. 根据需要审阅以下文件:

    • .env:
      • 定义要使用的 OpenSearch 和 OpenSearch Dashboards 版本。默认为最新版本 (3.1)。
      • 定义版本 2.12 及更高版本所需的 OPENSEARCH_INITIAL_ADMIN_PASSWORD 变量。
    • ./custom-config/opensearch_dashboards.yml:包含默认 opensearch_dashboards.yml 文件的 SAML 设置。
    • ./custom-config/config.yml:配置 SAML 以进行身份验证。
    • docker-compose.yml:定义一个 OpenSearch 服务器节点、一个 OpenSearch Dashboards 服务器节点和一个 SAML 服务器节点。
    • ./saml/config/authsources.php:包含此 SAML 域可验证的用户列表。
  4. 从命令行运行
    $ docker compose up.
    
  5. https://:5601 访问 OpenSearch Dashboards。

  6. 选择 使用单点登录登录。这会将您重定向到 SAML 登录页面。

  7. 使用 ./saml/config/authsources.php 中定义的用户(例如,user1,密码 user1pass)登录到 OpenSearch Dashboards。

  8. 登录后,请注意屏幕右上角显示的用户 ID 与 SAML 服务器的 ./saml/config/authsources.php 中为该用户定义的 NameID 属性(即 user1saml-test)相同。

  9. 如果您想检查 SAML 服务器,请运行 docker ps 查找其容器 ID,然后运行 docker exec -it <容器 ID> /bin/bash

    特别是,您可能会发现查看 /var/www/simplesamlphp/config//var/www/simplesamlphp/metadata/ 目录的内容很有帮助。

激活 SAML

要使用 SAML 进行身份验证,您需要在 config/opensearch-security/config.ymlauthc 部分配置相应的身份验证域。由于 SAML 完全在 HTTP 层上工作,因此您不需要任何 authentication_backend,可以将其设置为 noop。将本章中所有 SAML 特定配置选项放在 SAML HTTP 验证器的 config 部分中。

_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    authc:
      saml_auth_domain:
        http_enabled: true
        transport_enabled: false
        order: 1
        http_authenticator:
          type: saml
          challenge: true
          config:
            idp:
              metadata_file: okta.xml
              ...
        authentication_backend:
          type: noop

config.yml 中配置 SAML 后,您还必须在 OpenSearch Dashboards 中激活它

运行多个身份验证域

我们建议添加至少一个其他身份验证域,例如 LDAP 或内部用户数据库,以支持无需 SAML 的 OpenSearch API 访问。对于 OpenSearch Dashboards 和内部 OpenSearch Dashboards 服务器用户,您还必须添加另一个支持基本身份验证的身份验证域。此身份验证域应放置在链中的首位,并且 challenge 标志必须设置为 false

_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    authc:
      basic_internal_auth_domain:
        http_enabled: true
        transport_enabled: true
        order: 0
        http_authenticator:
          type: basic
          challenge: false
        authentication_backend:
          type: internal
      saml_auth_domain:
        http_enabled: true
        transport_enabled: false
        order: 1
        http_authenticator:
          type: saml
          challenge: true
          config:
            ...
        authentication_backend:
          type: noop

身份提供商元数据

SAML 身份提供商 (IdP) 提供一个 SAML 2.0 元数据文件,描述 IdP 的功能和配置。安全插件可以从 URL 或文件读取 IdP 元数据。您的选择取决于您的 IdP 和您的偏好。SAML 2.0 元数据文件是必需的。

名称 描述
idp.metadata_file 您的 IdP 的 SAML 2.0 元数据文件的路径。将元数据文件放在 OpenSearch 的 config 目录中。路径必须相对于 config 目录指定。如果未设置 idp.metadata_url,则此项为必需项。
idp.metadata_url 您的 IdP 的 SAML 2.0 元数据 URL。如果未设置 idp.metadata_file,则此项为必需项。

IdP 和服务提供商实体 ID

实体 ID 是 SAML 实体(无论是 IdP 还是服务提供商 (SP))的全局唯一名称。IdP 实体 ID 通常由您的 IdP 提供。SP 实体 ID 是您 IdP 中配置的应用程序或客户端的名称。我们建议为 OpenSearch Dashboards 添加新应用程序,并使用您的 OpenSearch Dashboards 安装的 URL 作为 SP 实体 ID。

名称 描述
idp.entity_id 您的 IdP 的实体 ID。必需。
sp.entity_id 服务提供商的实体 ID。必需。

JWT 验证的时间差异补偿

有时您可能会发现身份验证服务器和 OpenSearch 节点之间的时间不完全同步。在这种情况下,即使是几秒钟的差异,发行或接收 JSON Web Token (JWT) 的系统也可能会尝试验证 nbf(不早于)和 exp(过期)声明,并因时间差异而无法验证用户身份。

默认情况下,OpenSearch Security 允许 30 秒的窗口来补偿服务器时钟时间之间可能存在的偏差。要为此功能设置自定义值并覆盖默认值,您可以将 jwt_clock_skew_tolerance_seconds 设置添加到 config.yml 中。

http_authenticator:
  type: saml
  challenge: true
  config:
    idp:
      metadata_file: okta.xml
    jwt_clock_skew_tolerance_seconds: 20

OpenSearch Dashboards 设置

Web 浏览器 SSO 配置文件通过 HTTP GET 或 POST 交换信息。例如,登录 IdP 后,它会向 OpenSearch Dashboards 发回包含 SAML 响应的 HTTP POST。您必须配置 OpenSearch Dashboards 安装的基本 URL,HTTP 请求将发送到该 URL。

名称 描述
kibana_url OpenSearch Dashboards 基本 URL。必需。

用户名和角色属性

主体(例如,用户名)通常存储在 SAML 响应的 NameID 元素中。

<saml2:Subject>
  <saml2:NameID>admin</saml2:NameID>
  ...
</saml2:Subject>

如果您的 IdP 符合 SAML 2.0 规范,则无需特殊设置。如果您的 IdP 使用不同的元素名称,您也可以明确指定其名称。

角色属性是可选的。然而,大多数 IdP 也可以配置为在 SAML 断言中添加角色。如果存在,您可以在角色映射中使用这些角色。

<saml2:Attribute Name='Role'>
  <saml2:AttributeValue >Everyone</saml2:AttributeValue>
  <saml2:AttributeValue >Admins</saml2:AttributeValue>
</saml2:Attribute>

如果您想从 SAML 响应中提取角色,则需要指定包含角色的元素名称。

名称 描述
subject_key SAML 响应中存储主题的属性。可选。如果未配置,则使用 NameID 属性。
roles_key SAML 响应中存储角色的属性。可选。如果未配置,则不使用任何角色。

请求签名

从安全插件到 IdP 的请求可以选择性地签名。使用以下设置配置请求签名。

名称 描述
sp.signature_private_key 用于签署请求或解码加密断言的私钥。可选。当设置了 private_key_filepath 时不能使用。
sp.signature_private_key_password 私钥的密码(如果有)。
sp.signature_private_key_filepath 私钥的路径。文件必须放置在 OpenSearch config 目录下,并且路径必须相对于该目录指定。
sp.signature_algorithm 用于签署请求的算法。可能的值请参见下表。

私钥必须是 PKCS#8 格式。如果您想使用加密密钥,则必须使用 PKCS#12 兼容算法 (3DES) 进行加密。

安全插件支持以下签名算法。

算法
DSA_SHA1 http://www.w3.org/2000/09/xmldsig#dsa-sha1;
RSA_SHA1 http://www.w3.org/2000/09/xmldsig#rsa-sha1;
RSA_SHA256 http://www.w3.org/2001/04/xmldsig-more#rsa-sha256;
RSA_SHA384 http://www.w3.org/2001/04/xmldsig-more#rsa-sha384;
RSA_SHA512 http://www.w3.org/2001/04/xmldsig-more#rsa-sha512;

退出

通常,IdP 会在其 SAML 2.0 元数据中提供有关其单独注销 URL 的信息。如果是这种情况,安全插件会使用它们在 OpenSearch Dashboards 中渲染正确的注销链接。如果您的 IdP 不支持明确注销,则当用户再次访问 OpenSearch Dashboards 时,您可以强制重新登录。

名称 描述
sp.forceAuthn 即使用户与 IdP 存在活动会话,也强制重新登录。

目前,安全插件仅支持 HTTP-Redirect 注销绑定。请确保这在您的 IdP 中配置正确。

交换密钥设置

SAML 与其他协议不同,它不是为了在每个请求中交换用户凭据而设计的。安全插件将 SAML 响应交换为存储验证用户属性的轻量级 JWT。此令牌由您选择的交换密钥签名。请注意,当您更改此密钥时,所有使用它签名的令牌将立即失效。

名称 描述
exchange_key 用于签署令牌的密钥。算法是 HMACSHA512,因此我们建议使用 64 个字符,例如 9a2h8ajasdfhsdiydfn7dtd6d5ashsd89a2h8ajasdHhsdiyLfn7dtd6d5ashsdI。确保为 exchange_key 输入一个值,否则将返回错误。

TLS 设置

如果您从 URL 加载 IdP 元数据,我们建议您使用 SSL/TLS。如果您使用像 Okta 或 Auth0 这样的外部 IdP,它们使用受信任的证书,您通常不需要配置任何东西。如果您自己托管 IdP 并使用自己的根 CA,您可以按如下方式自定义 TLS 设置。这些设置仅用于通过 HTTPS 加载 SAML 元数据。

名称 描述
idp.enable_ssl 是否启用自定义 TLS 配置。默认为 false(使用 JDK 设置)。
idp.verify_hostnames 是否验证服务器 TLS 证书的主机名。

示例

authc:
  saml_auth_domain:
    http_enabled: true
    transport_enabled: false
    order: 1
    http_authenticator:
      type: saml
      challenge: true
      config:
        idp:
          enable_ssl: true
          verify_hostnames: true
          ...
    authentication_backend:
      type: noop

证书验证

通过设置以下配置选项**之一**来配置用于验证 IdP TLS 证书的根 CA:

config:
  idp:
    pemtrustedcas_filepath: path/to/trusted_cas.pem
config:
  idp:
    pemtrustedcas_content: |-
      -----BEGIN CERTIFICATE-----
      MIID/jCCAuagAwIBAgIBATANBgkqhkiG9w0BAQUFADCBjzETMBEGCgmSJomT8ixk
      ARkWA2NvbTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxGTAXBgNVBAoMEEV4YW1w
      bGUgQ29tIEluYy4xITAfBgNVBAsMGEV4YW1wbGUgQ29tIEluYy4gUm9vdCBDQTEh
      ...
      -----END CERTIFICATE-----
名称 描述
idp.pemtrustedcas_filepath 包含 IdP 根 CA 的 PEM 文件的路径。文件必须放置在 OpenSearch config 目录下,并且路径必须相对于该目录指定。
idp.pemtrustedcas_content IdP 服务器的根 CA 内容。当设置了 pemtrustedcas_filepath 时不能使用。

客户端身份验证

安全插件在获取 IdP 元数据时可以使用 TLS 客户端身份验证。如果启用,安全插件会为每个元数据请求向 IdP 发送一个 TLS 客户端证书。使用以下密钥配置客户端身份验证。

名称 描述
idp.enable_ssl_client_auth 是否向 IdP 服务器发送客户端证书。默认为 false
idp.pemcert_filepath 包含客户端证书的 PEM 文件的路径。文件必须放置在 OpenSearch config 目录下,并且路径必须相对于 config 目录指定。
idp.pemcert_content 客户端证书的内容。当设置了 pemcert_filepath 时不能使用。
idp.pemkey_filepath 客户端证书私钥的路径。文件必须放置在 OpenSearch config 目录下,并且路径必须相对于 config 目录指定。
idp.pemkey_content 证书私钥的内容。当设置了 pemkey_filepath 时不能使用。
idp.pemkey_password 私钥的密码(如果有)。

启用的密码套件和协议

您可以限制 IdP 连接允许的密码套件和 TLS 协议。例如,您只能启用强密码套件并将 TLS 版本限制为最新版本。

名称 描述
idp.enabled_ssl_ciphers 启用的 TLS 密码套件数组。仅支持 Java 格式。
idp.enabled_ssl_protocols 启用的 TLS 协议数组。仅支持 Java 格式。

最小配置示例

以下示例显示了最小配置:

_meta:
  type: "config"
  config_version: 2

config:
  dynamic:
    authc:
      saml_auth_domain:
        http_enabled: true
        transport_enabled: false
        order: 1
        http_authenticator:
          type: saml
          challenge: true
          config:
            idp:
              metadata_file: metadata.xml
              entity_id: http://idp.example.com/
            sp:
              entity_id: https://opensearch-dashboards.example.com
            kibana_url: https://opensearch-dashboards.example.com:5601/
            roles_key: Role
            exchange_key: 'peuvgOLrjzuhXf ...'
        authentication_backend:
          type: noop

OpenSearch Dashboards 配置

由于大多数 SAML 特定配置在安全插件中完成,因此只需通过添加以下内容在 opensearch_dashboards.yml 中激活 SAML:

opensearch_security.auth.type: "saml"

此外,您必须将用于验证 SAML 断言的 OpenSearch Dashboards 端点添加到您的允许列表中。

server.xsrf.allowlist: ["/_opendistro/_security/saml/acs"]

如果您使用注销 POST 绑定,您还需要将注销端点添加到您的允许列表中。

server.xsrf.allowlist: ["/_opendistro/_security/saml/acs", "/_opendistro/_security/saml/logout"]

要在 Dashboards 登录窗口中包含 SAML 和其他身份验证类型,请参阅配置登录选项

会话管理和附加 Cookie

为了改进会话管理,尤其是对于分配了多个角色的用户,Dashboards 提供了一个选项,可以将 cookie 有效负载拆分为多个 cookie,并在接收时重新组合这些有效负载。这有助于防止较大的 SAML 断言超出每个 cookie 的大小限制。以下示例中的两个设置允许您为额外的 cookie 设置前缀名称并指定它们的数量。它们被添加到 opensearch_dashboards.yml 文件中。默认的额外 cookie 数量是三个

opensearch_security.saml.extra_storage.cookie_prefix: security_authentication_saml
opensearch_security.saml.extra_storage.additional_cookies: 3

请注意,减少额外 cookie 的数量可能会导致在更改之前正在使用的一些 cookie 停止工作。我们建议确定一个固定的额外 cookie 数量,之后不再更改配置。

如果 IdP 的 ID 令牌特别大,OpenSearch 可能会抛出服务器日志认证错误,指示 HTTP 头部过大。在这种情况下,您可以增加 opensearch.yml 文件中 http.max_header_size 设置的值。

IdP 发起的 SSO

要使用 IdP 发起的 SSO,请将您的 IdP 的断言消费者服务(Assertion Consumer Service)端点设置为此

/_opendistro/_security/saml/acs/idpinitiated

然后将此端点添加到 opensearch_dashboards.yml 文件中的 server.xsrf.allowlist

server.xsrf.allowlist: ["/_opendistro/_security/saml/acs/idpinitiated", "/_opendistro/_security/saml/acs", "/_opendistro/_security/saml/logout"]