6.5. 使用基于 OAuth 2.0 令牌的授权


如果您将 OAuth 2.0 与 Red Hat Single Sign-On 用于基于令牌的身份验证搭配使用,您还可以使用 Red Hat Single Sign-On 配置授权规则来限制客户端对 Kafka 代理的访问。身份验证建立了用户的身份。授权决定该用户的访问权限级别。

AMQ Streams 支持通过 Red Hat Single Sign-On Authorization Services 使用基于 OAuth 2.0 令牌的授权,它允许您集中管理安全策略和权限。

Red Hat Single Sign-On 中定义的安全策略和权限用于授予对 Kafka 代理上资源的访问权限。用户和客户端与允许对 Kafka 代理执行特定操作的策略进行匹配。

Kafka 允许所有用户默认对代理进行完全访问,同时还提供 AclAuthorizer 插件来配置基于 Access Control Lists (ACL)的授权。

zookeeper 存储了基于 用户名 授予或拒绝对资源的访问的 ACL 规则。但是,红帽单点登录基于 OAuth 2.0 令牌的授权在您希望实现对 Kafka 代理的访问控制方面具有更大的灵活性。另外,您可以将 Kafka 代理配置为使用 OAuth 2.0 授权和 ACL。

6.5.1. OAuth 2.0 授权机制

AMQ Streams 中的 OAuth 2.0 授权使用红帽单点登录服务器授权服务 REST 端点,通过在特定用户上应用定义的安全策略来扩展基于令牌的身份验证,并为该用户提供授予不同资源的权限列表。策略使用角色和组将权限与用户匹配。OAuth 2.0 授权根据从 Red Hat Single Sign-On Authorization Services 用户获得的授予者列表在本地强制实施权限。

6.5.1.1. Kafka 代理自定义授权器

AMQ Streams 提供了 Red Hat Single Sign-On authorizer (KeycloakRBACAuthorizer)。要使用由 Red Hat Single Sign-On 提供的授权服务的 Red Hat Single Sign-On REST 端点,您可以在 Kafka 代理上配置自定义授权器。

授权程序根据需要从授权服务器获取授予权限的列表,并在 Kafka Broker 上本地强制实施授权,为每个客户端请求做出快速授权决策。

6.5.2. 配置 OAuth 2.0 授权支持

这个步骤描述了如何使用 Red Hat Single Sign-On Authorization Services 将 Kafka 代理配置为使用 OAuth 2.0 授权服务。

开始前

考虑某些用户所需的访问权限或希望限制某些用户。您可以结合使用 Red Hat Single Sign-On 角色客户端 和用户,在 Red Hat Single Sign-On 中配置访问权限。

通常,组用于根据机构部门或地理位置匹配用户。和角色用于根据用户的功能匹配。

使用红帽单点登录,您可以在 LDAP 中存储用户和组,而客户端和角色不能以这种方式存储。存储和访问用户数据可能是您选择配置授权策略的原因。

注意

无论 Kafka 代理上实施的授权是什么,超级用户 始终对 Kafka 代理没有限制的访问。

先决条件

  • AMQ Streams 必须通过 Red Hat Single Sign-On 配置为使用 OAuth 2.0 进行基于令牌的身份验证。设置授权时,您使用相同的红帽单点登录服务器端点。
  • OAuth 2.0 身份验证必须配置有 maxSecondsWithoutReauthentication 选项才能启用 re-authentication。

流程

  1. 访问 Red Hat Single Sign-On Admin Console,或使用 Red Hat Single Sign-On Admin CLI 为设置 OAuth 2.0 身份验证时创建的 Kafka 代理客户端启用授权服务。
  2. 使用授权服务定义客户端的资源、授权范围、策略和权限。
  3. 通过分配角色和组,将权限绑定到用户和客户端。
  4. 通过在编辑器中更新 Kafka 代理配置Kafka.spec.kafka,将 Kafka 代理配置为使用 Red Hat Single Sign-On 授权。

    oc edit kafka my-cluster
    Copy to Clipboard Toggle word wrap
  5. 将 Kafka 代理 kafka 配置配置为使用 keycloak 授权,并可以访问授权服务器和授权服务。

    例如:

    apiVersion: kafka.strimzi.io/v1beta2
    kind: Kafka
    metadata:
      name: my-cluster
    spec:
      kafka:
        # ...
        authorization:
          type: keycloak 
    1
    
          tokenEndpointUri: <https://<auth-server-address>/auth/realms/external/protocol/openid-connect/token> 
    2
    
          clientId: kafka 
    3
    
          delegateToKafkaAcls: false 
    4
    
          disableTlsHostnameVerification: false 
    5
    
          superUsers: 
    6
    
          - CN=fred
          - sam
          - CN=edward
          tlsTrustedCertificates: 
    7
    
          - secretName: oauth-server-cert
            certificate: ca.crt
          grantsRefreshPeriodSeconds: 60 
    8
    
          grantsRefreshPoolSize: 5 
    9
    
          connectTimeoutSeconds: 60 
    10
    
          readTimeoutSeconds: 60 
    11
    
        #...
    Copy to Clipboard Toggle word wrap
    1
    类型 keycloak 启用 Red Hat Single Sign-On 授权。
    2
    Red Hat Single Sign-On 令牌端点的 URI。对于生产环境,始终使用 https:// urls。当您配置基于令牌的 oauth 身份验证时,您可以将 jwksEndpointUri 指定为本地 JWT 验证的 URI。tokenEndpointUri URI 的主机名必须相同。
    3
    在启用了授权服务的 Red Hat Single Sign-On 中的 OAuth 2.0 客户端定义的客户端 ID。通常,kafka 用作 ID。
    4
    (可选)如果 Red Hat Single Sign-On Authorization Services 策略拒绝了访问,则对 Kafka AclAuthorizer 进行策展授权。默认为 false
    5
    (可选)禁用 TLS 主机名验证。默认为 false
    6
    (可选)指定 超级用户
    7
    (可选)用于 TLS 连接授权服务器的可信证书。
    8
    (可选)两个连续授予刷新运行的时间间隔。这是有效会话的最长时间,用于检测 Red Hat Single Sign-On 上用户的任何权限更改。默认值为 60。
    9
    (可选)用于刷新的线程数量(并行)为活跃会话授予。默认值为 5。
    10
    (可选)连接到 Red Hat Single Sign-On 令牌端点时连接超时(以秒为单位)。默认值为 60。
    11
    (可选)连接到 Red Hat Single Sign-On 令牌端点时读取超时(以秒为单位)。默认值为 60。
  6. 保存并退出编辑器,然后等待滚动更新完成。
  7. 检查日志中的更新,或者查看 pod 状态转换:

    oc logs -f ${POD_NAME} -c kafka
    oc get pod -w
    Copy to Clipboard Toggle word wrap

    滚动更新将代理配置为使用 OAuth 2.0 授权。

  8. 通过以客户端或具有特定角色的用户访问 Kafka 代理来验证配置的权限,确保它们具有必要的访问权限,或者没有应该具有访问权限。

