Client authentication using tokens based on JSON Web Tokens

Token 认证概述

Pulsar 支持通过加密 Token 的方式认证客户端,它是基于JSON Web TokensRFC-7519)来实现的。

你可以根据 Token 来识别 Pulsar 客户端。通过给 Token 关联一些 “principal” 或 “role”,可以用来授权客户端允许执行某些操作 (例如:发布消息主题或从主题消费消息) 。

用户通常需要从管理员(或某些自动化服务)获得 Token 字符串。

如下是一个简短的 JWT 签名字符串:

  1. eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY

应用程序需要在创建客户端实例时,指定所使用的 Token。 一个替代方法是通过“令牌供应商”(即通过一个函数返回所需要的Token)。

始终使用 TLS 传输加密

发送 Token 等同于在网络上发送密码。 在连接 Pulsar 服务的整个过程中,最好始终使用 TLS 加密。 有关详细信息,请参阅 使用 TLS 传输加密

命令行工具

命令行工具 pulsar-admin, pulsar-perf pulsar-client 使用 conf/client. onf 配置文件在 Pulsar 安装中。

你需要添加以下参数到该文件以使用 Pulsar 的 CLI 工具使用 Token 身份验证:

  1. webServiceUrl=http://broker.example.com:8080/
  2. brokerServiceUrl=pulsar://broker.example.com:6650/
  3. authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationToken
  4. authParams=token:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY

Token 字符串也可以从文件中读取,例如:

  1. authParams=file:///path/to/token/file

Pulsar 客户端

你可以使用 Token 对如下 Pulsar 客户端进行身份认证。

Java

Python

Go

C++

C#

  1. PulsarClient client = PulsarClient.builder() .serviceUrl("pulsar://broker.example.com:6650/") .authentication( AuthenticationFactory.token("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY")) .build();

