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 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 [email protected] is completely separate from the principal jennifer/[email protected], 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);

你可能感兴趣的:(serviceName在kafka的jaas.conf配置中的含义)