这部分论述了 Red Hat Single Sign-On Authorization Services 和 Kafka 使用的授权模型,并为每个模型定义重要的概念。

要授予访问 Kafka 的权限,您可以通过在 Red Hat Single Sign-Ons 中创建 OAuth 客户端规格,将 Red Hat Single Sign-On 授权服务对象映射到 Kafka 资源。使用 Red Hat Single Sign-On Authorization Services 规则为用户帐户或服务帐户授予 Kafka 权限。

显示常见 Kafka 操作所需的不同用户权限 示例,如创建和列出主题。

Kafka 和 Red Hat Single Sign-On 授权服务使用不同的授权模型。

Kafka 授权模型

Kafka 的授权模型使用 资源类型。当 Kafka 客户端对代理执行操作时,代理使用配置的 KeycloakRBACAuthorizer 检查客户端的权限,具体取决于操作和资源类型。

Kafka 使用五个资源类型来控制访问: 主题ClusterTransactionalIdDelegationToken。每个资源类型都有一组可用权限。

Topic

  • 创建
  • 删除
  • Describe
  • DescribeConfigs
  • 改变
  • AlterConfigs

  • Describe
  • 删除

集群

  • 创建
  • Describe
  • 改变
  • DescribeConfigs
  • AlterConfigs
  • IdempotentWrite
  • ClusterAction

TransactionalId

  • Describe

DelegationToken

  • Describe
Red Hat Single Sign-On 授权服务模型

红帽单点登录授权服务模型有四个定义和授予权限的概念: 资源授权范围策略权限

Resources
资源是一组资源定义,用于匹配允许的操作的资源。资源可能是单独的主题,例如,或者名称以同一前缀开头的所有主题。资源定义与一组可用的授权范围关联,后者代表资源上所有可用操作的集合。通常,实际上只允许这些操作的子集。
授权范围
授权范围是关于特定资源定义的一组所有可用操作。当您定义新资源时,会添加来自所有范围的范围。
策略(policy)

策略是一个授权规则,它使用条件与帐户列表匹配。策略可以匹配:

  • 基于客户端 ID 或角色 的服务帐户
  • 基于用户名、组或角色的 用户帐户
权限
权限向一组用户授予对特定资源定义的授权范围子集。

Kafka 授权模型用作定义控制对 Kafka 访问权限的 Red Hat Single Sign-On 角色和资源的基础。

要为用户帐户或服务帐户授予 Kafka 权限,您必须首先在用于 Kafka 代理的 Red Hat Single Sign-On 中创建 OAuth 客户端规格。然后,在客户端上指定 Red Hat Single Sign-On Authorization Services 规则。通常,代表代理的 OAuth 客户端的客户端 ID 是 kafka。带有 AMQ Streams 提供 的示例配置文件 使用 kafka 作为 OAuth 客户端 ID。

注意

如果有多个 Kafka 集群,您可以将单个 OAuth 客户端(kafka)用于所有这些 Kafka 集群。这为您提供了一个可定义和管理授权规则的统一空间。但是,您还可以使用不同的 OAuth 客户端 ID (如 my-cluster-kafkacluster-dev-kafka),并为每个客户端配置中为每个集群定义授权规则。

kafka 客户端定义必须在 Red Hat Single Sign-On Admin 控制台中启用 Authorization Enabled 选项。

所有权限都存在于 kafka 客户端范围内。如果您使用不同的 OAuth 客户端 ID 配置不同的 Kafka 集群,它们各自需要单独的权限集合,即使它们属于同一个 Red Hat Single Sign-On 域。