同样,你也可以传入一个 Supplier

  1. PulsarClient client = PulsarClient.builder() .serviceUrl("pulsar://broker.example.com:6650/") .authentication( AuthenticationFactory.token(() -> { // 从通用的数据源读取 Token return readToken(); })) .build();
  1. from pulsar import Client, AuthenticationTokenclient = Client('pulsar://broker.example.com:6650/' authentication=AuthenticationToken('eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY'))

或者,您也可以通过 Supplier

  1. def read_token(): with open('/path/to/token.txt') as tf: return tf.read().strip()client = Client('pulsar://broker.example.com:6650/' authentication=AuthenticationToken(read_token))
  1. client, err := NewClient(ClientOptions{ URL: "pulsar://localhost:6650", Authentication: NewAuthenticationToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY"),})

同样,你也可以传入一个 Supplier

  1. client, err := NewClient(ClientOptions{ URL: "pulsar://localhost:6650", Authentication: NewAuthenticationTokenSupplier(func () string { // Read token from custom source return readToken() }),})
  1. #include <pulsar/Client.h>pulsar::ClientConfiguration config;config.setAuth(pulsar::AuthToken::createWithToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY"));pulsar::Client client("pulsar://broker.example.com:6650/", config);
  1. var client = PulsarClient.Builder() .AuthenticateUsingToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKb2UifQ.ipevRNuRP6HflG8cFKnmUPtypruRC4fb1DWtoLL62SY") .Build();

启用 Token 认证

根据如下指南,可以在 Pulsar 集群中启用 Token 认证。

JWT 支持通过两种不同的秘钥,来生成和验证 Token:

  • 对称秘钥:
    • 使用单个 Secret key 来生成和验证 tokens。
  • 非对称秘钥:包含由私钥和公钥组成的一对密钥。
    • 使用 Private key 生成 Token。
    • 使用 Public key 验证 Token。

创建 Secret key

使用 Secret key 时,由管理员创建这个 Secret key, 并使用该密钥生成客户端 Token。 为了能够验证客户端,还需要在 Broker 上配置这个 Key。

默认在 Pulsar 安装目录的根目录生成输出文件。 您也可以使用下面的命令为输出文件指定绝对路径。

  1. $ bin/pulsar tokens create-secret-key --output my-secret.key

输入下面的命令可以生成 base64 编码的密钥。

  1. $ bin/pulsar tokens create-secret-key --output /opt/my-secret.key --base64

创建秘钥对

若需要使用公钥和私钥方式,需要先创建一对秘钥。 Pulsar 支持 Java JWT 库( 这里)支持的所有算法。

默认在 Pulsar 安装目录的根目录生成输出文件。 您也可以使用下面的命令为输出文件指定绝对路径。

  1. $ bin/pulsar tokens create-key-pair --output-private-key my-private.key --output-public-key my-public.key
  • 保存 my-private.key 到一个安全的位置,只有管理员能使用 my-private.key 来生成新的 tokens。
  • my-public.key 需要分发给所有 Pulsar brokers。 您可以公开共享此文件,不用担心安全问题。

生成 Token

A token is the credential associated with a user. 连接是通过 “principal” 或 “role” 完成的。 对于 JWT tokens,这个字段通常被称为 subject,尽管它们是完全相同的概念。

接下来,您需要使用这个命令来要求生成的具有一个 subject 字段的 token。

  1. $ bin/pulsar tokens create --secret-key file:///path/to/my-secret.key \
  2. --subject test-user

命令将在 stdout 上打印出 token 字符串。

类似地,您可以通过下面的命令使用 “private” key 来创建一个 token。

  1. $ bin/pulsar tokens create --private-key file:///path/to/my-private.key \
  2. --subject test-user

最后,你可以通过以下命令来创建一个带有过期时间的 Token。 Token 到期后会自动失效。

  1. $ bin/pulsar tokens create --secret-key file:///path/to/my-secret.key \
  2. --subject test-user \
  3. --expiry-time 1y

授权

Token 本身没有关联任何权限。 授权引擎确定 token 是否有权限。 一旦创建 token,就可以授予该 Token 执行某些操作的权限。 The following is an example.

  1. $ bin/pulsar-admin namespaces grant-permission my-tenant/my-namespace \
  2. --role test-user \
  3. --actions produce,consume

在 Brokers 上启用 token 认证

要让 brokers 能对客户端进行身份认证,请在 broker.conf 中添加以下参数:

  1. # 启用认证和鉴权
  2. authenticationEnabled=true
  3. authorizationEnabled=true
  4. authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderToken
  5. # 设置Broker 自身的认证。 Used when the broker connects to other brokers, either in same or other clusters
  6. brokerClientTlsEnabled=true
  7. brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationToken
  8. brokerClientAuthenticationParameters={"token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.9OHgE9ZUDeBTZs7nSMEFIuGNEX18FLR3qvy8mqxSxXw"}
  9. # Or, alternatively, read token from file
  10. # brokerClientAuthenticationParameters={"file":"///path/to/proxy-token.txt"}
  11. brokerClientTrustCertsFilePath=/path/my-ca/certs/ca.cert.pem
  12. # If this flag is set then the broker authenticates the original Auth data
  13. # else it just accepts the originalPrincipal and authorizes it (if required).
  14. authenticateOriginalAuthData=true
  15. # If using secret key (Note: key files must be DER-encoded)
  16. tokenSecretKey=file:///path/to/secret.key
  17. # The key can also be passed inline:
  18. # tokenSecretKey=data:;base64,FLFyW0oLJ2Fi22KKCm21J18mbAdztfSHN/lAT5ucEKU=
  19. # If using public/private (Note: key files must be DER-encoded)
  20. # tokenPublicKey=file:///path/to/public.key

Proxy 启用 Token 认证

要让 Proxy 能对客户端进行身份认证,请在 proxy.conf 中添加以下参数:

Proxy 连接 brokers 使用的是自己的 token。 你需要在 broker 的 代理角色 中配置此密钥对的角色标记。 有关详细信息,请参阅 授权指南

  1. # For clients connecting to the proxy
  2. authenticationEnabled=true
  3. authorizationEnabled=true
  4. authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderToken
  5. tokenSecretKey=file:///path/to/secret.key
  6. # For the proxy to connect to brokers
  7. brokerClientAuthenticationPlugin=org.apache.pulsar.client.impl.auth.AuthenticationToken
  8. brokerClientAuthenticationParameters={"token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0LXVzZXIifQ.9OHgE9ZUDeBTZs7nSMEFIuGNEX18FLR3qvy8mqxSxXw"}
  9. # Or, alternatively, read token from file
  10. # brokerClientAuthenticationParameters={"file":"///path/to/proxy-token.txt"}
  11. # Whether client authorization credentials are forwared to the broker for re-authorization.
  12. # Authentication must be enabled via authenticationEnabled=true for this to take effect.
  13. forwardAuthorizationCredentials=true