5.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 插件来根据访问控制列表(ACL)配置授权。

zookeeper 存储了基于 用户名 授予或拒绝对资源的访问的 ACL 规则。但是,带有 Red Hat Single Sign-On 的 OAuth 2.0 令牌的授权提供了更大的灵活性,有关如何实现对 Kafka 代理的访问控制。另外,您可以将 Kafka 代理配置为使用 OAuth 2.0 授权和 ACL。

5.5.1. OAuth 2.0 授权机制

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

5.5.1.1. Kafka 代理自定义授权器

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

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

5.5.2. 配置 OAuth 2.0 授权支持

此流程描述了如何使用 Red Hat Single Sign-On Authorization 服务将 Kafka 代理配置为使用 OAuth 2.0 授权。

开始前

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

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

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

注意

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

先决条件

  • AMQ Streams 必须将 OAuth 2.0 与 Red Hat Single Sign-On 用于 基于令牌的身份验证。设置授权时,您使用相同的红帽单点登录服务器端点。
  • 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 开始的主题读取

5.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

使用来自主题的消息

为了使用主题中的消息 需要描述和 Read 权限。在主题中使用通常依赖于将消费者偏移存储在消费者组中,这需要对消费者组需要额外的 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

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

除了生成主题的权限外,集群资源还需要额外的 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 权限。另外,有关涉及的主题还需要 描述 权限。

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

5.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 代理进行身份验证前,需要用户登录才需要用户登录。在这种情况下,访问令牌代表特定用户,而不是客户端应用程序。

5.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 身份提供程序中。
    角色
    角色 将用户或客户端标记为具有特定权限。角色是与组类似的概念。它们通常用于 为用户授予 组织角色的用户,并具有必要权限。角色不能存储在 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

5.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-32-rhel8:2.2.2 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