当 Kafka 客户端使用 OAUTHBEARER 身份验证时,Red Hat Single Sign-On 授权器(KeycloakRBACAuthorizer)使用当前会话的访问令牌来检索从红帽单点登录服务器授予的列表。为检索授权,授权器会评估红帽单点登录授权服务和权限。

Kafka 权限的授权范围

初始的 Red Hat Single Sign-On 配置通常涉及上传授权范围,以创建可在每个 Kafka 资源类型上执行的所有可能操作的列表。只有在定义任何权限前,才会执行此步骤。您可以手动添加授权范围,而不是上传它们。

无论资源类型是什么,授权范围必须包含所有可能的 Kafka 权限:

  • 创建
  • 删除
  • Describe
  • 改变
  • DescribeConfig
  • AlterConfig
  • ClusterAction
  • IdempotentWrite
注意

如果您确信不需要权限(例如,IdempotentWrite),您可以从授权范围列表中省略它。但是,该权限不适用于 Kafka 资源的目标。

权限检查的资源模式

在执行权限检查时,资源模式用于与目标资源模式匹配。通用模式格式为 RESOURCE-TYPE:PATTERN-NAME

资源类型镜像 Kafka 授权模型。该模式允许两个匹配选项:

  • 完全匹配(当模式不以 *结尾)
  • 前缀匹配(当模式以 *结尾)

资源模式示例

Topic:my-topic
Topic:orders-*
Group:orders-*
Cluster:*
Copy to Clipboard Toggle word wrap

另外,常规模式格式可以通过 kafka-cluster:CLUSTER-NAME 前缀,后跟一个逗号,其中 CLUSTER-NAME 代表 Kafka 自定义资源中的 metadata.name

带有集群前缀的资源的模式示例

kafka-cluster:my-cluster,Topic:*
kafka-cluster:*,Group:b_*
Copy to Clipboard Toggle word wrap

当缺少 kafka-cluster 前缀时,它会假定为 kafka-cluster:*

在定义资源时,您可以将其与与该资源相关的授权范围列表关联。设置针对目标资源类型采取的任何操作。

虽然您可以将任何授权范围添加到任何资源,但只有资源类型支持的范围才会考虑访问控制。

应用访问权限的策略

策略用于针对一个或多个用户帐户或服务帐户的目标权限。目标可指代:

  • 特定用户或服务帐户
  • realm 角色或客户端角色
  • 用户组
  • 与客户端 IP 地址匹配的 JavaScript 规则

策略被授予唯一名称,可重新利用目标多个资源的权限。

授予访问权限的权限

使用精细权限,将策略、资源和授权范围拉取到一起,并授予用户访问权限。

每个权限的名称应该明确定义它为哪个用户授予哪些权限。例如,开发团队 B 可从以 x 开始的主题读取

6.5.3.3. Kafka 操作所需的权限示例

以下示例演示了在 Kafka 上执行常见操作所需的用户权限。

创建主题

要创建主题,特定主题或 Cluster:kafka-cluster 需要 Create 权限。

bin/kafka-topics.sh --create --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

列出主题

如果用户具有指定主题 的描述 权限,则会列出该主题。

bin/kafka-topics.sh --list \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

显示主题详情

要显示主题详情,在主题上需要 DescribeDescribeConfigs 权限。

bin/kafka-topics.sh --describe --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

将消息生成到主题

要将消息生成到主题,主题上需要 DescribeWrite 权限。

如果主题尚未创建,并且启用了主题自动创建,则需要创建主题的权限。

bin/kafka-console-producer.sh  --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --producer.config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

使用来自主题的消息

为了消费主题中的消息,需要有主题的 DescribeRead 权限。在主题中使用通常依赖于将消费者偏移存储在消费者组中,这需要对消费者组需要额外的 DescribeRead 权限。

匹配需要两个 资源。例如:

Topic:my-topic
Group:my-group-*
Copy to Clipboard Toggle word wrap
bin/kafka-console-consumer.sh --topic my-topic --group my-group-1 --from-beginning \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --consumer.config /tmp/config.properties
Copy to Clipboard Toggle word wrap

使用幂等制作者将消息生成到主题

另外,Cluster:kafka-cluster 资源需要额外 IdempotentWrite 权限。

匹配需要两个 资源。例如:

Topic:my-topic
Cluster:kafka-cluster
Copy to Clipboard Toggle word wrap
bin/kafka-console-producer.sh  --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --producer.config=/tmp/config.properties --producer-property enable.idempotence=true --request-required-acks -1
Copy to Clipboard Toggle word wrap

列出消费者组

在列出消费者组时,只有返回用户具有 描述 权限的组。另外,如果用户对 Cluster:kafka-cluster 具有 Describe 权限,则返回所有消费者组。

bin/kafka-consumer-groups.sh --list \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

显示消费者组详情

要显示消费者组的详情,组必须具有 描述 权限以及与组关联的主题。

bin/kafka-consumer-groups.sh --describe --group my-group-1 \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

更改主题配置

要更改主题的配置,在主题上需要 DescribeAlter 权限。

bin/kafka-topics.sh --alter --topic my-topic --partitions 2 \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

显示 Kafka 代理配置

要使用 kafka-configs.sh 获取代理配置,Cluster:kafka-cluster 上需要 DescribeConfigs 权限。

bin/kafka-configs.sh --entity-type brokers --entity-name 0 --describe --all \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

更改 Kafka 代理配置

