serviceName在kafka的jaas.conf配置中的含义

本文使用的是HDP-2.6.0.3版本,在kafka_jaas.conf配置文件中有个配置项叫做serviceName,在使用storm 访问 kerberos kafka中的方法进行测试的时候发现,如果没有配置serviceName会报错No serviceName defined in either JAAS or Kafka config的错误,本文将会分析serviceName究竟是什么。

Kaffka 0.10.0源码分析

通过上面的报错可以定位到是org.apache.kafka.common.security.kerberos.KerberosLogin中到getServiceName方法返回到错误信息

private String getServiceName(Map<String, ?> configs, String loginContext) {
    String jaasServiceName;
    try {
        jaasServiceName = JaasUtils.jaasConfig(loginContext, JaasUtils.SERVICE_NAME);
    } catch (IOException e) {
        throw new KafkaException("Jaas configuration not found", e);
    }
    String configServiceName = (String) configs.get(SaslConfigs.SASL_KERBEROS_SERVICE_NAME);
    if (jaasServiceName != null && configServiceName != null && !jaasServiceName.equals(configServiceName)) {
        String message = "Conflicting serviceName values found in JAAS and Kafka configs " +
            "value in JAAS file " + jaasServiceName + ", value in Kafka config " + configServiceName;
        throw new IllegalArgumentException(message);
    }

    if (jaasServiceName != null)
        return jaasServiceName;
    if (configServiceName != null)
        return configServiceName;

    throw new IllegalArgumentException("No serviceName defined in either JAAS or Kafka config");
}

这段代码中,如果jaas文件中没有配置serviceName就会返回sasl.kerberos.service.name的参数值,而这个参数的含义

The Kerberos principal name that Kafka runs as. This can be defined either in Kafka's JAAS config or in Kafka's config.

下面是关于Kerberos principal的定义

A Kerberos principal is a unique identity to which Kerberos can assign tickets. Principals can have an arbitrary number of components. Each component is separated by a component separator, generally '/'. The last component is the realm, separated from the rest of the principal by the realm separator, generally '@'. If there is no realm component in the principal, then it will be assumed that the principal is in the default realm for the context in which it is being used.
Traditionally, a principal is divided into three parts: the primary, the instance, and the realm. The format of a typical Kerberos V5 principal is primary/instance@REALM.
The primary is the first part of the principal. In the case of a user, it's the same as your username. For a host, the primary is the word host.
The instance is an optional string that qualifies the primary. The instance is separated from the primary by a slash (/). In the case of a user, the instance is usually null, but a user might also have an additional principal, with an instance called admin, which he/she uses to administrate a database. The principal jennifer@ATHENA.MIT.EDU is completely separate from the principal jennifer/admin@ATHENA.MIT.EDU, with a separate password, and separate permissions. In the case of a host, the instance is the fully qualified hostname, e.g., daffodil.mit.edu.
The realm is your Kerberos realm. In most cases, your Kerberos realm is your domain name, in upper-case letters. For example, the machine daffodil.example.com would be in the realm EXAMPLE.COM.

所以结合上面的描述,准确的对serviceName的定义应该是kafka principal的primary的值。

在代码中serviceName是在org.apache.kafka.common.network.SaslChannelBuilderbuildChannel中使用的

authenticator = new SaslClientAuthenticator(id, loginManager.subject(), loginManager.serviceName(),
                        socketChannel.socket().getInetAddress().getHostName(), clientSaslMechanism, handshakeRequestEnable);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容