要更改 Kafka 代理的配置,Cluster:kafka-cluster 上需要 DescribeConfigsAlterConfigs 权限。

bin/kafka-configs --entity-type brokers --entity-name 0 --alter --add-config log.cleaner.threads=2 \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

删除主题

要删除主题,在主题上需要 DescribeDelete 权限。

bin/kafka-topics.sh --delete --topic my-topic \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config=/tmp/config.properties
Copy to Clipboard Toggle word wrap

选择潜在客户分区

要运行主题分区的领导选择,Cluster:kafka-cluster 上需要使用 Alter 权限。

bin/kafka-leader-election.sh --topic my-topic --partition 0 --election-type PREFERRED  /
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --admin.config /tmp/config.properties
Copy to Clipboard Toggle word wrap

重新分配分区

要生成分区重新分配文件,相关主题需要 描述 权限。

bin/kafka-reassign-partitions.sh --topics-to-move-json-file /tmp/topics-to-move.json --broker-list "0,1" --generate \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties > /tmp/partition-reassignment.json
Copy to Clipboard Toggle word wrap

要执行分区重新分配,Cluster:kafka-cluster 上需要 DescribeAlter 权限。另外,有关涉及的主题还需要 Describe 权限。

bin/kafka-reassign-partitions.sh --reassignment-json-file /tmp/partition-reassignment.json --execute \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties
Copy to Clipboard Toggle word wrap

要验证分区重新分配、描述AlterConfigs 权限是 Cluster:kafka-cluster,以及涉及的每个主题所需的权限。

bin/kafka-reassign-partitions.sh --reassignment-json-file /tmp/partition-reassignment.json --verify \
  --bootstrap-server my-cluster-kafka-bootstrap:9092 --command-config /tmp/config.properties
Copy to Clipboard Toggle word wrap

6.5.4. 试用红帽单点登录授权服务

本例解释了如何使用带有 keycloak 授权的红帽单点登录授权服务。使用 Red Hat Single Sign-On Authorization Services 对 Kafka 客户端实施访问限制。红帽单点登录授权服务使用授权范围、策略和权限来定义和应用对资源的访问控制。

Red Hat Single Sign-On Authorization Services REST 端点提供经过身份验证的用户授予资源的权限列表。权限列表从 Red Hat Single Sign-On 服务器获取,作为 Kafka 客户端建立经过身份验证的会话后的第一个操作。该列表在后台刷新,以便检测到对授权的更改。授予在 Kafka 代理上本地缓存并强制每个用户会话提供快速授权决策。

AMQ Streams 提供示例配置文件。这包括以下用于设置 Red Hat Single Sign-On 的示例文件:

kafka-ephemeral-oauth-single-keycloak-authz.yaml
使用 Red Hat Single Sign-On 为基于 OAuth 2.0 令牌授权配置的 Kafka 自定义资源示例。您可以使用自定义资源部署使用 keycloak 授权和基于令牌的 oauth 身份验证的 Kafka 集群。
kafka-authz-realm.json
红帽单点登录域示例配置了示例组、用户、角色和客户端。您可以将域导入到 Red Hat Single Sign-On 实例,以设置访问 Kafka 的精细权限。

如果要尝试使用 Red Hat Single Sign-On 的示例,请使用这些文件执行本节中所述的任务。

身份验证

当您配置基于令牌的 oauth 身份验证时,您可以将 jwksEndpointUri 指定为本地 JWT 验证的 URI。当您配置 keycloak 授权时,您可以将 tokenEndpointUri 指定为 Red Hat Single Sign-On 令牌端点的 URI。两个 URI 的主机名必须相同。

具有组或角色策略的目标权限

在 Red Hat Single Sign-On 中,启用服务帐户的保密客户端可以使用客户端 ID 和 secret 在其自己的名称中对服务器进行身份验证。对于通常以自己的名称而不是作为特定用户的代理(如网站)的微服务来说,这很方便。服务帐户可以像普通用户一样分配角色。但是,他们不能分配有组。因此,如果要使用服务帐户将权限目标到微服务,则无法使用组策略,而是应使用角色策略。相反,如果您只想将某些权限限制到需要用户名和密码的常规用户帐户,则可利用组策略而不是角色策略作为副作用。这个示例中使用了从 ClusterManager 开始的权限。执行集群管理通常使用 CLI 工具进行。在使用生成的访问令牌向 Kafka 代理进行身份验证前,需要用户登录才需要用户登录。在这种情况下,访问令牌代表特定用户,而不是客户端应用程序。

6.5.4.1. 访问 Red Hat Single Sign-On Admin Console

设置 Red Hat Single Sign-On,然后连接到其管理控制台并添加预配置的域。使用示例 kafka-authz-realm.json 文件导入域。您可以在 Admin 控制台中检查为 realm 定义的授权规则。这些规则授予对 Kafka 集群上的资源的访问权限,以使用 Red Hat Single Sign-On 域示例。

先决条件

  • 一个正常运行的 OpenShift 集群。
  • AMQ Streams 示例/security/keycloak-authorization/kafka-authz-realm.json 文件,该文件包含预先配置的域。

流程

  1. 使用 Red Hat Single Sign-On Operator 安装 Red Hat Single Sign-On 服务器,如 Red Hat Single Sign-On 文档中的服务器安装和配置 中所述。
  2. 等待 Red Hat Single Sign-On 实例处于运行状态。
  3. 获取外部主机名,以访问管理控制台。

    NS=sso
    oc get ingress keycloak -n $NS
    Copy to Clipboard Toggle word wrap

    在本例中,我们假定 Red Hat Single Sign-On 服务器正在 sso 命名空间中运行。

  4. 获取 admin 用户的密码。

    oc get -n $NS pod keycloak-0 -o yaml | less
    Copy to Clipboard Toggle word wrap

    密码存储为 secret,因此要获取 Red Hat Single Sign-On 实例的配置 YAML 文件,以标识 secret 的名称(secretKeyRef.name)。

  5. 使用 secret 的名称获取明文密码。

    SECRET_NAME=credential-keycloak
    oc get -n $NS secret $SECRET_NAME -o yaml | grep PASSWORD | awk '{print $2}' | base64 -D
    Copy to Clipboard Toggle word wrap

    在本例中,我们假定 secret 的名称为 credential-keycloak

  6. 使用您获取的用户名 admin 和密码登录 Admin 控制台。

    使用 https://HOSTNAME 来访问 OpenShift 入口。

    现在,您可以使用 Admin 控制台将示例域上传到 Red Hat Single Sign-On。

  7. 单击 Add Realm 以导入示例域。
  8. 添加 example /security/keycloak-authorization/kafka-authz-realm.json 文件,然后点 Create

    现在,在 Admin 控制台中将 kafka-authz 作为当前域。

    默认视图显示 Master 域。

  9. 在 Red Hat Single Sign-On Admin Console 中,进入 Clients > kafka > Authorization > Settings,并检查是否将 Decision Strategy 设置为 Affirmative

    Affirmative 策略意味着必须满足至少一个策略来访问 Kafka 集群。

  10. 在 Red Hat Single Sign-On Admin Console 中,进入 Groups, Users, RolesClients 来查看 realm 配置。

    用于创建用户组并设置用户权限。组是一组分配了名称的用户。它们用于将用户整理到地理、组织或部门单位。组可以链接到 LDAP 身份提供程序。您可以通过自定义 LDAP 服务器 admin 用户界面使用户成为一个组的成员,例如,授予 Kafka 资源的权限。
    用户
    用户 用于创建用户。在本例中,定义了 alicebobaliceClusterManager 组的成员,bobClusterManager-my-cluster 组的成员。用户可以存储在 LDAP 身份提供程序中。
    角色
    Roles 代表用户或客户端具有特定权限。角色是与组类似的概念。它们通常用于 为用户授予 组织角色的用户,并具有必要权限。角色不能存储在 LDAP 身份提供程序中。如果需要 LDAP,您可以使用组,并将 Red Hat Single Sign-On 角色添加到组中,以便当用户分配有组时,它们也会获得对应的角色。
    客户端

    客户端 可以有特定的配置。在本例中,配置了 kafka, kafka-cli, team-a-client, 和 team-b-client 客户端。

    • Kafka 代理使用 kafka 客户端来执行访问令牌验证所需的 OAuth 2.0 通信。此客户端还包含用于对 Kafka 代理执行授权的授权服务资源定义、策略和授权范围。授权配置在 Authorization 选项卡的 kafka 客户端中定义,在从 Settings 标签页上切换 Authorization 时,它就会可见。
    • kafka-cli 客户端是在使用用户名和密码进行身份验证时 Kafka 命令行工具使用的公共客户端,以获取访问令牌或刷新令牌。
    • team-a-clientteam-b-client 客户端是负责访问某些 Kafka 主题的部分服务的机密客户端。
  11. 在 Red Hat Single Sign-On Admin Console 中,进入 Authorization > Permissions 以查看使用为域定义的资源和策略授予权限。

    例如,kafka 客户端具有以下权限:

    Dev Team A can write to topics that start with x_ on any cluster
    Dev Team B can read from topics that start with x_ on any cluster
    Dev Team B can update consumer group offsets that start with x_ on any cluster
    ClusterManager of my-cluster Group has full access to cluster config on my-cluster
    ClusterManager of my-cluster Group has full access to consumer groups on my-cluster
    ClusterManager of my-cluster Group has full access to topics on my-cluster
    Copy to Clipboard Toggle word wrap
    开发团队 A
    Dev 团队 A realm 角色可以对任何集群上以 x_ 开头的主题进行写入。这将合并了一个名为 Topic:x_*DescribeWrite 范围以及 Dev Team A 策略的资源。Dev 团队 A 策略与具有 realm 角色 Dev Team A 的所有用户匹配。
    Dev Team B
    Dev Team B realm 角色可以从任何集群上的 x_ 开头的主题读取。这结合了 topics:x_*Group:x_* 资源、描述读取 范围以及 Dev Team B 策略。Dev 团队 B 策略与具有名为 Dev Team B 的域角色的所有用户匹配。匹配的用户和客户端能够读取主题,并为以 x_ 开始名称的主题和消费者组更新消耗的偏移量。

部署配置为连接到 Red Hat Single Sign-On 服务器的 Kafka 集群。使用示例 kafka-ephemeral-oauth-single-keycloak-authz.yaml 文件将 Kafka 集群部署为 Kafka 自定义资源。这个示例使用 keycloak 授权和 oauth 身份验证部署单节点 Kafka 集群。

先决条件

  • Red Hat Single Sign-On 授权服务器部署到 OpenShift 集群,并使用 example realm 加载。
  • Cluster Operator 已部署到 OpenShift 集群。
  • AMQ Streams example /security/keycloak-authorization/kafka-ephemeral-oauth-single-keycloak-authz.yaml 自定义资源。

流程

  1. 使用您部署的 Red Hat Single Sign-On 实例的主机名,为 Kafka 代理准备信任存储证书,以便与红帽单点登录服务器通信。

    SSO_HOST=SSO-HOSTNAME
    SSO_HOST_PORT=$SSO_HOST:443
    STOREPASS=storepass
    
    echo "Q" | openssl s_client -showcerts -connect $SSO_HOST_PORT 2>/dev/null | awk ' /BEGIN CERTIFICATE/,/END CERTIFICATE/ { print $0 } ' > /tmp/sso.crt
    Copy to Clipboard Toggle word wrap

    证书是必需的,因为 OpenShift ingress 用于进行安全(HTTPS)连接。

  2. 将证书作为机密部署到 OpenShift。

    oc create secret generic oauth-server-cert --from-file=/tmp/sso.crt -n $NS
    Copy to Clipboard Toggle word wrap
  3. 将主机名设置为环境变量

    SSO_HOST=SSO-HOSTNAME
    Copy to Clipboard Toggle word wrap
  4. 创建并部署示例 Kafka 集群。

    cat examples/security/keycloak-authorization/kafka-ephemeral-oauth-single-keycloak-authz.yaml | sed -E 's#\${SSO_HOST}'"#$SSO_HOST#" | oc create -n $NS -f -
    Copy to Clipboard Toggle word wrap

6.5.4.3. 为 CLI Kafka 客户端会话准备 TLS 连接

为交互式 CLI 会话创建一个新 pod。使用用于 TLS 连接性的红帽单点登录证书设置信任存储。truststore 连接至 Red Hat Single Sign-On 和 Kafka 代理。

先决条件

  • Red Hat Single Sign-On 授权服务器部署到 OpenShift 集群,并使用 example realm 加载。

    在 Red Hat Single Sign-On Admin Console 中,检查分配给客户端的角色在 Clients > Service Account Roles 中显示。

  • 配置为与 Red Hat Single Sign-On 连接的 Kafka 集群部署到 OpenShift 集群。

流程

  1. 使用 AMQ Streams Kafka 镜像运行一个新的交互式 pod 容器,以连接到正在运行的 Kafka 代理。

    NS=sso
    oc run -ti --restart=Never --image=registry.redhat.io/amq7/amq-streams-kafka-33-rhel8:2.3.0 kafka-cli -n $NS -- /bin/sh
    Copy to Clipboard Toggle word wrap
    注意

    如果 oc 超时等待镜像下载,后续尝试可能会导致 AlreadyExists 错误。

  2. 附加到 pod 容器。

    oc attach -ti kafka-cli -n $NS
    Copy to Clipboard Toggle word wrap
  3. 使用 Red Hat Single Sign-On 实例的主机名,使用 TLS 为客户端连接准备证书。

    SSO_HOST=SSO-HOSTNAME
    SSO_HOST_PORT=$SSO_HOST:443
    STOREPASS=storepass
    
    echo "Q" | openssl s_client -showcerts -connect $SSO_HOST_PORT 2>/dev/null | awk ' /BEGIN CERTIFICATE/,/END CERTIFICATE/ { print $0 } ' > /tmp/sso.crt
    Copy to Clipboard Toggle word wrap
  4. 为与 Kafka 代理的 TLS 连接创建信任存储。

    keytool -keystore /tmp/truststore.p12 -storetype pkcs12 -alias sso -storepass $STOREPASS -import -file /tmp/sso.crt -noprompt
    Copy to Clipboard Toggle word wrap
  5. 使用 Kafka bootstrap 地址作为 Kafka 代理的主机名,使用 tls 侦听器端口(9093)为 Kafka 代理准备证书。

    KAFKA_HOST_PORT=my-cluster-kafka-bootstrap:9093
    STOREPASS=storepass
    
    echo "Q" | openssl s_client -showcerts -connect $KAFKA_HOST_PORT 2>/dev/null | awk ' /BEGIN CERTIFICATE/,/END CERTIFICATE/ { print $0 } ' > /tmp/my-cluster-kafka.crt
    Copy to Clipboard Toggle word wrap
  6. 将 Kafka 代理的证书添加到 truststore 中。

    keytool -keystore /tmp/truststore.p12 -storetype pkcs12 -alias my-cluster-kafka -storepass $STOREPASS -import -file /tmp/my-cluster-kafka.crt -noprompt
    Copy to Clipboard Toggle word wrap

    使会话保持打开以检查授权访问权限。

通过交互式 CLI 会话检查通过 Red Hat Single Sign-On 域应用的授权规则。使用 Kafka 的示例制作者和使用者客户端应用检查,以创建具有不同访问级别的用户和服务帐户。

使用 team-a-clientteam-b-client 客户端检查授权规则。使用 alice admin 用户在 Kafka 上执行额外的管理任务。

本例中使用的 AMQ Streams Kafka 镜像包含 Kafka producer 和 consumer 二进制文件。

先决条件

设置客户端和 admin 用户配置

  1. 使用 team-a-client 客户端的身份验证属性准备 Kafka 配置文件。

    SSO_HOST=SSO-HOSTNAME
    
    cat > /tmp/team-a-client.properties << EOF
    security.protocol=SASL_SSL
    ssl.truststore.location=/tmp/truststore.p12
    ssl.truststore.password=$STOREPASS
    ssl.truststore.type=PKCS12
    sasl.mechanism=OAUTHBEARER
    sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      oauth.client.id="team-a-client" \
      oauth.client.secret="team-a-client-secret" \
      oauth.ssl.truststore.location="/tmp/truststore.p12" \
      oauth.ssl.truststore.password="$STOREPASS" \
      oauth.ssl.truststore.type="PKCS12" \
      oauth.token.endpoint.uri="https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" ;
    sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
    EOF
    Copy to Clipboard Toggle word wrap

    使用 SASL OAUTHBEARER 机制。这种机制需要客户端 ID 和客户端 secret,这意味着客户端首先连接到 Red Hat Single Sign-On 服务器来获取访问令牌。然后,客户端连接到 Kafka 代理并使用访问令牌进行身份验证。

  2. 准备 Kafka 配置文件,其中包含 team-b-client 客户端的身份验证属性。

    cat > /tmp/team-b-client.properties << EOF
    security.protocol=SASL_SSL
    ssl.truststore.location=/tmp/truststore.p12
    ssl.truststore.password=$STOREPASS
    ssl.truststore.type=PKCS12
    sasl.mechanism=OAUTHBEARER
    sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      oauth.client.id="team-b-client" \
      oauth.client.secret="team-b-client-secret" \
      oauth.ssl.truststore.location="/tmp/truststore.p12" \
      oauth.ssl.truststore.password="$STOREPASS" \
      oauth.ssl.truststore.type="PKCS12" \
      oauth.token.endpoint.uri="https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" ;
    sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
    EOF
    Copy to Clipboard Toggle word wrap
  3. 使用 curl 执行密码授权验证 admin 用户 alice,以获取刷新令牌。

    USERNAME=alice
    PASSWORD=alice-password
    
    GRANT_RESPONSE=$(curl -X POST "https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" -H 'Content-Type: application/x-www-form-urlencoded' -d "grant_type=password&username=$USERNAME&password=$PASSWORD&client_id=kafka-cli&scope=offline_access" -s -k)
    
    REFRESH_TOKEN=$(echo $GRANT_RESPONSE | awk -F "refresh_token\":\"" '{printf $2}' | awk -F "\"" '{printf $1}')
    Copy to Clipboard Toggle word wrap

    刷新令牌是一个离线令牌,它是长期的且无法过期。

  4. 使用 admin 用户 alice 的身份验证属性准备 Kafka 配置文件。

    cat > /tmp/alice.properties << EOF
    security.protocol=SASL_SSL
    ssl.truststore.location=/tmp/truststore.p12
    ssl.truststore.password=$STOREPASS
    ssl.truststore.type=PKCS12
    sasl.mechanism=OAUTHBEARER
    sasl.jaas.config=org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule required \
      oauth.refresh.token="$REFRESH_TOKEN" \
      oauth.client.id="kafka-cli" \
      oauth.ssl.truststore.location="/tmp/truststore.p12" \
      oauth.ssl.truststore.password="$STOREPASS" \
      oauth.ssl.truststore.type="PKCS12" \
      oauth.token.endpoint.uri="https://$SSO_HOST/auth/realms/kafka-authz/protocol/openid-connect/token" ;
    sasl.login.callback.handler.class=io.strimzi.kafka.oauth.client.JaasClientOauthLoginCallbackHandler
    EOF
    Copy to Clipboard Toggle word wrap

    kafka-cli 公共客户端用于 sasl.jaas.config 中的 oauth.client.id。由于这是不需要机密的公共客户端。客户端使用上一步中通过身份验证的刷新令牌进行身份验证。刷新令牌会在 scenes 后面请求访问令牌,然后将其发送到 Kafka 代理以进行身份验证。

生成具有授权访问权限的消息

使用 team-a-client 配置检查您可以生成消息到以 a_x_ 开头的主题。

  1. 将 写入到主题 my-topic

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic my-topic \
      --producer.config=/tmp/team-a-client.properties
    First message
    Copy to Clipboard Toggle word wrap

    此请求返回 Not authorized 以访问主题:[my-topic] 错误。

    team-a-client 具有 Dev Team A 角色,它有权对以 a_ 开头的主题执行任何受支持操作,但只能写入以 x_ 开头的主题。名为 my-topic 的主题都匹配这些规则。

  2. 将 写入到主题 a_messages

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \
      --producer.config /tmp/team-a-client.properties
    First message
    Second message
    Copy to Clipboard Toggle word wrap

    在 Kafka 中成功生成信息。

  3. 按 CTRL+C 退出 CLI 应用程序。
  4. 检查 Kafka 容器日志,获取请求的 Authorization GRANTED 的 debug 日志。

    oc logs my-cluster-kafka-0 -f -n $NS
    Copy to Clipboard Toggle word wrap

使用具有授权访问权限的消息

使用 team-a-client 配置来消耗主题 a_messages 中的消息。

  1. 从主题 a_messages 获取消息。

    bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \
      --from-beginning --consumer.config /tmp/team-a-client.properties
    Copy to Clipboard Toggle word wrap

    该请求会返回一个错误,因为 team-a-clientDev Team A 角色只能访问具有以 _ 开始名称的消费者组。

  2. 更新 team-a-client 属性,以指定允许使用的自定义使用者组。

    bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \
      --from-beginning --consumer.config /tmp/team-a-client.properties --group a_consumer_group_1
    Copy to Clipboard Toggle word wrap

    使用者接收来自 a_messages 主题的所有消息。

使用授权访问权限管理 Kafka

team-a-client 是一个没有集群级别访问权限的帐户,但它可用于一些管理操作。

  1. 列出主题。

    bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties --list
    Copy to Clipboard Toggle word wrap

    返回 a_messages 主题。

  2. 列出使用者组。

    bin/kafka-consumer-groups.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties --list
    Copy to Clipboard Toggle word wrap

    a_consumer_group_1 consumer 组返回。

    获取集群配置的详情。

    bin/kafka-configs.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties \
      --entity-type brokers --describe --entity-default
    Copy to Clipboard Toggle word wrap

    请求返回一个错误,因为操作需要 team-a-client 没有集群级别权限。

使用具有不同权限的客户端

使用 team-b-client 配置为以 b_ 开头的主题生成消息。

  1. 将 写入到主题 a_messages

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic a_messages \
      --producer.config /tmp/team-b-client.properties
    Message 1
    Copy to Clipboard Toggle word wrap

    此请求返回 Not authorized 以访问主题:[a_messages] 错误。

  2. 将主题 b_messages 写入主题。

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic b_messages \
      --producer.config /tmp/team-b-client.properties
    Message 1
    Message 2
    Message 3
    Copy to Clipboard Toggle word wrap

    在 Kafka 中成功生成信息。

  3. 将 写入到主题 x_messages

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --producer.config /tmp/team-b-client.properties
    Message 1
    Copy to Clipboard Toggle word wrap

    不授权访问主题:[x_messages] 错误将返回,team-b-client 只能从主题 x_messages 中读取。

  4. 使用 team-a-client 写入主题 x_messages

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --producer.config /tmp/team-a-client.properties
    Message 1
    Copy to Clipboard Toggle word wrap

    此请求返回 Not authorized 以访问主题:[x_messages] 错误。team-a-client 可以写入 x_messages 主题,但如果不存在,则没有创建主题的权限。在 team-a-client 可以写入 x_messages 主题之前,管理员 高级用户 必须通过正确的配置创建它,如分区和副本的数量。

使用授权 admin 用户管理 Kafka

使用 admin 用户 alice 管理 Kafka。alice 具有管理任何 Kafka 集群上的所有内容的完整访问权限。

  1. alice 身份创建 x_messages 主题。

    bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/alice.properties \
      --topic x_messages --create --replication-factor 1 --partitions 1
    Copy to Clipboard Toggle word wrap

    主题创建成功。

  2. 列出所有主题为 alice

    bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/alice.properties --list
    bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-a-client.properties --list
    bin/kafka-topics.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/team-b-client.properties --list
    Copy to Clipboard Toggle word wrap

    admin 用户 alice 可以列出所有主题,而 team-a-clientteam-b-client 只能列出它们可访问的主题。

    Dev 团队 ADev Team B 角色都 描述x_ 开头的主题,但它们无法看到其他组的主题,因为它们没有 描述 权限。

  3. 使用 team-a-clientx_messages 主题生成信息:

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --producer.config /tmp/team-a-client.properties
    Message 1
    Message 2
    Message 3
    Copy to Clipboard Toggle word wrap

    因为 alice 创建 x_messages 主题,因此成功生成给 Kafka 的信息。

  4. 使用 team-b-clientx_messages 主题生成消息。

    bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --producer.config /tmp/team-b-client.properties
    Message 4
    Message 5
    Copy to Clipboard Toggle word wrap

    此请求返回 Not authorized 以访问主题:[x_messages] 错误。

  5. 使用 team-b-client 使用 x_messages 主题的消息:

    bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --from-beginning --consumer.config /tmp/team-b-client.properties --group x_consumer_group_b
    Copy to Clipboard Toggle word wrap

    使用者接收来自 x_messages 主题的所有消息。

  6. 使用 team-a-client 使用 x_messages 主题的消息。

    bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --from-beginning --consumer.config /tmp/team-a-client.properties --group x_consumer_group_a
    Copy to Clipboard Toggle word wrap

    此请求返回 Not authorized 以访问主题:[x_messages] 错误。

  7. 使用 team-a-client 使用以 _ 开头的消费者组的消息。

    bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --from-beginning --consumer.config /tmp/team-a-client.properties --group a_consumer_group_a
    Copy to Clipboard Toggle word wrap

    此请求返回 Not authorized 以访问主题:[x_messages] 错误。

    Dev Team A 没有以 x_ 开始的主题的 Read 访问权限。

  8. 使用 alicex_messages 主题生成消息。

    bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --topic x_messages \
      --from-beginning --consumer.config /tmp/alice.properties
    Copy to Clipboard Toggle word wrap

    在 Kafka 中成功生成信息。

    alice 可以从任何主题读取或写入。

  9. 使用 alice 读取集群配置。

    bin/kafka-configs.sh --bootstrap-server my-cluster-kafka-bootstrap:9093 --command-config /tmp/alice.properties \
      --entity-type brokers --describe --entity-default
    Copy to Clipboard Toggle word wrap

    本例中的集群配置为空。

返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat